Skip to content

Commit 55391ff

Browse files
committed
Add security_task_prctl event
1 parent d1d6857 commit 55391ff

File tree

9 files changed

+394
-9
lines changed

9 files changed

+394
-9
lines changed

pkg/ebpf/c/tracee.bpf.c

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5387,6 +5387,250 @@ int BPF_KPROBE(trace_chmod_common)
53875387
return events_perf_submit(&p, 0);
53885388
}
53895389

5390+
SEC("kprobe/security_task_prctl")
5391+
int BPF_KPROBE(trace_security_task_prctl)
5392+
{
5393+
program_data_t p = {};
5394+
if (!init_program_data(&p, ctx, SECURITY_TASK_PRCTL))
5395+
return 0;
5396+
5397+
if (!evaluate_scope_filters(&p))
5398+
return 0;
5399+
5400+
// Save raw args
5401+
int option = PT_REGS_PARM1(ctx);
5402+
unsigned long arg2 = PT_REGS_PARM2(ctx);
5403+
unsigned long arg3 = PT_REGS_PARM3(ctx);
5404+
unsigned long arg4 = PT_REGS_PARM4(ctx);
5405+
unsigned long arg5 = PT_REGS_PARM5(ctx);
5406+
save_to_submit_buf(&p.event->args_buf, &option, sizeof(option), 0);
5407+
save_to_submit_buf(&p.event->args_buf, &arg2, sizeof(arg2), 1);
5408+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 2);
5409+
save_to_submit_buf(&p.event->args_buf, &arg4, sizeof(arg4), 3);
5410+
save_to_submit_buf(&p.event->args_buf, &arg5, sizeof(arg5), 4);
5411+
5412+
// Save PR_SET_VMA arg
5413+
if (option == PR_SET_VMA && arg2 == PR_SET_VMA_ANON_NAME && arg5 != 0)
5414+
save_str_to_buf(&p.event->args_buf, (char *) arg5, 5);
5415+
5416+
// Save PR_SET_MM args
5417+
if (option == PR_SET_MM) {
5418+
// Save all old mm info regardless of operation
5419+
struct mm_struct *mm = get_mm_from_task(p.event->task);
5420+
save_to_submit_buf(&p.event->args_buf,
5421+
__builtin_preserve_access_index(&mm->start_code),
5422+
sizeof(mm->start_code),
5423+
6);
5424+
save_to_submit_buf(&p.event->args_buf,
5425+
__builtin_preserve_access_index(&mm->end_code),
5426+
sizeof(mm->end_code),
5427+
7);
5428+
save_to_submit_buf(&p.event->args_buf,
5429+
__builtin_preserve_access_index(&mm->start_data),
5430+
sizeof(mm->start_data),
5431+
8);
5432+
save_to_submit_buf(&p.event->args_buf,
5433+
__builtin_preserve_access_index(&mm->end_data),
5434+
sizeof(mm->end_data),
5435+
9);
5436+
save_to_submit_buf(&p.event->args_buf,
5437+
__builtin_preserve_access_index(&mm->start_brk),
5438+
sizeof(mm->start_brk),
5439+
10);
5440+
save_to_submit_buf(
5441+
&p.event->args_buf, __builtin_preserve_access_index(&mm->brk), sizeof(mm->brk), 11);
5442+
save_to_submit_buf(&p.event->args_buf,
5443+
__builtin_preserve_access_index(&mm->start_stack),
5444+
sizeof(mm->start_stack),
5445+
12);
5446+
save_to_submit_buf(&p.event->args_buf,
5447+
__builtin_preserve_access_index(&mm->arg_start),
5448+
sizeof(mm->arg_start),
5449+
13);
5450+
save_to_submit_buf(&p.event->args_buf,
5451+
__builtin_preserve_access_index(&mm->arg_end),
5452+
sizeof(mm->arg_end),
5453+
14);
5454+
save_to_submit_buf(&p.event->args_buf,
5455+
__builtin_preserve_access_index(&mm->env_start),
5456+
sizeof(mm->env_start),
5457+
15);
5458+
save_to_submit_buf(&p.event->args_buf,
5459+
__builtin_preserve_access_index(&mm->env_end),
5460+
sizeof(mm->env_end),
5461+
16);
5462+
void *saved_auxv;
5463+
u32 size;
5464+
struct mm_struct___redhat *mm_redhat = (struct mm_struct___redhat *) mm;
5465+
// Upstream kernel
5466+
if (bpf_core_field_exists(mm->saved_auxv)) {
5467+
saved_auxv = __builtin_preserve_access_index(&mm->saved_auxv);
5468+
size = bpf_core_field_size(mm->saved_auxv);
5469+
}
5470+
// Red Hat kernel
5471+
else if (bpf_core_field_exists(mm_redhat->mm_rh)) {
5472+
struct mm_struct_rh *mm_rh = BPF_CORE_READ(mm_redhat, mm_rh);
5473+
saved_auxv = __builtin_preserve_access_index(&mm_rh->saved_auxv);
5474+
size = bpf_core_field_size(mm_rh->saved_auxv);
5475+
}
5476+
// Unknown variation of mm_struct
5477+
else
5478+
return 0;
5479+
5480+
save_bytes_to_buf(&p.event->args_buf, saved_auxv, size, 17);
5481+
5482+
struct file *exe = BPF_CORE_READ(mm, exe_file);
5483+
void *exe_path = get_path_str(__builtin_preserve_access_index(&exe->f_path));
5484+
dev_t exe_dev = get_dev_from_file(exe);
5485+
unsigned long exe_inode = get_inode_nr_from_file(exe);
5486+
u64 exe_ctime = get_ctime_nanosec_from_file(exe);
5487+
umode_t exe_inode_mode = get_inode_mode_from_file(exe);
5488+
5489+
save_str_to_buf(&p.event->args_buf, exe_path, 18);
5490+
save_to_submit_buf(&p.event->args_buf, &exe_dev, sizeof(exe_dev), 19);
5491+
save_to_submit_buf(&p.event->args_buf, &exe_inode, sizeof(exe_inode), 20);
5492+
save_to_submit_buf(&p.event->args_buf, &exe_ctime, sizeof(exe_ctime), 21);
5493+
save_to_submit_buf(&p.event->args_buf, &exe_inode_mode, sizeof(exe_inode_mode), 22);
5494+
5495+
struct prctl_mm_map *mm_map;
5496+
5497+
// Save new mm info according to operation
5498+
switch (arg2) {
5499+
case PR_SET_MM_START_CODE:
5500+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 23);
5501+
break;
5502+
case PR_SET_MM_END_CODE:
5503+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 24);
5504+
break;
5505+
case PR_SET_MM_START_DATA:
5506+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 25);
5507+
break;
5508+
case PR_SET_MM_END_DATA:
5509+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 26);
5510+
break;
5511+
case PR_SET_MM_START_BRK:
5512+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 27);
5513+
break;
5514+
case PR_SET_MM_BRK:
5515+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 28);
5516+
break;
5517+
case PR_SET_MM_START_STACK:
5518+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 29);
5519+
break;
5520+
case PR_SET_MM_ARG_START:
5521+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 30);
5522+
break;
5523+
case PR_SET_MM_ARG_END:
5524+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 31);
5525+
break;
5526+
case PR_SET_MM_ENV_START:
5527+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 32);
5528+
break;
5529+
case PR_SET_MM_ENV_END:
5530+
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 33);
5531+
break;
5532+
case PR_SET_MM_AUXV:
5533+
size = AT_VECTOR_SIZE * sizeof(unsigned long);
5534+
if (arg4 < size)
5535+
size = arg4;
5536+
save_bytes_to_buf(&p.event->args_buf, (void *) arg3, size, 34);
5537+
break;
5538+
case PR_SET_MM_EXE_FILE:
5539+
exe = get_struct_file_from_fd(arg3);
5540+
exe_path = get_path_str(__builtin_preserve_access_index(&exe->f_path));
5541+
exe_dev = get_dev_from_file(exe);
5542+
exe_inode = get_inode_nr_from_file(exe);
5543+
exe_ctime = get_ctime_nanosec_from_file(exe);
5544+
exe_inode_mode = get_inode_mode_from_file(exe);
5545+
5546+
save_str_to_buf(&p.event->args_buf, exe_path, 35);
5547+
save_to_submit_buf(&p.event->args_buf, &exe_dev, sizeof(exe_dev), 36);
5548+
save_to_submit_buf(&p.event->args_buf, &exe_inode, sizeof(exe_inode), 37);
5549+
save_to_submit_buf(&p.event->args_buf, &exe_ctime, sizeof(exe_ctime), 38);
5550+
save_to_submit_buf(&p.event->args_buf, &exe_inode_mode, sizeof(exe_inode_mode), 39);
5551+
5552+
break;
5553+
case PR_SET_MM_MAP:
5554+
mm_map = (struct prctl_mm_map *) arg3;
5555+
save_to_submit_buf(&p.event->args_buf,
5556+
__builtin_preserve_access_index(&mm_map->start_code),
5557+
sizeof(mm_map->start_code),
5558+
23);
5559+
save_to_submit_buf(&p.event->args_buf,
5560+
__builtin_preserve_access_index(&mm_map->end_code),
5561+
sizeof(mm_map->end_code),
5562+
24);
5563+
save_to_submit_buf(&p.event->args_buf,
5564+
__builtin_preserve_access_index(&mm_map->start_data),
5565+
sizeof(mm_map->start_data),
5566+
25);
5567+
save_to_submit_buf(&p.event->args_buf,
5568+
__builtin_preserve_access_index(&mm_map->end_data),
5569+
sizeof(mm_map->end_data),
5570+
26);
5571+
save_to_submit_buf(&p.event->args_buf,
5572+
__builtin_preserve_access_index(&mm_map->start_brk),
5573+
sizeof(mm_map->start_brk),
5574+
27);
5575+
save_to_submit_buf(&p.event->args_buf,
5576+
__builtin_preserve_access_index(&mm_map->brk),
5577+
sizeof(mm_map->brk),
5578+
28);
5579+
save_to_submit_buf(&p.event->args_buf,
5580+
__builtin_preserve_access_index(&mm_map->start_stack),
5581+
sizeof(mm_map->start_stack),
5582+
29);
5583+
save_to_submit_buf(&p.event->args_buf,
5584+
__builtin_preserve_access_index(&mm_map->arg_start),
5585+
sizeof(mm_map->arg_start),
5586+
30);
5587+
save_to_submit_buf(&p.event->args_buf,
5588+
__builtin_preserve_access_index(&mm_map->arg_end),
5589+
sizeof(mm_map->arg_end),
5590+
31);
5591+
save_to_submit_buf(&p.event->args_buf,
5592+
__builtin_preserve_access_index(&mm_map->env_start),
5593+
sizeof(mm_map->env_start),
5594+
32);
5595+
save_to_submit_buf(&p.event->args_buf,
5596+
__builtin_preserve_access_index(&mm_map->env_end),
5597+
sizeof(mm_map->env_end),
5598+
33);
5599+
save_bytes_to_buf(&p.event->args_buf,
5600+
BPF_CORE_READ_USER(mm_map, auxv),
5601+
BPF_CORE_READ_USER(mm_map, auxv_size),
5602+
34);
5603+
5604+
exe = get_struct_file_from_fd(BPF_CORE_READ_USER(mm_map, exe_fd));
5605+
exe_path = get_path_str(__builtin_preserve_access_index(&exe->f_path));
5606+
exe_dev = get_dev_from_file(exe);
5607+
exe_inode = get_inode_nr_from_file(exe);
5608+
exe_ctime = get_ctime_nanosec_from_file(exe);
5609+
exe_inode_mode = get_inode_mode_from_file(exe);
5610+
5611+
save_str_to_buf(&p.event->args_buf, exe_path, 35);
5612+
save_to_submit_buf(&p.event->args_buf, &exe_dev, sizeof(exe_dev), 36);
5613+
save_to_submit_buf(&p.event->args_buf, &exe_inode, sizeof(exe_inode), 37);
5614+
save_to_submit_buf(&p.event->args_buf, &exe_ctime, sizeof(exe_ctime), 38);
5615+
save_to_submit_buf(&p.event->args_buf, &exe_inode_mode, sizeof(exe_inode_mode), 39);
5616+
5617+
break;
5618+
default:
5619+
// unknown/invalid operation
5620+
return 0;
5621+
}
5622+
}
5623+
5624+
// Save old securebits for PR_SET_SECUREBITS
5625+
if (option == PR_SET_SECUREBITS) {
5626+
struct task_struct *task = p.event->task;
5627+
unsigned int old_securebits = BPF_CORE_READ(task, cred, securebits);
5628+
save_to_submit_buf(&p.event->args_buf, &old_securebits, sizeof(old_securebits), 40);
5629+
}
5630+
5631+
return events_perf_submit(&p, 0);
5632+
}
5633+
53905634
//
53915635
// Syscall checkers
53925636
//

pkg/ebpf/c/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ enum event_id_e
136136
CHMOD_COMMON,
137137
OPEN_FILE_NS,
138138
OPEN_FILE_MOUNT,
139+
SECURITY_TASK_PRCTL,
139140
MAX_EVENT_ID,
140141
NO_EVENT_SUBMIT,
141142

pkg/ebpf/c/vmlinux.h

Lines changed: 43 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;
@@ -702,20 +703,54 @@ struct rb_root {
702703
struct rb_node *rb_node;
703704
};
704705

706+
#if defined(__TARGET_ARCH_x86)
707+
#define AT_VECTOR_SIZE_ARCH 3
708+
#elif defined(__TARGET_ARCH_arm64)
709+
#define AT_VECTOR_SIZE_ARCH 2
710+
#else
711+
#define AT_VECTOR_SIZE_ARCH 0
712+
#endif
713+
714+
#define AT_VECTOR_SIZE_BASE 22
715+
#define AT_VECTOR_SIZE (2 * (AT_VECTOR_SIZE_ARCH + AT_VECTOR_SIZE_BASE + 1))
716+
705717
struct mm_struct {
706718
struct {
707719
struct rb_root mm_rb;
708-
long unsigned int stack_vm;
709-
long unsigned int start_brk;
710-
long unsigned int brk;
711-
long unsigned int start_stack;
712-
long unsigned int arg_start;
713-
long unsigned int arg_end;
714-
long unsigned int env_start;
715-
long unsigned int env_end;
720+
unsigned long stack_vm;
721+
unsigned long start_code;
722+
unsigned long end_code;
723+
unsigned long start_data;
724+
unsigned long end_data;
725+
unsigned long start_brk;
726+
unsigned long brk;
727+
unsigned long start_stack;
728+
unsigned long arg_start;
729+
unsigned long arg_end;
730+
unsigned long env_start;
731+
unsigned long env_end;
732+
unsigned long saved_auxv[AT_VECTOR_SIZE];
733+
struct file *exe_file;
716734
};
717735
};
718736

737+
struct prctl_mm_map {
738+
__u64 start_code;
739+
__u64 end_code;
740+
__u64 start_data;
741+
__u64 end_data;
742+
__u64 start_brk;
743+
__u64 brk;
744+
__u64 start_stack;
745+
__u64 arg_start;
746+
__u64 arg_end;
747+
__u64 env_start;
748+
__u64 env_end;
749+
__u64 *auxv;
750+
__u32 auxv_size;
751+
__u32 exe_fd;
752+
};
753+
719754
struct vfsmount {
720755
struct dentry *mnt_root;
721756
struct super_block *mnt_sb;

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[AT_VECTOR_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"),

0 commit comments

Comments
 (0)