15e6da6beSIan Rogers // SPDX-License-Identifier: GPL-2.0
25e6da6beSIan Rogers /*
35e6da6beSIan Rogers * Augment the raw_syscalls tracepoints with the contents of the pointer arguments.
45e6da6beSIan Rogers *
55e6da6beSIan Rogers * This exactly matches what is marshalled into the raw_syscall:sys_enter
65e6da6beSIan Rogers * payload expected by the 'perf trace' beautifiers.
75e6da6beSIan Rogers */
85e6da6beSIan Rogers
95e6da6beSIan Rogers #include <linux/bpf.h>
105e6da6beSIan Rogers #include <bpf/bpf_helpers.h>
115e6da6beSIan Rogers #include <linux/limits.h>
125e6da6beSIan Rogers
13262b54b6SArnaldo Carvalho de Melo /**
14262b54b6SArnaldo Carvalho de Melo * is_power_of_2() - check if a value is a power of two
15262b54b6SArnaldo Carvalho de Melo * @n: the value to check
16262b54b6SArnaldo Carvalho de Melo *
17262b54b6SArnaldo Carvalho de Melo * Determine whether some value is a power of two, where zero is *not*
18262b54b6SArnaldo Carvalho de Melo * considered a power of two. Return: true if @n is a power of 2, otherwise
19262b54b6SArnaldo Carvalho de Melo * false.
20262b54b6SArnaldo Carvalho de Melo */
21262b54b6SArnaldo Carvalho de Melo #define is_power_of_2(n) (n != 0 && ((n & (n - 1)) == 0))
22262b54b6SArnaldo Carvalho de Melo
235e6da6beSIan Rogers #define MAX_CPUS 4096
245e6da6beSIan Rogers
255e6da6beSIan Rogers // FIXME: These should come from system headers
2633b725ceSIan Rogers #ifndef bool
275e6da6beSIan Rogers typedef char bool;
2833b725ceSIan Rogers #endif
295e6da6beSIan Rogers typedef int pid_t;
305e6da6beSIan Rogers typedef long long int __s64;
315e6da6beSIan Rogers typedef __s64 time64_t;
325e6da6beSIan Rogers
335e6da6beSIan Rogers struct timespec64 {
345e6da6beSIan Rogers time64_t tv_sec;
355e6da6beSIan Rogers long int tv_nsec;
365e6da6beSIan Rogers };
375e6da6beSIan Rogers
385e6da6beSIan Rogers /* bpf-output associated map */
395e6da6beSIan Rogers struct __augmented_syscalls__ {
405e6da6beSIan Rogers __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
415e6da6beSIan Rogers __type(key, int);
425e6da6beSIan Rogers __type(value, __u32);
435e6da6beSIan Rogers __uint(max_entries, MAX_CPUS);
445e6da6beSIan Rogers } __augmented_syscalls__ SEC(".maps");
455e6da6beSIan Rogers
465e6da6beSIan Rogers /*
475e6da6beSIan Rogers * What to augment at entry?
485e6da6beSIan Rogers *
495e6da6beSIan Rogers * Pointer arg payloads (filenames, etc) passed from userspace to the kernel
505e6da6beSIan Rogers */
515e6da6beSIan Rogers struct syscalls_sys_enter {
525e6da6beSIan Rogers __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
535e6da6beSIan Rogers __type(key, __u32);
545e6da6beSIan Rogers __type(value, __u32);
555e6da6beSIan Rogers __uint(max_entries, 512);
565e6da6beSIan Rogers } syscalls_sys_enter SEC(".maps");
575e6da6beSIan Rogers
585e6da6beSIan Rogers /*
595e6da6beSIan Rogers * What to augment at exit?
605e6da6beSIan Rogers *
615e6da6beSIan Rogers * Pointer arg payloads returned from the kernel (struct stat, etc) to userspace.
625e6da6beSIan Rogers */
635e6da6beSIan Rogers struct syscalls_sys_exit {
645e6da6beSIan Rogers __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
655e6da6beSIan Rogers __type(key, __u32);
665e6da6beSIan Rogers __type(value, __u32);
675e6da6beSIan Rogers __uint(max_entries, 512);
685e6da6beSIan Rogers } syscalls_sys_exit SEC(".maps");
695e6da6beSIan Rogers
705e6da6beSIan Rogers struct syscall_enter_args {
715e6da6beSIan Rogers unsigned long long common_tp_fields;
725e6da6beSIan Rogers long syscall_nr;
735e6da6beSIan Rogers unsigned long args[6];
745e6da6beSIan Rogers };
755e6da6beSIan Rogers
765e6da6beSIan Rogers struct syscall_exit_args {
775e6da6beSIan Rogers unsigned long long common_tp_fields;
785e6da6beSIan Rogers long syscall_nr;
795e6da6beSIan Rogers long ret;
805e6da6beSIan Rogers };
815e6da6beSIan Rogers
825e6da6beSIan Rogers struct augmented_arg {
835e6da6beSIan Rogers unsigned int size;
845e6da6beSIan Rogers int err;
855e6da6beSIan Rogers char value[PATH_MAX];
865e6da6beSIan Rogers };
875e6da6beSIan Rogers
885e6da6beSIan Rogers struct pids_filtered {
895e6da6beSIan Rogers __uint(type, BPF_MAP_TYPE_HASH);
905e6da6beSIan Rogers __type(key, pid_t);
915e6da6beSIan Rogers __type(value, bool);
925e6da6beSIan Rogers __uint(max_entries, 64);
935e6da6beSIan Rogers } pids_filtered SEC(".maps");
945e6da6beSIan Rogers
955e6da6beSIan Rogers /*
965e6da6beSIan Rogers * Desired design of maximum size and alignment (see RFC2553)
975e6da6beSIan Rogers */
985e6da6beSIan Rogers #define SS_MAXSIZE 128 /* Implementation specific max size */
995e6da6beSIan Rogers
1005e6da6beSIan Rogers typedef unsigned short sa_family_t;
1015e6da6beSIan Rogers
1025e6da6beSIan Rogers /*
1035e6da6beSIan Rogers * FIXME: Should come from system headers
1045e6da6beSIan Rogers *
1055e6da6beSIan Rogers * The definition uses anonymous union and struct in order to control the
1065e6da6beSIan Rogers * default alignment.
1075e6da6beSIan Rogers */
1085e6da6beSIan Rogers struct sockaddr_storage {
1095e6da6beSIan Rogers union {
1105e6da6beSIan Rogers struct {
1115e6da6beSIan Rogers sa_family_t ss_family; /* address family */
1125e6da6beSIan Rogers /* Following field(s) are implementation specific */
1135e6da6beSIan Rogers char __data[SS_MAXSIZE - sizeof(unsigned short)];
1145e6da6beSIan Rogers /* space to achieve desired size, */
1155e6da6beSIan Rogers /* _SS_MAXSIZE value minus size of ss_family */
1165e6da6beSIan Rogers };
1175e6da6beSIan Rogers void *__align; /* implementation specific desired alignment */
1185e6da6beSIan Rogers };
1195e6da6beSIan Rogers };
1205e6da6beSIan Rogers
1215e6da6beSIan Rogers struct augmented_args_payload {
1225e6da6beSIan Rogers struct syscall_enter_args args;
1235e6da6beSIan Rogers union {
1245e6da6beSIan Rogers struct {
1255e6da6beSIan Rogers struct augmented_arg arg, arg2;
1265e6da6beSIan Rogers };
1275e6da6beSIan Rogers struct sockaddr_storage saddr;
1285e6da6beSIan Rogers char __data[sizeof(struct augmented_arg)];
1295e6da6beSIan Rogers };
1305e6da6beSIan Rogers };
1315e6da6beSIan Rogers
1325e6da6beSIan Rogers // We need more tmp space than the BPF stack can give us
1335e6da6beSIan Rogers struct augmented_args_tmp {
1345e6da6beSIan Rogers __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
1355e6da6beSIan Rogers __type(key, int);
1365e6da6beSIan Rogers __type(value, struct augmented_args_payload);
1375e6da6beSIan Rogers __uint(max_entries, 1);
1385e6da6beSIan Rogers } augmented_args_tmp SEC(".maps");
1395e6da6beSIan Rogers
augmented_args_payload(void)1405e6da6beSIan Rogers static inline struct augmented_args_payload *augmented_args_payload(void)
1415e6da6beSIan Rogers {
1425e6da6beSIan Rogers int key = 0;
1435e6da6beSIan Rogers return bpf_map_lookup_elem(&augmented_args_tmp, &key);
1445e6da6beSIan Rogers }
1455e6da6beSIan Rogers
augmented__output(void * ctx,struct augmented_args_payload * args,int len)1465e6da6beSIan Rogers static inline int augmented__output(void *ctx, struct augmented_args_payload *args, int len)
1475e6da6beSIan Rogers {
1485e6da6beSIan Rogers /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */
1495e6da6beSIan Rogers return bpf_perf_event_output(ctx, &__augmented_syscalls__, BPF_F_CURRENT_CPU, args, len);
1505e6da6beSIan Rogers }
1515e6da6beSIan Rogers
1525e6da6beSIan Rogers static inline
augmented_arg__read_str(struct augmented_arg * augmented_arg,const void * arg,unsigned int arg_len)1535e6da6beSIan Rogers unsigned int augmented_arg__read_str(struct augmented_arg *augmented_arg, const void *arg, unsigned int arg_len)
1545e6da6beSIan Rogers {
1555e6da6beSIan Rogers unsigned int augmented_len = sizeof(*augmented_arg);
156*b18be5a5SThomas Richter int string_len = bpf_probe_read_user_str(&augmented_arg->value, arg_len, arg);
1575e6da6beSIan Rogers
1585e6da6beSIan Rogers augmented_arg->size = augmented_arg->err = 0;
1595e6da6beSIan Rogers /*
1605e6da6beSIan Rogers * probe_read_str may return < 0, e.g. -EFAULT
1615e6da6beSIan Rogers * So we leave that in the augmented_arg->size that userspace will
1625e6da6beSIan Rogers */
1635e6da6beSIan Rogers if (string_len > 0) {
1645e6da6beSIan Rogers augmented_len -= sizeof(augmented_arg->value) - string_len;
1657d964231SArnaldo Carvalho de Melo _Static_assert(is_power_of_2(sizeof(augmented_arg->value)), "sizeof(augmented_arg->value) needs to be a power of two");
1665e6da6beSIan Rogers augmented_len &= sizeof(augmented_arg->value) - 1;
1675e6da6beSIan Rogers augmented_arg->size = string_len;
1685e6da6beSIan Rogers } else {
1695e6da6beSIan Rogers /*
1705e6da6beSIan Rogers * So that username notice the error while still being able
1715e6da6beSIan Rogers * to skip this augmented arg record
1725e6da6beSIan Rogers */
1735e6da6beSIan Rogers augmented_arg->err = string_len;
1745e6da6beSIan Rogers augmented_len = offsetof(struct augmented_arg, value);
1755e6da6beSIan Rogers }
1765e6da6beSIan Rogers
1775e6da6beSIan Rogers return augmented_len;
1785e6da6beSIan Rogers }
1795e6da6beSIan Rogers
1805e6da6beSIan Rogers SEC("tp/raw_syscalls/sys_enter")
syscall_unaugmented(struct syscall_enter_args * args)1815e6da6beSIan Rogers int syscall_unaugmented(struct syscall_enter_args *args)
1825e6da6beSIan Rogers {
1835e6da6beSIan Rogers return 1;
1845e6da6beSIan Rogers }
1855e6da6beSIan Rogers
1865e6da6beSIan Rogers /*
1875e6da6beSIan Rogers * These will be tail_called from SEC("raw_syscalls:sys_enter"), so will find in
1885e6da6beSIan Rogers * augmented_args_tmp what was read by that raw_syscalls:sys_enter and go
1895e6da6beSIan Rogers * on from there, reading the first syscall arg as a string, i.e. open's
1905e6da6beSIan Rogers * filename.
1915e6da6beSIan Rogers */
1925e6da6beSIan Rogers SEC("tp/syscalls/sys_enter_connect")
sys_enter_connect(struct syscall_enter_args * args)1935e6da6beSIan Rogers int sys_enter_connect(struct syscall_enter_args *args)
1945e6da6beSIan Rogers {
1955e6da6beSIan Rogers struct augmented_args_payload *augmented_args = augmented_args_payload();
1965e6da6beSIan Rogers const void *sockaddr_arg = (const void *)args->args[1];
1975e6da6beSIan Rogers unsigned int socklen = args->args[2];
1985e6da6beSIan Rogers unsigned int len = sizeof(augmented_args->args);
1995e6da6beSIan Rogers
2005e6da6beSIan Rogers if (augmented_args == NULL)
2015e6da6beSIan Rogers return 1; /* Failure: don't filter */
2025e6da6beSIan Rogers
203262b54b6SArnaldo Carvalho de Melo _Static_assert(is_power_of_2(sizeof(augmented_args->saddr)), "sizeof(augmented_args->saddr) needs to be a power of two");
20418364804SArnaldo Carvalho de Melo socklen &= sizeof(augmented_args->saddr) - 1;
2055e6da6beSIan Rogers
206*b18be5a5SThomas Richter bpf_probe_read_user(&augmented_args->saddr, socklen, sockaddr_arg);
2075e6da6beSIan Rogers
2085e6da6beSIan Rogers return augmented__output(args, augmented_args, len + socklen);
2095e6da6beSIan Rogers }
2105e6da6beSIan Rogers
2115e6da6beSIan Rogers SEC("tp/syscalls/sys_enter_sendto")
sys_enter_sendto(struct syscall_enter_args * args)2125e6da6beSIan Rogers int sys_enter_sendto(struct syscall_enter_args *args)
2135e6da6beSIan Rogers {
2145e6da6beSIan Rogers struct augmented_args_payload *augmented_args = augmented_args_payload();
2155e6da6beSIan Rogers const void *sockaddr_arg = (const void *)args->args[4];
2165e6da6beSIan Rogers unsigned int socklen = args->args[5];
2175e6da6beSIan Rogers unsigned int len = sizeof(augmented_args->args);
2185e6da6beSIan Rogers
2195e6da6beSIan Rogers if (augmented_args == NULL)
2205e6da6beSIan Rogers return 1; /* Failure: don't filter */
2215e6da6beSIan Rogers
22218364804SArnaldo Carvalho de Melo socklen &= sizeof(augmented_args->saddr) - 1;
2235e6da6beSIan Rogers
224*b18be5a5SThomas Richter bpf_probe_read_user(&augmented_args->saddr, socklen, sockaddr_arg);
2255e6da6beSIan Rogers
2265e6da6beSIan Rogers return augmented__output(args, augmented_args, len + socklen);
2275e6da6beSIan Rogers }
2285e6da6beSIan Rogers
2295e6da6beSIan Rogers SEC("tp/syscalls/sys_enter_open")
sys_enter_open(struct syscall_enter_args * args)2305e6da6beSIan Rogers int sys_enter_open(struct syscall_enter_args *args)
2315e6da6beSIan Rogers {
2325e6da6beSIan Rogers struct augmented_args_payload *augmented_args = augmented_args_payload();
2335e6da6beSIan Rogers const void *filename_arg = (const void *)args->args[0];
2345e6da6beSIan Rogers unsigned int len = sizeof(augmented_args->args);
2355e6da6beSIan Rogers
2365e6da6beSIan Rogers if (augmented_args == NULL)
2375e6da6beSIan Rogers return 1; /* Failure: don't filter */
2385e6da6beSIan Rogers
2395e6da6beSIan Rogers len += augmented_arg__read_str(&augmented_args->arg, filename_arg, sizeof(augmented_args->arg.value));
2405e6da6beSIan Rogers
2415e6da6beSIan Rogers return augmented__output(args, augmented_args, len);
2425e6da6beSIan Rogers }
2435e6da6beSIan Rogers
2445e6da6beSIan Rogers SEC("tp/syscalls/sys_enter_openat")
sys_enter_openat(struct syscall_enter_args * args)2455e6da6beSIan Rogers int sys_enter_openat(struct syscall_enter_args *args)
2465e6da6beSIan Rogers {
2475e6da6beSIan Rogers struct augmented_args_payload *augmented_args = augmented_args_payload();
2485e6da6beSIan Rogers const void *filename_arg = (const void *)args->args[1];
2495e6da6beSIan Rogers unsigned int len = sizeof(augmented_args->args);
2505e6da6beSIan Rogers
2515e6da6beSIan Rogers if (augmented_args == NULL)
2525e6da6beSIan Rogers return 1; /* Failure: don't filter */
2535e6da6beSIan Rogers
2545e6da6beSIan Rogers len += augmented_arg__read_str(&augmented_args->arg, filename_arg, sizeof(augmented_args->arg.value));
2555e6da6beSIan Rogers
2565e6da6beSIan Rogers return augmented__output(args, augmented_args, len);
2575e6da6beSIan Rogers }
2585e6da6beSIan Rogers
2595e6da6beSIan Rogers SEC("tp/syscalls/sys_enter_rename")
sys_enter_rename(struct syscall_enter_args * args)2605e6da6beSIan Rogers int sys_enter_rename(struct syscall_enter_args *args)
2615e6da6beSIan Rogers {
2625e6da6beSIan Rogers struct augmented_args_payload *augmented_args = augmented_args_payload();
2635e6da6beSIan Rogers const void *oldpath_arg = (const void *)args->args[0],
2645e6da6beSIan Rogers *newpath_arg = (const void *)args->args[1];
2655e6da6beSIan Rogers unsigned int len = sizeof(augmented_args->args), oldpath_len;
2665e6da6beSIan Rogers
2675e6da6beSIan Rogers if (augmented_args == NULL)
2685e6da6beSIan Rogers return 1; /* Failure: don't filter */
2695e6da6beSIan Rogers
2705e6da6beSIan Rogers oldpath_len = augmented_arg__read_str(&augmented_args->arg, oldpath_arg, sizeof(augmented_args->arg.value));
2715e6da6beSIan Rogers len += oldpath_len + augmented_arg__read_str((void *)(&augmented_args->arg) + oldpath_len, newpath_arg, sizeof(augmented_args->arg.value));
2725e6da6beSIan Rogers
2735e6da6beSIan Rogers return augmented__output(args, augmented_args, len);
2745e6da6beSIan Rogers }
2755e6da6beSIan Rogers
2765e6da6beSIan Rogers SEC("tp/syscalls/sys_enter_renameat")
sys_enter_renameat(struct syscall_enter_args * args)2775e6da6beSIan Rogers int sys_enter_renameat(struct syscall_enter_args *args)
2785e6da6beSIan Rogers {
2795e6da6beSIan Rogers struct augmented_args_payload *augmented_args = augmented_args_payload();
2805e6da6beSIan Rogers const void *oldpath_arg = (const void *)args->args[1],
2815e6da6beSIan Rogers *newpath_arg = (const void *)args->args[3];
2825e6da6beSIan Rogers unsigned int len = sizeof(augmented_args->args), oldpath_len;
2835e6da6beSIan Rogers
2845e6da6beSIan Rogers if (augmented_args == NULL)
2855e6da6beSIan Rogers return 1; /* Failure: don't filter */
2865e6da6beSIan Rogers
2875e6da6beSIan Rogers oldpath_len = augmented_arg__read_str(&augmented_args->arg, oldpath_arg, sizeof(augmented_args->arg.value));
2885e6da6beSIan Rogers len += oldpath_len + augmented_arg__read_str((void *)(&augmented_args->arg) + oldpath_len, newpath_arg, sizeof(augmented_args->arg.value));
2895e6da6beSIan Rogers
2905e6da6beSIan Rogers return augmented__output(args, augmented_args, len);
2915e6da6beSIan Rogers }
2925e6da6beSIan Rogers
2935e6da6beSIan Rogers #define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */
2945e6da6beSIan Rogers
2955e6da6beSIan Rogers // we need just the start, get the size to then copy it
2965e6da6beSIan Rogers struct perf_event_attr_size {
2975e6da6beSIan Rogers __u32 type;
2985e6da6beSIan Rogers /*
2995e6da6beSIan Rogers * Size of the attr structure, for fwd/bwd compat.
3005e6da6beSIan Rogers */
3015e6da6beSIan Rogers __u32 size;
3025e6da6beSIan Rogers };
3035e6da6beSIan Rogers
3045e6da6beSIan Rogers SEC("tp/syscalls/sys_enter_perf_event_open")
sys_enter_perf_event_open(struct syscall_enter_args * args)3055e6da6beSIan Rogers int sys_enter_perf_event_open(struct syscall_enter_args *args)
3065e6da6beSIan Rogers {
3075e6da6beSIan Rogers struct augmented_args_payload *augmented_args = augmented_args_payload();
3085e6da6beSIan Rogers const struct perf_event_attr_size *attr = (const struct perf_event_attr_size *)args->args[0], *attr_read;
3095e6da6beSIan Rogers unsigned int len = sizeof(augmented_args->args);
3105e6da6beSIan Rogers
3115e6da6beSIan Rogers if (augmented_args == NULL)
3125e6da6beSIan Rogers goto failure;
3135e6da6beSIan Rogers
314*b18be5a5SThomas Richter if (bpf_probe_read_user(&augmented_args->__data, sizeof(*attr), attr) < 0)
3155e6da6beSIan Rogers goto failure;
3165e6da6beSIan Rogers
3175e6da6beSIan Rogers attr_read = (const struct perf_event_attr_size *)augmented_args->__data;
3185e6da6beSIan Rogers
3195e6da6beSIan Rogers __u32 size = attr_read->size;
3205e6da6beSIan Rogers
3215e6da6beSIan Rogers if (!size)
3225e6da6beSIan Rogers size = PERF_ATTR_SIZE_VER0;
3235e6da6beSIan Rogers
3245e6da6beSIan Rogers if (size > sizeof(augmented_args->__data))
3255e6da6beSIan Rogers goto failure;
3265e6da6beSIan Rogers
3275e6da6beSIan Rogers // Now that we read attr->size and tested it against the size limits, read it completely
328*b18be5a5SThomas Richter if (bpf_probe_read_user(&augmented_args->__data, size, attr) < 0)
3295e6da6beSIan Rogers goto failure;
3305e6da6beSIan Rogers
3315e6da6beSIan Rogers return augmented__output(args, augmented_args, len + size);
3325e6da6beSIan Rogers failure:
3335e6da6beSIan Rogers return 1; /* Failure: don't filter */
3345e6da6beSIan Rogers }
3355e6da6beSIan Rogers
3365e6da6beSIan Rogers SEC("tp/syscalls/sys_enter_clock_nanosleep")
sys_enter_clock_nanosleep(struct syscall_enter_args * args)3375e6da6beSIan Rogers int sys_enter_clock_nanosleep(struct syscall_enter_args *args)
3385e6da6beSIan Rogers {
3395e6da6beSIan Rogers struct augmented_args_payload *augmented_args = augmented_args_payload();
3405e6da6beSIan Rogers const void *rqtp_arg = (const void *)args->args[2];
3415e6da6beSIan Rogers unsigned int len = sizeof(augmented_args->args);
3425e6da6beSIan Rogers __u32 size = sizeof(struct timespec64);
3435e6da6beSIan Rogers
3445e6da6beSIan Rogers if (augmented_args == NULL)
3455e6da6beSIan Rogers goto failure;
3465e6da6beSIan Rogers
3475e6da6beSIan Rogers if (size > sizeof(augmented_args->__data))
3485e6da6beSIan Rogers goto failure;
3495e6da6beSIan Rogers
350*b18be5a5SThomas Richter bpf_probe_read_user(&augmented_args->__data, size, rqtp_arg);
3515e6da6beSIan Rogers
3525e6da6beSIan Rogers return augmented__output(args, augmented_args, len + size);
3535e6da6beSIan Rogers failure:
3545e6da6beSIan Rogers return 1; /* Failure: don't filter */
3555e6da6beSIan Rogers }
3565e6da6beSIan Rogers
getpid(void)3575e6da6beSIan Rogers static pid_t getpid(void)
3585e6da6beSIan Rogers {
3595e6da6beSIan Rogers return bpf_get_current_pid_tgid();
3605e6da6beSIan Rogers }
3615e6da6beSIan Rogers
pid_filter__has(struct pids_filtered * pids,pid_t pid)3625e6da6beSIan Rogers static bool pid_filter__has(struct pids_filtered *pids, pid_t pid)
3635e6da6beSIan Rogers {
3645e6da6beSIan Rogers return bpf_map_lookup_elem(pids, &pid) != NULL;
3655e6da6beSIan Rogers }
3665e6da6beSIan Rogers
3675e6da6beSIan Rogers SEC("tp/raw_syscalls/sys_enter")
sys_enter(struct syscall_enter_args * args)3685e6da6beSIan Rogers int sys_enter(struct syscall_enter_args *args)
3695e6da6beSIan Rogers {
3705e6da6beSIan Rogers struct augmented_args_payload *augmented_args;
3715e6da6beSIan Rogers /*
3725e6da6beSIan Rogers * We start len, the amount of data that will be in the perf ring
3735e6da6beSIan Rogers * buffer, if this is not filtered out by one of pid_filter__has(),
3745e6da6beSIan Rogers * syscall->enabled, etc, with the non-augmented raw syscall payload,
3755e6da6beSIan Rogers * i.e. sizeof(augmented_args->args).
3765e6da6beSIan Rogers *
3775e6da6beSIan Rogers * We'll add to this as we add augmented syscalls right after that
3785e6da6beSIan Rogers * initial, non-augmented raw_syscalls:sys_enter payload.
3795e6da6beSIan Rogers */
3805e6da6beSIan Rogers
3815e6da6beSIan Rogers if (pid_filter__has(&pids_filtered, getpid()))
3825e6da6beSIan Rogers return 0;
3835e6da6beSIan Rogers
3845e6da6beSIan Rogers augmented_args = augmented_args_payload();
3855e6da6beSIan Rogers if (augmented_args == NULL)
3865e6da6beSIan Rogers return 1;
3875e6da6beSIan Rogers
388*b18be5a5SThomas Richter bpf_probe_read_kernel(&augmented_args->args, sizeof(augmented_args->args), args);
3895e6da6beSIan Rogers
3905e6da6beSIan Rogers /*
3915e6da6beSIan Rogers * Jump to syscall specific augmenter, even if the default one,
3925e6da6beSIan Rogers * "!raw_syscalls:unaugmented" that will just return 1 to return the
3935e6da6beSIan Rogers * unaugmented tracepoint payload.
3945e6da6beSIan Rogers */
3955e6da6beSIan Rogers bpf_tail_call(args, &syscalls_sys_enter, augmented_args->args.syscall_nr);
3965e6da6beSIan Rogers
3975e6da6beSIan Rogers // If not found on the PROG_ARRAY syscalls map, then we're filtering it:
3985e6da6beSIan Rogers return 0;
3995e6da6beSIan Rogers }
4005e6da6beSIan Rogers
4015e6da6beSIan Rogers SEC("tp/raw_syscalls/sys_exit")
sys_exit(struct syscall_exit_args * args)4025e6da6beSIan Rogers int sys_exit(struct syscall_exit_args *args)
4035e6da6beSIan Rogers {
4045e6da6beSIan Rogers struct syscall_exit_args exit_args;
4055e6da6beSIan Rogers
4065e6da6beSIan Rogers if (pid_filter__has(&pids_filtered, getpid()))
4075e6da6beSIan Rogers return 0;
4085e6da6beSIan Rogers
409*b18be5a5SThomas Richter bpf_probe_read_kernel(&exit_args, sizeof(exit_args), args);
4105e6da6beSIan Rogers /*
4115e6da6beSIan Rogers * Jump to syscall specific return augmenter, even if the default one,
4125e6da6beSIan Rogers * "!raw_syscalls:unaugmented" that will just return 1 to return the
4135e6da6beSIan Rogers * unaugmented tracepoint payload.
4145e6da6beSIan Rogers */
4155e6da6beSIan Rogers bpf_tail_call(args, &syscalls_sys_exit, exit_args.syscall_nr);
4165e6da6beSIan Rogers /*
4175e6da6beSIan Rogers * If not found on the PROG_ARRAY syscalls map, then we're filtering it:
4185e6da6beSIan Rogers */
4195e6da6beSIan Rogers return 0;
4205e6da6beSIan Rogers }
4215e6da6beSIan Rogers
4225e6da6beSIan Rogers char _license[] SEC("license") = "GPL";
423