hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/tools/perf/examples/bpf/augmented_syscalls.c
....@@ -1,6 +1,6 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
3
- * Augment the openat syscall with the contents of the filename pointer argument.
3
+ * Augment syscalls with the contents of the pointer arguments.
44 *
55 * Test it with:
66 *
....@@ -10,22 +10,55 @@
1010 * the last one should be the one for '/etc/passwd'.
1111 *
1212 * This matches what is marshalled into the raw_syscall:sys_enter payload
13
- * expected by the 'perf trace' beautifiers, and can be used by them unmodified,
14
- * which will be done as that feature is implemented in the next csets, for now
15
- * it will appear in a dump done by the default tracepoint handler in 'perf trace',
16
- * that uses bpf_output__fprintf() to just dump those contents, as done with
17
- * the bpf-output event associated with the __bpf_output__ map declared in
18
- * tools/perf/include/bpf/stdio.h.
13
+ * expected by the 'perf trace' beautifiers, and can be used by them, that will
14
+ * check if perf_sample->raw_data is more than what is expected for each
15
+ * syscalls:sys_{enter,exit}_SYSCALL tracepoint, uing the extra data as the
16
+ * contents of pointer arguments.
1917 */
2018
2119 #include <stdio.h>
20
+#include <linux/socket.h>
2221
23
-struct bpf_map SEC("maps") __augmented_syscalls__ = {
24
- .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
25
- .key_size = sizeof(int),
26
- .value_size = sizeof(u32),
27
- .max_entries = __NR_CPUS__,
22
+/* bpf-output associated map */
23
+bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__);
24
+
25
+struct syscall_exit_args {
26
+ unsigned long long common_tp_fields;
27
+ long syscall_nr;
28
+ long ret;
2829 };
30
+
31
+struct augmented_filename {
32
+ unsigned int size;
33
+ int reserved;
34
+ char value[256];
35
+};
36
+
37
+#define augmented_filename_syscall(syscall) \
38
+struct augmented_enter_##syscall##_args { \
39
+ struct syscall_enter_##syscall##_args args; \
40
+ struct augmented_filename filename; \
41
+}; \
42
+int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args) \
43
+{ \
44
+ struct augmented_enter_##syscall##_args augmented_args = { .filename.reserved = 0, }; \
45
+ unsigned int len = sizeof(augmented_args); \
46
+ probe_read(&augmented_args.args, sizeof(augmented_args.args), args); \
47
+ augmented_args.filename.size = probe_read_str(&augmented_args.filename.value, \
48
+ sizeof(augmented_args.filename.value), \
49
+ args->filename_ptr); \
50
+ if (augmented_args.filename.size < sizeof(augmented_args.filename.value)) { \
51
+ len -= sizeof(augmented_args.filename.value) - augmented_args.filename.size; \
52
+ len &= sizeof(augmented_args.filename.value) - 1; \
53
+ } \
54
+ /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ \
55
+ return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, \
56
+ &augmented_args, len); \
57
+} \
58
+int syscall_exit(syscall)(struct syscall_exit_args *args) \
59
+{ \
60
+ return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */ \
61
+}
2962
3063 struct syscall_enter_openat_args {
3164 unsigned long long common_tp_fields;
....@@ -36,20 +69,101 @@
3669 long mode;
3770 };
3871
39
-struct augmented_enter_openat_args {
40
- struct syscall_enter_openat_args args;
41
- char filename[64];
72
+augmented_filename_syscall(openat);
73
+
74
+struct syscall_enter_open_args {
75
+ unsigned long long common_tp_fields;
76
+ long syscall_nr;
77
+ char *filename_ptr;
78
+ long flags;
79
+ long mode;
4280 };
4381
44
-int syscall_enter(openat)(struct syscall_enter_openat_args *args)
45
-{
46
- struct augmented_enter_openat_args augmented_args;
82
+augmented_filename_syscall(open);
4783
48
- probe_read(&augmented_args.args, sizeof(augmented_args.args), args);
49
- probe_read_str(&augmented_args.filename, sizeof(augmented_args.filename), args->filename_ptr);
50
- perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU,
51
- &augmented_args, sizeof(augmented_args));
52
- return 1;
84
+struct syscall_enter_inotify_add_watch_args {
85
+ unsigned long long common_tp_fields;
86
+ long syscall_nr;
87
+ long fd;
88
+ char *filename_ptr;
89
+ long mask;
90
+};
91
+
92
+augmented_filename_syscall(inotify_add_watch);
93
+
94
+struct statbuf;
95
+
96
+struct syscall_enter_newstat_args {
97
+ unsigned long long common_tp_fields;
98
+ long syscall_nr;
99
+ char *filename_ptr;
100
+ struct stat *statbuf;
101
+};
102
+
103
+augmented_filename_syscall(newstat);
104
+
105
+#ifndef _K_SS_MAXSIZE
106
+#define _K_SS_MAXSIZE 128
107
+#endif
108
+
109
+#define augmented_sockaddr_syscall(syscall) \
110
+struct augmented_enter_##syscall##_args { \
111
+ struct syscall_enter_##syscall##_args args; \
112
+ struct sockaddr_storage addr; \
113
+}; \
114
+int syscall_enter(syscall)(struct syscall_enter_##syscall##_args *args) \
115
+{ \
116
+ struct augmented_enter_##syscall##_args augmented_args; \
117
+ unsigned long addrlen = sizeof(augmented_args.addr); \
118
+ probe_read(&augmented_args.args, sizeof(augmented_args.args), args); \
119
+/* FIXME_CLANG_OPTIMIZATION_THAT_ACCESSES_USER_CONTROLLED_ADDRLEN_DESPITE_THIS_CHECK */ \
120
+/* if (addrlen > augmented_args.args.addrlen) */ \
121
+/* addrlen = augmented_args.args.addrlen; */ \
122
+/* */ \
123
+ probe_read(&augmented_args.addr, addrlen, args->addr_ptr); \
124
+ /* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */ \
125
+ return perf_event_output(args, &__augmented_syscalls__, BPF_F_CURRENT_CPU, \
126
+ &augmented_args, \
127
+ sizeof(augmented_args) - sizeof(augmented_args.addr) + addrlen);\
128
+} \
129
+int syscall_exit(syscall)(struct syscall_exit_args *args) \
130
+{ \
131
+ return 1; /* 0 as soon as we start copying data returned by the kernel, e.g. 'read' */ \
53132 }
54133
134
+struct sockaddr;
135
+
136
+struct syscall_enter_bind_args {
137
+ unsigned long long common_tp_fields;
138
+ long syscall_nr;
139
+ long fd;
140
+ struct sockaddr *addr_ptr;
141
+ unsigned long addrlen;
142
+};
143
+
144
+augmented_sockaddr_syscall(bind);
145
+
146
+struct syscall_enter_connect_args {
147
+ unsigned long long common_tp_fields;
148
+ long syscall_nr;
149
+ long fd;
150
+ struct sockaddr *addr_ptr;
151
+ unsigned long addrlen;
152
+};
153
+
154
+augmented_sockaddr_syscall(connect);
155
+
156
+struct syscall_enter_sendto_args {
157
+ unsigned long long common_tp_fields;
158
+ long syscall_nr;
159
+ long fd;
160
+ void *buff;
161
+ long len;
162
+ unsigned long flags;
163
+ struct sockaddr *addr_ptr;
164
+ long addr_len;
165
+};
166
+
167
+augmented_sockaddr_syscall(sendto);
168
+
55169 license(GPL);