From 98b799cb74f2e95be94c27a0627643f0ab259a2c Mon Sep 17 00:00:00 2001 From: Paul Cacheux Date: Fri, 29 Nov 2024 19:05:16 +0100 Subject: [PATCH] [CWS] switch auid hooks to fentry (#28769) --- pkg/security/ebpf/c/include/hooks/login_uid.h | 12 ++++++------ pkg/security/ebpf/kernel/kernel.go | 15 ++++++++++++--- pkg/security/probe/probe_ebpf.go | 14 +++++++++++--- pkg/security/tests/login_uid_test.go | 2 -- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/pkg/security/ebpf/c/include/hooks/login_uid.h b/pkg/security/ebpf/c/include/hooks/login_uid.h index 86d25f0e948164..d96148bdfa84f1 100644 --- a/pkg/security/ebpf/c/include/hooks/login_uid.h +++ b/pkg/security/ebpf/c/include/hooks/login_uid.h @@ -3,12 +3,12 @@ #include "helpers/syscalls.h" -SEC("kprobe/audit_set_loginuid") -int hook_audit_set_loginuid(struct pt_regs *ctx) { +HOOK_ENTRY("audit_set_loginuid") +int hook_audit_set_loginuid(ctx_t *ctx) { struct syscall_cache_t syscall = { .type = EVENT_LOGIN_UID_WRITE, .login_uid = { - .auid = (u32)PT_REGS_PARM1(ctx), + .auid = (u32)CTX_PARM1(ctx), }, }; @@ -16,9 +16,9 @@ int hook_audit_set_loginuid(struct pt_regs *ctx) { return 0; } -SEC("kretprobe/audit_set_loginuid") -int rethook_audit_set_loginuid(struct pt_regs *ctx) { - int retval = PT_REGS_RC(ctx); +HOOK_EXIT("audit_set_loginuid") +int rethook_audit_set_loginuid(ctx_t *ctx) { + int retval = CTX_PARMRET(ctx, 1); if (retval < 0) { return 0; } diff --git a/pkg/security/ebpf/kernel/kernel.go b/pkg/security/ebpf/kernel/kernel.go index e710b4a29eb9be..011273ef795895 100644 --- a/pkg/security/ebpf/kernel/kernel.go +++ b/pkg/security/ebpf/kernel/kernel.go @@ -332,8 +332,7 @@ func (k *Version) HaveLegacyPipeInodeInfoStruct() bool { return k.Code != 0 && k.Code < Kernel5_5 } -// HaveFentrySupport returns whether the kernel supports fentry probes -func (k *Version) HaveFentrySupport() bool { +func (k *Version) commonFentryCheck(funcName string) bool { if features.HaveProgramType(ebpf.Tracing) != nil { return false } @@ -341,7 +340,7 @@ func (k *Version) HaveFentrySupport() bool { spec := &ebpf.ProgramSpec{ Type: ebpf.Tracing, AttachType: ebpf.AttachTraceFEntry, - AttachTo: "vfs_open", + AttachTo: funcName, Instructions: asm.Instructions{ asm.LoadImm(asm.R0, 0, asm.DWord), asm.Return(), @@ -366,6 +365,16 @@ func (k *Version) HaveFentrySupport() bool { return true } +// HaveFentrySupport returns whether the kernel supports fentry probes +func (k *Version) HaveFentrySupport() bool { + return k.commonFentryCheck("vfs_open") +} + +// HaveFentrySupportWithStructArgs returns whether the kernel supports fentry probes with struct arguments +func (k *Version) HaveFentrySupportWithStructArgs() bool { + return k.commonFentryCheck("audit_set_loginuid") +} + // SupportBPFSendSignal returns true if the eBPF function bpf_send_signal is available func (k *Version) SupportBPFSendSignal() bool { return k.Code != 0 && k.Code >= Kernel5_3 diff --git a/pkg/security/probe/probe_ebpf.go b/pkg/security/probe/probe_ebpf.go index 6f1090b63a72c7..1c1e8fa37bc82d 100644 --- a/pkg/security/probe/probe_ebpf.go +++ b/pkg/security/probe/probe_ebpf.go @@ -194,11 +194,19 @@ func (p *EBPFProbe) selectFentryMode() { return } - supported := p.kernelVersion.HaveFentrySupport() - if !supported { + if !p.kernelVersion.HaveFentrySupport() { + p.useFentry = false seclog.Errorf("fentry enabled but not supported, falling back to kprobe mode") + return } - p.useFentry = supported + + if !p.kernelVersion.HaveFentrySupportWithStructArgs() { + p.useFentry = false + seclog.Warnf("fentry enabled but not supported with struct args, falling back to kprobe mode") + return + } + + p.useFentry = true } func (p *EBPFProbe) isNetworkNotSupported() bool { diff --git a/pkg/security/tests/login_uid_test.go b/pkg/security/tests/login_uid_test.go index 31d548788e349c..82743dcabeee70 100644 --- a/pkg/security/tests/login_uid_test.go +++ b/pkg/security/tests/login_uid_test.go @@ -89,8 +89,6 @@ func TestLoginUID(t *testing.T) { return err } - t.Logf("test out: %s\n", string(out)) - return nil }, func(event *model.Event, rule *rules.Rule) { assert.Equal(t, "exec", event.GetType(), "wrong event type")