Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 244 additions & 0 deletions pkg/ebpf/c/tracee.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -5412,6 +5412,250 @@ int BPF_KPROBE(trace_chmod_common)
return events_perf_submit(&p, 0);
}

SEC("kprobe/security_task_prctl")
int BPF_KPROBE(trace_security_task_prctl)
{
program_data_t p = {};
if (!init_program_data(&p, ctx, SECURITY_TASK_PRCTL))
return 0;

if (!evaluate_scope_filters(&p))
return 0;

// Save raw args
int option = PT_REGS_PARM1(ctx);
unsigned long arg2 = PT_REGS_PARM2(ctx);
unsigned long arg3 = PT_REGS_PARM3(ctx);
unsigned long arg4 = PT_REGS_PARM4(ctx);
unsigned long arg5 = PT_REGS_PARM5(ctx);
save_to_submit_buf(&p.event->args_buf, &option, sizeof(option), 0);
save_to_submit_buf(&p.event->args_buf, &arg2, sizeof(arg2), 1);
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 2);
save_to_submit_buf(&p.event->args_buf, &arg4, sizeof(arg4), 3);
save_to_submit_buf(&p.event->args_buf, &arg5, sizeof(arg5), 4);

// Save PR_SET_VMA arg
if (option == PR_SET_VMA && arg2 == PR_SET_VMA_ANON_NAME && arg5 != 0)
save_str_to_buf(&p.event->args_buf, (char *) arg5, 5);

// Save PR_SET_MM args
if (option == PR_SET_MM) {
// Save all old mm info regardless of operation
struct mm_struct *mm = get_mm_from_task(p.event->task);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->start_code),
sizeof(mm->start_code),
6);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->end_code),
sizeof(mm->end_code),
7);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->start_data),
sizeof(mm->start_data),
8);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->end_data),
sizeof(mm->end_data),
9);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->start_brk),
sizeof(mm->start_brk),
10);
save_to_submit_buf(
&p.event->args_buf, __builtin_preserve_access_index(&mm->brk), sizeof(mm->brk), 11);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->start_stack),
sizeof(mm->start_stack),
12);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->arg_start),
sizeof(mm->arg_start),
13);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->arg_end),
sizeof(mm->arg_end),
14);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->env_start),
sizeof(mm->env_start),
15);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm->env_end),
sizeof(mm->env_end),
16);
void *saved_auxv;
u32 size;
struct mm_struct___redhat *mm_redhat = (struct mm_struct___redhat *) mm;
// Upstream kernel
if (bpf_core_field_exists(mm->saved_auxv)) {
saved_auxv = __builtin_preserve_access_index(&mm->saved_auxv);
size = bpf_core_field_size(mm->saved_auxv);
}
// Red Hat kernel
else if (bpf_core_field_exists(mm_redhat->mm_rh)) {
struct mm_struct_rh *mm_rh = BPF_CORE_READ(mm_redhat, mm_rh);
saved_auxv = __builtin_preserve_access_index(&mm_rh->saved_auxv);
size = bpf_core_field_size(mm_rh->saved_auxv);
}
// Unknown variation of mm_struct
else
return 0;

save_bytes_to_buf(&p.event->args_buf, saved_auxv, size, 17);

struct file *exe = BPF_CORE_READ(mm, exe_file);
void *exe_path = get_path_str(__builtin_preserve_access_index(&exe->f_path));
dev_t exe_dev = get_dev_from_file(exe);
unsigned long exe_inode = get_inode_nr_from_file(exe);
u64 exe_ctime = get_ctime_nanosec_from_file(exe);
umode_t exe_inode_mode = get_inode_mode_from_file(exe);

save_str_to_buf(&p.event->args_buf, exe_path, 18);
save_to_submit_buf(&p.event->args_buf, &exe_dev, sizeof(exe_dev), 19);
save_to_submit_buf(&p.event->args_buf, &exe_inode, sizeof(exe_inode), 20);
save_to_submit_buf(&p.event->args_buf, &exe_ctime, sizeof(exe_ctime), 21);
save_to_submit_buf(&p.event->args_buf, &exe_inode_mode, sizeof(exe_inode_mode), 22);

struct prctl_mm_map *mm_map;

// Save new mm info according to operation
switch (arg2) {
case PR_SET_MM_START_CODE:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 23);
break;
case PR_SET_MM_END_CODE:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 24);
break;
case PR_SET_MM_START_DATA:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 25);
break;
case PR_SET_MM_END_DATA:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 26);
break;
case PR_SET_MM_START_BRK:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 27);
break;
case PR_SET_MM_BRK:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 28);
break;
case PR_SET_MM_START_STACK:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 29);
break;
case PR_SET_MM_ARG_START:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 30);
break;
case PR_SET_MM_ARG_END:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 31);
break;
case PR_SET_MM_ENV_START:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 32);
break;
case PR_SET_MM_ENV_END:
save_to_submit_buf(&p.event->args_buf, &arg3, sizeof(arg3), 33);
break;
case PR_SET_MM_AUXV:
size = AT_VECTOR_SIZE * sizeof(unsigned long);
if (arg4 < size)
size = arg4;
save_bytes_to_buf(&p.event->args_buf, (void *) arg3, size, 34);
break;
case PR_SET_MM_EXE_FILE:
exe = get_struct_file_from_fd(arg3);
exe_path = get_path_str(__builtin_preserve_access_index(&exe->f_path));
exe_dev = get_dev_from_file(exe);
exe_inode = get_inode_nr_from_file(exe);
exe_ctime = get_ctime_nanosec_from_file(exe);
exe_inode_mode = get_inode_mode_from_file(exe);

save_str_to_buf(&p.event->args_buf, exe_path, 35);
save_to_submit_buf(&p.event->args_buf, &exe_dev, sizeof(exe_dev), 36);
save_to_submit_buf(&p.event->args_buf, &exe_inode, sizeof(exe_inode), 37);
save_to_submit_buf(&p.event->args_buf, &exe_ctime, sizeof(exe_ctime), 38);
save_to_submit_buf(&p.event->args_buf, &exe_inode_mode, sizeof(exe_inode_mode), 39);

break;
case PR_SET_MM_MAP:
mm_map = (struct prctl_mm_map *) arg3;
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->start_code),
sizeof(mm_map->start_code),
23);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->end_code),
sizeof(mm_map->end_code),
24);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->start_data),
sizeof(mm_map->start_data),
25);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->end_data),
sizeof(mm_map->end_data),
26);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->start_brk),
sizeof(mm_map->start_brk),
27);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->brk),
sizeof(mm_map->brk),
28);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->start_stack),
sizeof(mm_map->start_stack),
29);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->arg_start),
sizeof(mm_map->arg_start),
30);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->arg_end),
sizeof(mm_map->arg_end),
31);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->env_start),
sizeof(mm_map->env_start),
32);
save_to_submit_buf(&p.event->args_buf,
__builtin_preserve_access_index(&mm_map->env_end),
sizeof(mm_map->env_end),
33);
save_bytes_to_buf(&p.event->args_buf,
BPF_CORE_READ_USER(mm_map, auxv),
BPF_CORE_READ_USER(mm_map, auxv_size),
34);

exe = get_struct_file_from_fd(BPF_CORE_READ_USER(mm_map, exe_fd));
exe_path = get_path_str(__builtin_preserve_access_index(&exe->f_path));
exe_dev = get_dev_from_file(exe);
exe_inode = get_inode_nr_from_file(exe);
exe_ctime = get_ctime_nanosec_from_file(exe);
exe_inode_mode = get_inode_mode_from_file(exe);

save_str_to_buf(&p.event->args_buf, exe_path, 35);
save_to_submit_buf(&p.event->args_buf, &exe_dev, sizeof(exe_dev), 36);
save_to_submit_buf(&p.event->args_buf, &exe_inode, sizeof(exe_inode), 37);
save_to_submit_buf(&p.event->args_buf, &exe_ctime, sizeof(exe_ctime), 38);
save_to_submit_buf(&p.event->args_buf, &exe_inode_mode, sizeof(exe_inode_mode), 39);

break;
default:
// unknown/invalid operation
return 0;
}
}

// Save old securebits for PR_SET_SECUREBITS
if (option == PR_SET_SECUREBITS) {
struct task_struct *task = p.event->task;
unsigned int old_securebits = BPF_CORE_READ(task, cred, securebits);
save_to_submit_buf(&p.event->args_buf, &old_securebits, sizeof(old_securebits), 40);
}

return events_perf_submit(&p, 0);
}

//
// Syscall checkers
//
Expand Down
1 change: 1 addition & 0 deletions pkg/ebpf/c/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ typedef struct event_context {
X(OPEN_FILE_NS, ) \
X(OPEN_FILE_MOUNT, ) \
X(SECURITY_SB_UMOUNT, ) \
X(SECURITY_TASK_PRCTL, ) \
// ...

#define EVENT_ID_LIST_LAST \
Expand Down
51 changes: 43 additions & 8 deletions pkg/ebpf/c/vmlinux.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ struct task_struct {
u64 start_boottime;
u64 real_start_time;
const struct cred *real_cred;
const struct cred *cred;
char comm[16];
struct files_struct *files;
struct fs_struct *fs;
Expand Down Expand Up @@ -743,20 +744,54 @@ struct rb_root {
struct rb_node *rb_node;
};

#if defined(__TARGET_ARCH_x86)
#define AT_VECTOR_SIZE_ARCH 3
#elif defined(__TARGET_ARCH_arm64)
#define AT_VECTOR_SIZE_ARCH 2
#else
#define AT_VECTOR_SIZE_ARCH 0
#endif

#define AT_VECTOR_SIZE_BASE 22
#define AT_VECTOR_SIZE (2 * (AT_VECTOR_SIZE_ARCH + AT_VECTOR_SIZE_BASE + 1))

struct mm_struct {
struct {
struct rb_root mm_rb;
long unsigned int stack_vm;
long unsigned int start_brk;
long unsigned int brk;
long unsigned int start_stack;
long unsigned int arg_start;
long unsigned int arg_end;
long unsigned int env_start;
long unsigned int env_end;
unsigned long stack_vm;
unsigned long start_code;
unsigned long end_code;
unsigned long start_data;
unsigned long end_data;
unsigned long start_brk;
unsigned long brk;
unsigned long start_stack;
unsigned long arg_start;
unsigned long arg_end;
unsigned long env_start;
unsigned long env_end;
unsigned long saved_auxv[AT_VECTOR_SIZE];
struct file *exe_file;
};
};

struct prctl_mm_map {
__u64 start_code;
__u64 end_code;
__u64 start_data;
__u64 end_data;
__u64 start_brk;
__u64 brk;
__u64 start_stack;
__u64 arg_start;
__u64 arg_end;
__u64 env_start;
__u64 env_end;
__u64 *auxv;
__u32 auxv_size;
__u32 exe_fd;
};

struct vfsmount {
struct dentry *mnt_root;
struct super_block *mnt_sb;
Expand Down
25 changes: 25 additions & 0 deletions pkg/ebpf/c/vmlinux_flavors.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,31 @@ struct inode___older_v611 {
struct timespec64 __i_ctime;
};

// Red Hat mm_struct variation
struct mm_struct_rh {
unsigned long saved_auxv[AT_VECTOR_SIZE];
};

struct mm_struct___redhat {
struct {
unsigned long start_code;
unsigned long end_code;
unsigned long start_data;
unsigned long end_data;
unsigned long start_brk;
unsigned long brk;
unsigned long start_stack;
unsigned long arg_start;
unsigned long arg_end;
unsigned long env_start;
unsigned long env_end;
struct file *exe_file;
};
union {
struct mm_struct_rh *mm_rh;
};
};

///////////////////

#pragma clang attribute pop
Expand Down
20 changes: 20 additions & 0 deletions pkg/ebpf/c/vmlinux_missing.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,4 +287,24 @@ static inline struct inet_sock *inet_sk(const struct sock *sk)
/* File supports atomic writes */
#define FMODE_CAN_ATOMIC_WRITE ((fmode_t) (1 << 7))

#define PR_SET_SECUREBITS 28
#define PR_SET_MM 35
#define PR_SET_MM_START_CODE 1
#define PR_SET_MM_END_CODE 2
#define PR_SET_MM_START_DATA 3
#define PR_SET_MM_END_DATA 4
#define PR_SET_MM_START_STACK 5
#define PR_SET_MM_START_BRK 6
#define PR_SET_MM_BRK 7
#define PR_SET_MM_ARG_START 8
#define PR_SET_MM_ARG_END 9
#define PR_SET_MM_ENV_START 10
#define PR_SET_MM_ENV_END 11
#define PR_SET_MM_AUXV 12
#define PR_SET_MM_EXE_FILE 13
#define PR_SET_MM_MAP 14
#define PR_SET_MM_MAP_SIZE 15
#define PR_SET_VMA 0x53564d41
#define PR_SET_VMA_ANON_NAME 0

#endif
1 change: 1 addition & 0 deletions pkg/ebpf/probes/probe_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ func NewDefaultProbeGroup(module *bpf.Module, netEnabled bool, defaultAutoload b
Dup3Ret: NewTraceProbe(SyscallExit, "dup3", "trace_ret_dup3"),
ChmodCommon: NewTraceProbe(KProbe, "chmod_common", "trace_chmod_common"),
SecuritySbUmount: NewTraceProbe(KProbe, "security_sb_umount", "trace_security_sb_umount"),
SecurityTaskPrctl: NewTraceProbe(KProbe, "security_task_prctl", "trace_security_task_prctl"),

TestUnavailableHook: NewTraceProbe(KProbe, "non_existing_func", "empty_kprobe"),
ExecTest: NewTraceProbe(RawTracepoint, "raw_syscalls:sched_process_exec", "tracepoint__exec_test"),
Expand Down
Loading