diff --git a/docs/docs/events/builtin/extra/chmod_common.md b/docs/docs/events/builtin/extra/chmod_common.md new file mode 100644 index 000000000000..324320987f42 --- /dev/null +++ b/docs/docs/events/builtin/extra/chmod_common.md @@ -0,0 +1,34 @@ +# chmod_common + +## Intro + +chmod_common - An event capturing changes to access permissions of files and directories. + +## Description + +This event captures any changes to the current working directory (typically by using the `chmod` and similar syscalls). + +## Arguments + +* `pathname`:`const char*`[K] - path of the file or directory +* `mode`:`mode_t`[K] - the mode to apply to the file or directory + +## Hooks + +### chmod_common + +#### Type + +kprobe + +#### Purpose + +Catch access permissions changes of files and directories. + +## Example Use Case + +## Issues + +## Related Events + +`chmod`, `fchmod`, `fchmodat` diff --git a/mkdocs.yml b/mkdocs.yml index b041d8d334e1..d3d2e1692123 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -110,6 +110,7 @@ nav: - security_path_notify: docs/events/builtin/extra/security_path_notify.md - set_fs_pwd: docs/events/builtin/extra/set_fs_pwd.md - tracee_info: docs/events/builtin/extra/tracee_info.md + - chmod_common: docs/events/builtin/extra/chmod_common.md - Syscalls: - Overview: docs/events/builtin/syscalls/index.md - syscalls: diff --git a/pkg/ebpf/c/tracee.bpf.c b/pkg/ebpf/c/tracee.bpf.c index 112b44d9bb10..36c88fad8021 100644 --- a/pkg/ebpf/c/tracee.bpf.c +++ b/pkg/ebpf/c/tracee.bpf.c @@ -2500,14 +2500,14 @@ int BPF_KPROBE(trace_debugfs_create_file) return 0; char *name = (char *) PT_REGS_PARM1(ctx); - mode_t mode = (unsigned short) PT_REGS_PARM2(ctx); + umode_t mode = (unsigned short) PT_REGS_PARM2(ctx); struct dentry *dentry = (struct dentry *) PT_REGS_PARM3(ctx); void *dentry_path = get_dentry_path_str(dentry); unsigned long proc_ops_addr = (unsigned long) PT_REGS_PARM5(ctx); save_str_to_buf(&p.event->args_buf, name, 0); save_str_to_buf(&p.event->args_buf, dentry_path, 1); - save_to_submit_buf(&p.event->args_buf, &mode, sizeof(mode_t), 2); + save_to_submit_buf(&p.event->args_buf, &mode, sizeof(umode_t), 2); save_to_submit_buf(&p.event->args_buf, (void *) &proc_ops_addr, sizeof(u64), 3); return events_perf_submit(&p, 0); @@ -5161,6 +5161,26 @@ int BPF_KPROBE(trace_security_settime64) return events_perf_submit(&p, 0); } +SEC("kprobe/chmod_common") +int BPF_KPROBE(trace_chmod_common) +{ + program_data_t p = {}; + if (!init_program_data(&p, ctx, CHMOD_COMMON)) + return 0; + + if (!evaluate_scope_filters(&p)) + return 0; + + struct path *path = (struct path *) PT_REGS_PARM1(ctx); + umode_t mode = PT_REGS_PARM2(ctx); + void *file_path = get_path_str(path); + + save_str_to_buf(&p.event->args_buf, file_path, 0); + save_to_submit_buf(&p.event->args_buf, &mode, sizeof(umode_t), 1); + + return events_perf_submit(&p, 0); +} + // clang-format off // Network Packets (works from ~5.2 and beyond) diff --git a/pkg/ebpf/c/types.h b/pkg/ebpf/c/types.h index b6ee3df138f4..b6822b92add6 100644 --- a/pkg/ebpf/c/types.h +++ b/pkg/ebpf/c/types.h @@ -131,6 +131,7 @@ enum event_id_e PROCESS_EXECUTE_FAILED_INTERNAL, SECURITY_TASK_SETRLIMIT, SECURITY_SETTIME64, + CHMOD_COMMON, MAX_EVENT_ID, NO_EVENT_SUBMIT, diff --git a/pkg/ebpf/probes/probe_group.go b/pkg/ebpf/probes/probe_group.go index 7e3e57329d3b..4578f319571c 100644 --- a/pkg/ebpf/probes/probe_group.go +++ b/pkg/ebpf/probes/probe_group.go @@ -235,6 +235,7 @@ func NewDefaultProbeGroup(module *bpf.Module, netEnabled bool) (*ProbeGroup, err Dup2Ret: NewTraceProbe(SyscallExit, "dup2", "trace_ret_dup2"), Dup3: NewTraceProbe(SyscallEnter, "dup3", "trace_dup3"), Dup3Ret: NewTraceProbe(SyscallExit, "dup3", "trace_ret_dup3"), + ChmodCommon: NewTraceProbe(KProbe, "chmod_common", "trace_chmod_common"), TestUnavailableHook: NewTraceProbe(KProbe, "non_existing_func", "empty_kprobe"), ExecTest: NewTraceProbe(RawTracepoint, "raw_syscalls:sched_process_exec", "tracepoint__exec_test"), diff --git a/pkg/ebpf/probes/probes.go b/pkg/ebpf/probes/probes.go index bdf5ae6525b8..85ed9376b6d7 100644 --- a/pkg/ebpf/probes/probes.go +++ b/pkg/ebpf/probes/probes.go @@ -161,6 +161,7 @@ const ( Dup2Ret Dup3 Dup3Ret + ChmodCommon ) // Test probe handles diff --git a/pkg/events/core.go b/pkg/events/core.go index e7b2e60cfe4c..8e8c59ad8509 100644 --- a/pkg/events/core.go +++ b/pkg/events/core.go @@ -113,6 +113,7 @@ const ( ProcessExecuteFailedInternal SecurityTaskSetrlimit SecuritySettime64 + ChmodCommon MaxCommonID ) @@ -262,7 +263,7 @@ var CoreEvents = map[ID]Definition{ params: []trace.ArgMeta{ {Type: "const char*", Name: "pathname"}, {Type: "int", Name: "flags"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, }, dependencies: Dependencies{ probes: []Probe{ @@ -2241,7 +2242,7 @@ var CoreEvents = map[ID]Definition{ sets: []string{"syscalls", "fs", "fs_dir_ops"}, params: []trace.ArgMeta{ {Type: "const char*", Name: "pathname"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, }, dependencies: Dependencies{ probes: []Probe{ @@ -2288,7 +2289,7 @@ var CoreEvents = map[ID]Definition{ sets: []string{"default", "syscalls", "fs", "fs_file_ops"}, params: []trace.ArgMeta{ {Type: "const char*", Name: "pathname"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, }, dependencies: Dependencies{ probes: []Probe{ @@ -2408,7 +2409,7 @@ var CoreEvents = map[ID]Definition{ sets: []string{"default", "syscalls", "fs", "fs_file_attr"}, params: []trace.ArgMeta{ {Type: "const char*", Name: "pathname"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, }, dependencies: Dependencies{ probes: []Probe{ @@ -2432,7 +2433,7 @@ var CoreEvents = map[ID]Definition{ sets: []string{"default", "syscalls", "fs", "fs_file_attr"}, params: []trace.ArgMeta{ {Type: "int", Name: "fd"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, }, dependencies: Dependencies{ probes: []Probe{ @@ -3417,7 +3418,7 @@ var CoreEvents = map[ID]Definition{ sets: []string{"syscalls", "fs", "fs_file_ops"}, params: []trace.ArgMeta{ {Type: "const char*", Name: "pathname"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, {Type: "dev_t", Name: "dev"}, }, dependencies: Dependencies{ @@ -5980,7 +5981,7 @@ var CoreEvents = map[ID]Definition{ params: []trace.ArgMeta{ {Type: "const char*", Name: "name"}, {Type: "int", Name: "oflag"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, {Type: "struct mq_attr*", Name: "attr"}, }, dependencies: Dependencies{ @@ -6411,7 +6412,7 @@ var CoreEvents = map[ID]Definition{ {Type: "int", Name: "dirfd"}, {Type: "const char*", Name: "pathname"}, {Type: "int", Name: "flags"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, }, dependencies: Dependencies{ probes: []Probe{ @@ -6436,7 +6437,7 @@ var CoreEvents = map[ID]Definition{ params: []trace.ArgMeta{ {Type: "int", Name: "dirfd"}, {Type: "const char*", Name: "pathname"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, }, dependencies: Dependencies{ probes: []Probe{ @@ -6461,7 +6462,7 @@ var CoreEvents = map[ID]Definition{ params: []trace.ArgMeta{ {Type: "int", Name: "dirfd"}, {Type: "const char*", Name: "pathname"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, {Type: "dev_t", Name: "dev"}, }, dependencies: Dependencies{ @@ -6694,7 +6695,7 @@ var CoreEvents = map[ID]Definition{ params: []trace.ArgMeta{ {Type: "int", Name: "dirfd"}, {Type: "const char*", Name: "pathname"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, {Type: "int", Name: "flags"}, }, dependencies: Dependencies{ @@ -12065,7 +12066,7 @@ var CoreEvents = map[ID]Definition{ params: []trace.ArgMeta{ {Type: "const char*", Name: "file_name"}, {Type: "const char*", Name: "path"}, - {Type: "mode_t", Name: "mode"}, + {Type: "umode_t", Name: "mode"}, {Type: "void*", Name: "proc_ops_addr"}, }, }, @@ -13042,6 +13043,23 @@ var CoreEvents = map[ID]Definition{ {Type: "int", Name: "tz_dsttime"}, }, }, + ChmodCommon: { + id: ChmodCommon, + id32Bit: Sys32Undefined, + name: "chmod_common", + version: NewVersion(1, 0, 0), + syscall: true, + sets: []string{}, + params: []trace.ArgMeta{ + {Type: "const char*", Name: "pathname"}, + {Type: "umode_t", Name: "mode"}, + }, + dependencies: Dependencies{ + probes: []Probe{ + {handle: probes.ChmodCommon, required: true}, + }, + }, + }, // // Begin of Signal Events (Control Plane) // diff --git a/pkg/events/parse_args.go b/pkg/events/parse_args.go index 5f9f184101d9..61b803c0dc0c 100644 --- a/pkg/events/parse_args.go +++ b/pkg/events/parse_args.go @@ -133,13 +133,7 @@ func ParseArgs(event *trace.Event) error { parseOpenFlagArgument(flagsArg, uint64(flags)) } } - case Mknod, Mknodat, Chmod, Fchmod, Fchmodat: - if modeArg := GetArg(event, "mode"); modeArg != nil { - if mode, isUint32 := modeArg.Value.(uint32); isUint32 { - parseInodeMode(modeArg, uint64(mode)) - } - } - case SecurityInodeMknod: + case Mknod, Mknodat, SecurityInodeMknod, Chmod, Fchmod, Fchmodat, ChmodCommon: if modeArg := GetArg(event, "mode"); modeArg != nil { if mode, isUint16 := modeArg.Value.(uint16); isUint16 { parseInodeMode(modeArg, uint64(mode)) diff --git a/tests/integration/event_filters_test.go b/tests/integration/event_filters_test.go index e3e9868ea25f..ad58108213ac 100644 --- a/tests/integration/event_filters_test.go +++ b/tests/integration/event_filters_test.go @@ -1603,7 +1603,7 @@ func Test_EventFilters(t *testing.T) { expectEvent(anyHost, "fakeprog1", testutils.CPUForTests, anyPID, 0, events.Openat, orPolNames("comm-event-data-64"), orPolIDs(64), expectArg("dirfd", int32(0)), expectArg("flags", int32(0)), - expectArg("mode", uint32(0)), + expectArg("mode", uint16(0)), ), }, []string{}, @@ -1615,7 +1615,7 @@ func Test_EventFilters(t *testing.T) { []trace.Event{ expectEvent(anyHost, "fakeprog2", testutils.CPUForTests, anyPID, 0, events.Open, orPolNames("comm-event-data-42"), orPolIDs(42), expectArg("flags", int32(0)), - expectArg("mode", uint32(0)), + expectArg("mode", uint16(0)), ), }, []string{}, @@ -1683,7 +1683,7 @@ func Test_EventFilters(t *testing.T) { expectEvent(anyHost, "fakeprog1", testutils.CPUForTests, anyPID, 0, events.Openat, orPolNames("comm-event-retval-64"), orPolIDs(64), expectArg("dirfd", int32(0)), expectArg("flags", int32(0)), - expectArg("mode", uint32(0)), + expectArg("mode", uint16(0)), ), }, []string{},