Skip to content

Commit 2d70e31

Browse files
committed
Add security_task_prctl event
1 parent 1150c94 commit 2d70e31

File tree

9 files changed

+362
-9
lines changed

9 files changed

+362
-9
lines changed

pkg/ebpf/c/tracee.bpf.c

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5300,6 +5300,234 @@ int BPF_KPROBE(trace_chmod_common)
53005300
return events_perf_submit(&p, 0);
53015301
}
53025302

5303+
SEC("kprobe/security_task_prctl")
5304+
int BPF_KPROBE(trace_security_task_prctl)
5305+
{
5306+
program_data_t p = {};
5307+
if (!init_program_data(&p, ctx, SECURITY_TASK_PRCTL))
5308+
return 0;
5309+
5310+
if (!evaluate_scope_filters(&p))
5311+
return 0;
5312+
5313+
// Save raw args
5314+
int option = PT_REGS_PARM1(ctx);
5315+
unsigned long arg2 = PT_REGS_PARM2(ctx);
5316+
unsigned long arg3 = PT_REGS_PARM3(ctx);
5317+
unsigned long arg4 = PT_REGS_PARM4(ctx);
5318+
unsigned long arg5 = PT_REGS_PARM5(ctx);
5319+
save_to_submit_buf(&p.event->args_buf, &option, sizeof(option), 0);
5320+
save_to_submit_buf(&p.event->args_buf, &arg2, sizeof(arg2), 1);
5321+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 2);
5322+
save_to_submit_buf(&p.event->args_buf, &arg4, sizeof(arg4), 3);
5323+
save_to_submit_buf(&p.event->args_buf, &arg5, sizeof(arg5), 4);
5324+
5325+
// Save PR_SET_VMA arg
5326+
if (option == PR_SET_VMA)
5327+
save_str_to_buf(&p.event->args_buf, (char *) arg5, 5);
5328+
5329+
// Save PR_SET_MM args
5330+
if (option == PR_SET_MM) {
5331+
// Save all old mm info regardless of operation
5332+
struct mm_struct *mm = get_mm_from_task(p.event->task);
5333+
save_to_submit_buf(&p.event->args_buf,
5334+
__builtin_preserve_access_index(&mm->start_code),
5335+
sizeof(mm->start_code),
5336+
6);
5337+
save_to_submit_buf(&p.event->args_buf,
5338+
__builtin_preserve_access_index(&mm->end_code),
5339+
sizeof(mm->end_code),
5340+
7);
5341+
save_to_submit_buf(&p.event->args_buf,
5342+
__builtin_preserve_access_index(&mm->start_data),
5343+
sizeof(mm->start_data),
5344+
8);
5345+
save_to_submit_buf(&p.event->args_buf,
5346+
__builtin_preserve_access_index(&mm->end_data),
5347+
sizeof(mm->end_data),
5348+
9);
5349+
save_to_submit_buf(&p.event->args_buf,
5350+
__builtin_preserve_access_index(&mm->start_brk),
5351+
sizeof(mm->start_brk),
5352+
10);
5353+
save_to_submit_buf(
5354+
&p.event->args_buf, __builtin_preserve_access_index(&mm->brk), sizeof(mm->brk), 11);
5355+
save_to_submit_buf(&p.event->args_buf,
5356+
__builtin_preserve_access_index(&mm->start_stack),
5357+
sizeof(mm->start_stack),
5358+
12);
5359+
save_to_submit_buf(&p.event->args_buf,
5360+
__builtin_preserve_access_index(&mm->arg_start),
5361+
sizeof(mm->arg_start),
5362+
13);
5363+
save_to_submit_buf(&p.event->args_buf,
5364+
__builtin_preserve_access_index(&mm->arg_end),
5365+
sizeof(mm->arg_end),
5366+
14);
5367+
save_to_submit_buf(&p.event->args_buf,
5368+
__builtin_preserve_access_index(&mm->env_start),
5369+
sizeof(mm->env_start),
5370+
15);
5371+
save_to_submit_buf(&p.event->args_buf,
5372+
__builtin_preserve_access_index(&mm->env_end),
5373+
sizeof(mm->env_end),
5374+
16);
5375+
void *saved_auxv;
5376+
u32 size;
5377+
if (bpf_core_field_exists(mm->saved_auxv)) {
5378+
saved_auxv = BPF_CORE_READ(mm, saved_auxv);
5379+
size = bpf_core_field_size(mm->saved_auxv);
5380+
}
5381+
// Red Hat version
5382+
else {
5383+
struct mm_struct___redhat *mm_redhat = (struct mm_struct___redhat *) mm;
5384+
saved_auxv = BPF_CORE_READ(mm_redhat, mm_rh, saved_auxv);
5385+
size = bpf_core_field_size(mm_redhat->mm_rh->saved_auxv);
5386+
}
5387+
save_bytes_to_buf(&p.event->args_buf, saved_auxv, size, 17);
5388+
5389+
struct file *exe = BPF_CORE_READ(mm, exe_file);
5390+
void *exe_path = get_path_str(__builtin_preserve_access_index(&exe->f_path));
5391+
dev_t exe_dev = get_dev_from_file(exe);
5392+
unsigned long exe_inode = get_inode_nr_from_file(exe);
5393+
u64 exe_ctime = get_ctime_nanosec_from_file(exe);
5394+
umode_t exe_inode_mode = get_inode_mode_from_file(exe);
5395+
5396+
save_str_to_buf(&p.event->args_buf, exe_path, 18);
5397+
save_to_submit_buf(&p.event->args_buf, &exe_dev, sizeof(exe_dev), 19);
5398+
save_to_submit_buf(&p.event->args_buf, &exe_inode, sizeof(exe_inode), 20);
5399+
save_to_submit_buf(&p.event->args_buf, &exe_ctime, sizeof(exe_ctime), 21);
5400+
save_to_submit_buf(&p.event->args_buf, &exe_inode_mode, sizeof(exe_inode_mode), 22);
5401+
5402+
struct prctl_mm_map *mm_map;
5403+
5404+
// Save new mm info according to operation
5405+
switch (arg2) {
5406+
case PR_SET_MM_START_CODE:
5407+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 23);
5408+
break;
5409+
case PR_SET_MM_END_CODE:
5410+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 24);
5411+
break;
5412+
case PR_SET_MM_START_DATA:
5413+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 25);
5414+
break;
5415+
case PR_SET_MM_END_DATA:
5416+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 26);
5417+
break;
5418+
case PR_SET_MM_START_BRK:
5419+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 27);
5420+
break;
5421+
case PR_SET_MM_BRK:
5422+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 28);
5423+
break;
5424+
case PR_SET_MM_START_STACK:
5425+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 29);
5426+
break;
5427+
case PR_SET_MM_ARG_START:
5428+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 30);
5429+
break;
5430+
case PR_SET_MM_ARG_END:
5431+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 31);
5432+
break;
5433+
case PR_SET_MM_ENV_START:
5434+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 32);
5435+
break;
5436+
case PR_SET_MM_ENV_END:
5437+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 33);
5438+
break;
5439+
case PR_SET_MM_AUXV:
5440+
save_bytes_to_buf(&p.event->args_buf, (void *) arg3, arg4, 34);
5441+
break;
5442+
case PR_SET_MM_EXE_FILE:
5443+
exe = get_struct_file_from_fd(arg3);
5444+
exe_path = get_path_str(__builtin_preserve_access_index(&exe->f_path));
5445+
exe_dev = get_dev_from_file(exe);
5446+
exe_inode = get_inode_nr_from_file(exe);
5447+
exe_ctime = get_ctime_nanosec_from_file(exe);
5448+
exe_inode_mode = get_inode_mode_from_file(exe);
5449+
5450+
save_str_to_buf(&p.event->args_buf, exe_path, 35);
5451+
save_to_submit_buf(&p.event->args_buf, &exe_dev, sizeof(exe_dev), 36);
5452+
save_to_submit_buf(&p.event->args_buf, &exe_inode, sizeof(exe_inode), 37);
5453+
save_to_submit_buf(&p.event->args_buf, &exe_ctime, sizeof(exe_ctime), 38);
5454+
save_to_submit_buf(&p.event->args_buf, &exe_inode_mode, sizeof(exe_inode_mode), 39);
5455+
5456+
break;
5457+
case PR_SET_MM_MAP:
5458+
mm_map = (struct prctl_mm_map *) arg3;
5459+
save_to_submit_buf(&p.event->args_buf,
5460+
__builtin_preserve_access_index(&mm_map->start_code),
5461+
sizeof(mm_map->start_code),
5462+
23);
5463+
save_to_submit_buf(&p.event->args_buf,
5464+
__builtin_preserve_access_index(&mm_map->end_code),
5465+
sizeof(mm_map->end_code),
5466+
24);
5467+
save_to_submit_buf(&p.event->args_buf,
5468+
__builtin_preserve_access_index(&mm_map->start_data),
5469+
sizeof(mm_map->start_data),
5470+
25);
5471+
save_to_submit_buf(&p.event->args_buf,
5472+
__builtin_preserve_access_index(&mm_map->end_data),
5473+
sizeof(mm_map->end_data),
5474+
26);
5475+
save_to_submit_buf(&p.event->args_buf,
5476+
__builtin_preserve_access_index(&mm_map->start_brk),
5477+
sizeof(mm_map->start_brk),
5478+
27);
5479+
save_to_submit_buf(&p.event->args_buf,
5480+
__builtin_preserve_access_index(&mm_map->brk),
5481+
sizeof(mm_map->brk),
5482+
28);
5483+
save_to_submit_buf(&p.event->args_buf,
5484+
__builtin_preserve_access_index(&mm_map->start_stack),
5485+
sizeof(mm_map->start_stack),
5486+
29);
5487+
save_to_submit_buf(&p.event->args_buf,
5488+
__builtin_preserve_access_index(&mm_map->arg_start),
5489+
sizeof(mm_map->arg_start),
5490+
30);
5491+
save_to_submit_buf(&p.event->args_buf,
5492+
__builtin_preserve_access_index(&mm_map->arg_end),
5493+
sizeof(mm_map->arg_end),
5494+
31);
5495+
save_to_submit_buf(&p.event->args_buf,
5496+
__builtin_preserve_access_index(&mm_map->env_start),
5497+
sizeof(mm_map->env_start),
5498+
32);
5499+
save_to_submit_buf(&p.event->args_buf,
5500+
__builtin_preserve_access_index(&mm_map->env_end),
5501+
sizeof(mm_map->env_end),
5502+
33);
5503+
save_bytes_to_buf(&p.event->args_buf,
5504+
BPF_CORE_READ_USER(mm_map, auxv),
5505+
BPF_CORE_READ_USER(mm_map, auxv_size),
5506+
34);
5507+
5508+
exe = get_struct_file_from_fd(BPF_CORE_READ_USER(mm_map, exe_fd));
5509+
exe_path = get_path_str(__builtin_preserve_access_index(&exe->f_path));
5510+
exe_dev = get_dev_from_file(exe);
5511+
exe_inode = get_inode_nr_from_file(exe);
5512+
exe_ctime = get_ctime_nanosec_from_file(exe);
5513+
exe_inode_mode = get_inode_mode_from_file(exe);
5514+
5515+
save_str_to_buf(&p.event->args_buf, exe_path, 35);
5516+
save_to_submit_buf(&p.event->args_buf, &exe_dev, sizeof(exe_dev), 36);
5517+
save_to_submit_buf(&p.event->args_buf, &exe_inode, sizeof(exe_inode), 37);
5518+
save_to_submit_buf(&p.event->args_buf, &exe_ctime, sizeof(exe_ctime), 38);
5519+
save_to_submit_buf(&p.event->args_buf, &exe_inode_mode, sizeof(exe_inode_mode), 39);
5520+
5521+
break;
5522+
default:
5523+
// unknown/invalid operation
5524+
return 0;
5525+
}
5526+
}
5527+
5528+
return events_perf_submit(&p, 0);
5529+
}
5530+
53035531
//
53045532
// Syscall checkers
53055533
//

pkg/ebpf/c/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ enum event_id_e
134134
SECURITY_TASK_SETRLIMIT,
135135
SECURITY_SETTIME64,
136136
CHMOD_COMMON,
137+
SECURITY_TASK_PRCTL,
137138
MAX_EVENT_ID,
138139
NO_EVENT_SUBMIT,
139140

pkg/ebpf/c/vmlinux.h

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -699,17 +699,40 @@ struct rb_root {
699699
struct mm_struct {
700700
struct {
701701
struct rb_root mm_rb;
702-
long unsigned int stack_vm;
703-
long unsigned int start_brk;
704-
long unsigned int brk;
705-
long unsigned int start_stack;
706-
long unsigned int arg_start;
707-
long unsigned int arg_end;
708-
long unsigned int env_start;
709-
long unsigned int env_end;
702+
unsigned long stack_vm;
703+
unsigned long start_code;
704+
unsigned long end_code;
705+
unsigned long start_data;
706+
unsigned long end_data;
707+
unsigned long start_brk;
708+
unsigned long brk;
709+
unsigned long start_stack;
710+
unsigned long arg_start;
711+
unsigned long arg_end;
712+
unsigned long env_start;
713+
unsigned long env_end;
714+
unsigned long saved_auxv[0]; // length can be obtained at runtime using bpf_core_file_size()
715+
struct file *exe_file;
710716
};
711717
};
712718

719+
struct prctl_mm_map {
720+
__u64 start_code;
721+
__u64 end_code;
722+
__u64 start_data;
723+
__u64 end_data;
724+
__u64 start_brk;
725+
__u64 brk;
726+
__u64 start_stack;
727+
__u64 arg_start;
728+
__u64 arg_end;
729+
__u64 env_start;
730+
__u64 env_end;
731+
__u64 *auxv;
732+
__u32 auxv_size;
733+
__u32 exe_fd;
734+
};
735+
713736
struct vfsmount {
714737
struct dentry *mnt_root;
715738
};

pkg/ebpf/c/vmlinux_flavors.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,31 @@ struct inode___older_v611 {
105105
struct timespec64 __i_ctime;
106106
};
107107

108+
// Red Hat mm_struct variation
109+
struct mm_struct_rh {
110+
unsigned long saved_auxv[0]; // length can be obtained at runtime using bpf_core_file_size()
111+
};
112+
113+
struct mm_struct___redhat {
114+
struct {
115+
unsigned long start_code;
116+
unsigned long end_code;
117+
unsigned long start_data;
118+
unsigned long end_data;
119+
unsigned long start_brk;
120+
unsigned long brk;
121+
unsigned long start_stack;
122+
unsigned long arg_start;
123+
unsigned long arg_end;
124+
unsigned long env_start;
125+
unsigned long env_end;
126+
struct file *exe_file;
127+
};
128+
union {
129+
struct mm_struct_rh *mm_rh;
130+
};
131+
};
132+
108133
///////////////////
109134

110135
#pragma clang attribute pop

pkg/ebpf/c/vmlinux_missing.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,4 +266,22 @@ static inline struct inet_sock *inet_sk(const struct sock *sk)
266266
#define IPPROTO_DSTOPTS 60 // IPv6 destination options
267267
#define IPPROTO_MH 135 // IPv6 mobility header
268268

269+
#define PR_SET_VMA 0x53564d41
270+
#define PR_SET_MM 35
271+
#define PR_SET_MM_START_CODE 1
272+
#define PR_SET_MM_END_CODE 2
273+
#define PR_SET_MM_START_DATA 3
274+
#define PR_SET_MM_END_DATA 4
275+
#define PR_SET_MM_START_STACK 5
276+
#define PR_SET_MM_START_BRK 6
277+
#define PR_SET_MM_BRK 7
278+
#define PR_SET_MM_ARG_START 8
279+
#define PR_SET_MM_ARG_END 9
280+
#define PR_SET_MM_ENV_START 10
281+
#define PR_SET_MM_ENV_END 11
282+
#define PR_SET_MM_AUXV 12
283+
#define PR_SET_MM_EXE_FILE 13
284+
#define PR_SET_MM_MAP 14
285+
#define PR_SET_MM_MAP_SIZE 15
286+
269287
#endif

pkg/ebpf/probes/probe_group.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ func NewDefaultProbeGroup(module *bpf.Module, netEnabled bool) (*ProbeGroup, err
257257
Dup3: NewTraceProbe(SyscallEnter, "dup3", "trace_dup3"),
258258
Dup3Ret: NewTraceProbe(SyscallExit, "dup3", "trace_ret_dup3"),
259259
ChmodCommon: NewTraceProbe(KProbe, "chmod_common", "trace_chmod_common"),
260+
SecurityTaskPrctl: NewTraceProbe(KProbe, "security_task_prctl", "trace_security_task_prctl"),
260261

261262
TestUnavailableHook: NewTraceProbe(KProbe, "non_existing_func", "empty_kprobe"),
262263
ExecTest: NewTraceProbe(RawTracepoint, "raw_syscalls:sched_process_exec", "tracepoint__exec_test"),

pkg/ebpf/probes/probes.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ const (
162162
Dup3
163163
Dup3Ret
164164
ChmodCommon
165+
SecurityTaskPrctl
165166
)
166167

167168
// Test probe handles

0 commit comments

Comments
 (0)