Skip to content

Commit e73cf9a

Browse files
committed
Add security_task_prctl event
1 parent 12a7e77 commit e73cf9a

File tree

9 files changed

+374
-9
lines changed

9 files changed

+374
-9
lines changed

pkg/ebpf/c/tracee.bpf.c

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5296,6 +5296,241 @@ int BPF_KPROBE(trace_chmod_common)
52965296
return events_perf_submit(&p, 0);
52975297
}
52985298

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

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: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ struct task_struct {
293293
u64 start_boottime;
294294
u64 real_start_time;
295295
const struct cred *real_cred;
296+
const struct cred *cred;
296297
char comm[16];
297298
struct files_struct *files;
298299
struct nsproxy *nsproxy;
@@ -699,17 +700,40 @@ struct rb_root {
699700
struct mm_struct {
700701
struct {
701702
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;
703+
unsigned long stack_vm;
704+
unsigned long start_code;
705+
unsigned long end_code;
706+
unsigned long start_data;
707+
unsigned long end_data;
708+
unsigned long start_brk;
709+
unsigned long brk;
710+
unsigned long start_stack;
711+
unsigned long arg_start;
712+
unsigned long arg_end;
713+
unsigned long env_start;
714+
unsigned long env_end;
715+
unsigned long saved_auxv[0]; // length can be obtained at runtime using bpf_core_file_size()
716+
struct file *exe_file;
710717
};
711718
};
712719

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

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: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,4 +266,24 @@ 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_SECUREBITS 28
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+
#define PR_SET_VMA 0x53564d41
287+
#define PR_SET_VMA_ANON_NAME 0
288+
269289
#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)