Skip to content

Commit 37d07d1

Browse files
authored
x-pack/auditbeat/module/system/socket: defend against exec with zero arguments (#30586)
execve can have a zero-length argv so fall back to using /proc/comm, or path base.
1 parent a84f4d5 commit 37d07d1

2 files changed

Lines changed: 25 additions & 2 deletions

File tree

CHANGELOG.next.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...main[Check the HEAD dif
4747
*Auditbeat*
4848

4949
- auditd: Add error.message to events when processing fails. {pull}30009[30009]
50+
- Fix handling of execve call events which have no argument. {issue}30585[30585] {pull}30586[30586]
5051

5152
*Filebeat*
5253

x-pack/auditbeat/module/system/socket/events.go

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,8 @@ func (e *execveCall) getProcess() *process {
888888
if idx := bytes.IndexByte(e.Path[:], 0); idx >= 0 {
889889
// Fast path if we already have the path.
890890
p.path = string(e.Path[:idx])
891+
// Keep the basename in case we can't get the process name.
892+
p.name = filepath.Base(p.path)
891893
} else {
892894
// Attempt to get the path from the /prox/<pid>/exe symlink.
893895
var err error
@@ -896,9 +898,13 @@ func (e *execveCall) getProcess() *process {
896898
if pe, ok := err.(*os.PathError); ok && strings.Contains(pe.Path, "(deleted)") {
897899
// Keep the deleted path from the PathError.
898900
p.path = pe.Path
901+
// Keep the basename in case we can't get the process name.
902+
p.name = filepath.Base(strings.TrimSuffix(p.path, " (deleted)"))
899903
} else {
900904
// Fallback to the truncated path.
901905
p.path = string(e.Path[:]) + " ..."
906+
// Don't trim the ellipsis to indicate this may be incorrect.
907+
p.name = filepath.Base(p.path)
902908
}
903909
}
904910
}
@@ -943,8 +949,24 @@ func (e *execveCall) getProcess() *process {
943949
}
944950
}
945951

946-
// Get name from first argument.
947-
p.name = filepath.Base(p.args[0])
952+
// Carefully get the process name; we may have zero arguments.
953+
if len(p.args) != 0 {
954+
// Get name from first argument.
955+
p.name = filepath.Base(p.args[0])
956+
} else {
957+
// Attempt to get name from /proc/<pid>/comm — only available since 2.6.33.
958+
comm, err := os.ReadFile(fmt.Sprintf("/proc/%d/comm", e.Meta.PID))
959+
if err == nil {
960+
p.name = strings.TrimRight(string(comm), "\x00")
961+
if len(p.name) == 16 {
962+
// The name may have been truncated if it is TASK_COMM_LEN long.
963+
p.name += "..."
964+
}
965+
} else if p.name == "" {
966+
// This should never happen.
967+
p.name = "(unknown)"
968+
}
969+
}
948970

949971
if e.creds != nil {
950972
p.hasCreds = true

0 commit comments

Comments
 (0)