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