From 44d90c4dbf582b9ff48c1442b9e89a8ad01856bf Mon Sep 17 00:00:00 2001 From: Dan Kortschak Date: Wed, 15 Nov 2023 16:01:11 +1030 Subject: [PATCH] x-pack/auditbeat/module/socket/guess: fix creds trigger for newer kernels In kernel commit 981ee95c (into v6.3) calls to access_override_creds were gated behind a test for the requirement for the call. This change results in non-execution of prepare_creds and so failure of the guess. An alternative has been identified that does not exhibit this behaviour, mq_open. So replace the sys_access trigger with sys_mq_open. --- CHANGELOG.next.asciidoc | 1 + .../module/system/socket/guess/creds.go | 38 +++++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index cccaace964a9..0cbabf853982 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -65,6 +65,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff] *Auditbeat* +- Fix guess trigger for system/socket creds on newer kernels. {issue}36905[36905] {pull}37136[37136] *Filebeat* diff --git a/x-pack/auditbeat/module/system/socket/guess/creds.go b/x-pack/auditbeat/module/system/socket/guess/creds.go index 4180725addfb..189f6b10e5bc 100644 --- a/x-pack/auditbeat/module/system/socket/guess/creds.go +++ b/x-pack/auditbeat/module/system/socket/guess/creds.go @@ -19,6 +19,17 @@ import ( "github.com/elastic/elastic-agent-libs/mapstr" ) +/* +struct mq_attr { + long mq_flags; + long mq_maxmsg; + long mq_msgsize; + long mq_curmsgs; + long __reserved[4]; +}; +*/ +import "C" + /* creds guess discovers the offsets of (E)UID/(E)GID fields within a struct cred (defined in {linux}/include/linux.cred.h): @@ -138,13 +149,26 @@ func (g *guessStructCreds) Extract(ev interface{}) (mapstr.M, bool) { }, true } -// Trigger invokes the SYS_ACCESS syscall: -// -// int access(const char *pathname, int mode); +// Trigger invokes the SYS_MQ_OPEN syscall: // -// The function call will return an error due to path being NULL, but it will -// have invoked prepare_creds before argument validation. +// int mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr); func (g *guessStructCreds) Trigger() error { - syscall.Syscall(unix.SYS_ACCESS, 0, 0, 0) - return nil + name, err := unix.BytePtrFromString("/omg") + if err != nil { + return err + } + attr := C.struct_mq_attr{ + mq_maxmsg: 1, + mq_msgsize: 8, + } + mqd, _, err := syscall.Syscall6(unix.SYS_MQ_OPEN, + uintptr(unsafe.Pointer(name)), + uintptr(os.O_CREATE|os.O_RDWR), + 0o644, + uintptr(unsafe.Pointer(&attr)), + 0, 0) + if err != syscall.Errno(0) { + return err + } + return unix.Close(int(mqd)) }