1 /*
2 * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@strace.io>
3 * Copyright (c) 2017 Quentin Monnet <quentin.monnet@6wind.com>
4 * Copyright (c) 2015-2023 The strace developers.
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: LGPL-2.1-or-later
8 */
9
10 #include "defs.h"
11
12 #ifdef HAVE_LINUX_BPF_H
13 # include <linux/bpf.h>
14 #endif
15 #include <linux/filter.h>
16
17 #include "bpf_attr.h"
18
19 #include "xlat/bpf_commands.h"
20 #include "xlat/bpf_file_flags.h"
21 #include "xlat/bpf_file_mode_flags.h"
22 #include "xlat/bpf_map_types.h"
23 #include "xlat/bpf_map_flags.h"
24 #include "xlat/bpf_prog_types.h"
25 #include "xlat/bpf_prog_flags.h"
26 #include "xlat/bpf_map_lookup_elem_flags.h"
27 #include "xlat/bpf_map_update_elem_flags.h"
28 #include "xlat/bpf_attach_type.h"
29 #include "xlat/bpf_attach_flags.h"
30 #include "xlat/bpf_query_flags.h"
31 #include "xlat/bpf_stats_type.h"
32 #include "xlat/bpf_task_fd_type.h"
33 #include "xlat/bpf_test_run_flags.h"
34 #include "xlat/bpf_link_create_kprobe_multi_flags.h"
35 #include "xlat/ebpf_regs.h"
36 #include "xlat/numa_node.h"
37
38 #define XLAT_MACROS_ONLY
39 # include "xlat/clocknames.h" /* For CLOCK_BOOTTIME */
40 #undef XLAT_MACROS_ONLY
41
42 #define DECL_BPF_CMD_DECODER(bpf_cmd_decoder) \
43 int \
44 bpf_cmd_decoder(struct tcb *const tcp, \
45 const kernel_ulong_t addr, \
46 const unsigned int size, \
47 void *const data) \
48 /* End of DECL_BPF_CMD_DECODER definition. */
49
50 #define BEGIN_BPF_CMD_DECODER(bpf_cmd) \
51 static DECL_BPF_CMD_DECODER(decode_ ## bpf_cmd) \
52 { \
53 struct bpf_cmd ## _struct attr = {}; \
54 size_t attr_size = bpf_cmd ## _struct_size; \
55 const unsigned int len = MIN(size, attr_size); \
56 memcpy(&attr, data, len); \
57 do { \
58 /* End of BEGIN_BPF_CMD_DECODER definition. */
59
60 #define END_BPF_CMD_DECODER(rval) \
61 decode_attr_extra_data(tcp, data, size, attr_size); \
62 } while (0); \
63 tprint_struct_end(); \
64 return (rval); \
65 } \
66 /* End of END_BPF_CMD_DECODER definition. */
67
68 #define BPF_CMD_ENTRY(bpf_cmd) \
69 [bpf_cmd] = decode_ ## bpf_cmd
70
71 typedef DECL_BPF_CMD_DECODER((*bpf_cmd_decoder_t));
72
73 /*
74 * A note about bpf syscall decoder: it doesn't perform any size sanity checks,
75 * so even if it leads to partial copying of one of the fields, the command
76 * handler will still use the (partially-copied-from-userspace, partially
77 * zeroed) field value. That's why we stop decoding and check for known sizes
78 * that correspond to released versions of the structure used by the specific
79 * command - it looks like the most sensible way to parse this insanity.
80 */
81
82 static int
83 decode_attr_extra_data(struct tcb *const tcp,
84 const char *data,
85 unsigned int size,
86 const size_t attr_size)
87 {
88 if (size <= attr_size)
89 return 0;
90
91 data += attr_size;
92 size -= attr_size;
93
94 for (unsigned int i = 0; i < size; ++i) {
95 if (data[i]) {
96 tprint_struct_next();
97 if (abbrev(tcp)) {
98 tprint_more_data_follows();
99 } else {
100 tprints_field_name("extra_data");
101 print_quoted_string(data, size,
102 QUOTE_FORCE_HEX);
103 tprintf_comment("bytes %zu..%zu",
104 attr_size, attr_size + size - 1);
105 }
106 return RVAL_DECODED;
107 }
108 }
109
110 return 0;
111 }
112
113 struct ebpf_insn {
114 uint8_t code;
115 uint8_t dst_reg:4;
116 uint8_t src_reg:4;
117 int16_t off;
118 int32_t imm;
119 };
120
121 struct ebpf_insns_data {
122 unsigned int count;
123 };
124
125 static bool
126 print_ebpf_insn(struct tcb * const tcp, void * const elem_buf,
127 const size_t elem_size, void * const data)
128 {
129 struct ebpf_insns_data *eid = data;
130 struct ebpf_insn *insn = elem_buf;
131
132 if (eid->count++ >= BPF_MAXINSNS) {
133 tprint_more_data_follows();
134 return false;
135 }
136
137 tprint_struct_begin();
138 PRINT_FIELD_OBJ_VAL(*insn, code, print_bpf_filter_code, true);
139
140 /* We can't use PRINT_FIELD_XVAL on bit fields */
141 tprint_struct_next();
142 tprints_field_name("dst_reg");
143 printxval(ebpf_regs, insn->dst_reg, "BPF_REG_???");
144 tprint_struct_next();
145 tprints_field_name("src_reg");
146 printxval(ebpf_regs, insn->src_reg, "BPF_REG_???");
147
148 tprint_struct_next();
149 PRINT_FIELD_D(*insn, off);
150 tprint_struct_next();
151 PRINT_FIELD_X(*insn, imm);
152 tprint_struct_end();
153
154 return true;
155 }
156
157 static void
158 print_ebpf_prog(struct tcb *const tcp, const uint64_t addr, const uint32_t len)
159 {
160 print_big_u64_addr(addr);
161 if (abbrev(tcp)) {
162 printaddr(addr);
163 } else {
164 struct ebpf_insns_data eid = {};
165 struct ebpf_insn insn;
166
167 print_array(tcp, addr, len, &insn, sizeof(insn),
168 tfetch_mem, print_ebpf_insn, &eid);
169 }
170 }
171
172 BEGIN_BPF_CMD_DECODER(BPF_MAP_CREATE)
173 {
174 tprint_struct_begin();
175 PRINT_FIELD_XVAL(attr, map_type, bpf_map_types, "BPF_MAP_TYPE_???");
176 tprint_struct_next();
177 PRINT_FIELD_U(attr, key_size);
178 tprint_struct_next();
179 PRINT_FIELD_U(attr, value_size);
180 tprint_struct_next();
181 PRINT_FIELD_U(attr, max_entries);
182
183 /* map_flags field was added in Linux commit v4.6-rc1~91^2~108^2~6. */
184 if (len <= offsetof(struct BPF_MAP_CREATE_struct, map_flags))
185 break;
186 tprint_struct_next();
187 PRINT_FIELD_FLAGS(attr, map_flags, bpf_map_flags, "BPF_F_???");
188
189 /*
190 * inner_map_fd field was added in Linux commit
191 * v4.12-rc1~64^3~373^2~2.
192 */
193 if (len <= offsetof(struct BPF_MAP_CREATE_struct, inner_map_fd))
194 break;
195 tprint_struct_next();
196 PRINT_FIELD_FD(attr, inner_map_fd, tcp);
197
198 /* numa_node field was added in Linux commit v4.14-rc1~130^2~196^2~1. */
199 if (len <= offsetof(struct BPF_MAP_CREATE_struct, numa_node))
200 break;
201 if (attr.map_flags & BPF_F_NUMA_NODE) {
202 /*
203 * Kernel uses the value of -1 as a designation for "no NUMA
204 * node specified", and even uses NUMA_NO_NODE constant;
205 * however, the constant definition is not a part of UAPI
206 * headers, thus we can't simply print this named constant
207 * instead of the value. Let's force verbose xlat style instead
208 * in order to provide the information for the user while
209 * not hampering the availability to derive the actual value
210 * without the access to the kernel headers.
211 */
212 tprint_struct_next();
213 PRINT_FIELD_XVAL_U_VERBOSE(attr, numa_node, numa_node, NULL);
214 }
215
216 /* map_name field was added in Linux commit v4.15-rc1~84^2~605^2~3. */
217 if (len <= offsetof(struct BPF_MAP_CREATE_struct, map_name))
218 break;
219 tprint_struct_next();
220 PRINT_FIELD_CSTRING_SZ(attr, map_name,
221 MIN(sizeof(attr.map_name),
222 len - offsetof(struct BPF_MAP_CREATE_struct,
223 map_name)));
224
225 /*
226 * map_ifindex field was added in Linux commit
227 * v4.16-rc1~123^2~145^2~5^2~8.
228 */
229 if (len <= offsetof(struct BPF_MAP_CREATE_struct, map_ifindex))
230 break;
231 tprint_struct_next();
232 PRINT_FIELD_IFINDEX(attr, map_ifindex);
233
234 /*
235 * The following three fields were introduced by Linux commits
236 * v4.18-rc1~114^2~417^2~1^2~3 and v4.18-rc1~114^2~148^2~7^2~2.
237 */
238 if (len <= offsetof(struct BPF_MAP_CREATE_struct, btf_fd))
239 break;
240 tprint_struct_next();
241 PRINT_FIELD_FD(attr, btf_fd, tcp);
242 tprint_struct_next();
243 PRINT_FIELD_U(attr, btf_key_type_id);
244 tprint_struct_next();
245 PRINT_FIELD_U(attr, btf_value_type_id);
246
247 /*
248 * The following field was introduced by Linux commit
249 * v5.6-rc1~151^2~46^2~37^2~5.
250 */
251 if (len <= offsetof(struct BPF_MAP_CREATE_struct, btf_vmlinux_value_type_id))
252 break;
253 tprint_struct_next();
254 PRINT_FIELD_U(attr, btf_vmlinux_value_type_id);
255
256 /*
257 * The following field was introduced by Linux commit
258 * v5.16-rc1~159^2~2^2~20^2~4.
259 */
260 if (len <= offsetof(struct BPF_MAP_CREATE_struct, map_extra))
261 break;
262 tprint_struct_next();
263 PRINT_FIELD_U64(attr, map_extra);
264 }
265 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
266
267 BEGIN_BPF_CMD_DECODER(BPF_MAP_LOOKUP_ELEM)
268 {
269 tprint_struct_begin();
270 PRINT_FIELD_FD(attr, map_fd, tcp);
271 tprint_struct_next();
272 PRINT_FIELD_ADDR64(attr, key);
273 tprint_struct_next();
274 PRINT_FIELD_ADDR64(attr, value);
275 /* flags field was added in Linux commit v5.1-rc1~178^2~375^2~4^2~3. */
276 if (len <= offsetof(struct BPF_MAP_LOOKUP_ELEM_struct, flags))
277 break;
278 tprint_struct_next();
279 PRINT_FIELD_FLAGS(attr, flags, bpf_map_lookup_elem_flags, "BPF_???");
280 }
281 END_BPF_CMD_DECODER(RVAL_DECODED)
282
283 #define decode_BPF_MAP_LOOKUP_AND_DELETE_ELEM decode_BPF_MAP_LOOKUP_ELEM
284
285 BEGIN_BPF_CMD_DECODER(BPF_MAP_UPDATE_ELEM)
286 {
287 tprint_struct_begin();
288 PRINT_FIELD_FD(attr, map_fd, tcp);
289 tprint_struct_next();
290 PRINT_FIELD_ADDR64(attr, key);
291 tprint_struct_next();
292 PRINT_FIELD_ADDR64(attr, value);
293 tprint_struct_next();
294 PRINT_FIELD_XVAL(attr, flags, bpf_map_update_elem_flags, "BPF_???");
295 }
296 END_BPF_CMD_DECODER(RVAL_DECODED)
297
298 BEGIN_BPF_CMD_DECODER(BPF_MAP_DELETE_ELEM)
299 {
300 tprint_struct_begin();
301 PRINT_FIELD_FD(attr, map_fd, tcp);
302 tprint_struct_next();
303 PRINT_FIELD_ADDR64(attr, key);
304 }
305 END_BPF_CMD_DECODER(RVAL_DECODED)
306
307 BEGIN_BPF_CMD_DECODER(BPF_MAP_GET_NEXT_KEY)
308 {
309 tprint_struct_begin();
310 PRINT_FIELD_FD(attr, map_fd, tcp);
311 tprint_struct_next();
312 PRINT_FIELD_ADDR64(attr, key);
313 tprint_struct_next();
314 PRINT_FIELD_ADDR64(attr, next_key);
315 }
316 END_BPF_CMD_DECODER(RVAL_DECODED)
317
318 BEGIN_BPF_CMD_DECODER(BPF_MAP_FREEZE)
319 {
320 tprint_struct_begin();
321 PRINT_FIELD_FD(attr, map_fd, tcp);
322 }
323 END_BPF_CMD_DECODER(RVAL_DECODED)
324
325 BEGIN_BPF_CMD_DECODER(BPF_PROG_LOAD)
326 {
327 tprint_struct_begin();
328 PRINT_FIELD_XVAL(attr, prog_type, bpf_prog_types, "BPF_PROG_TYPE_???");
329 tprint_struct_next();
330 PRINT_FIELD_U(attr, insn_cnt);
331 tprint_struct_next();
332 PRINT_FIELD_OBJ_TCB_VAL(attr, insns, tcp,
333 print_ebpf_prog, attr.insn_cnt);
334
335 tprint_struct_next();
336 tprints_field_name("license");
337 print_big_u64_addr(attr.license);
338 printstr(tcp, attr.license);
339
340 /* log_* fields were added in Linux commit v3.18-rc1~52^2~1^2~4. */
341 if (len <= offsetof(struct BPF_PROG_LOAD_struct, log_level))
342 break;
343 tprint_struct_next();
344 PRINT_FIELD_U(attr, log_level);
345 tprint_struct_next();
346 PRINT_FIELD_U(attr, log_size);
347 tprint_struct_next();
348 tprints_field_name("log_buf");
349 print_big_u64_addr(attr.log_buf);
350 printstr_ex(tcp, attr.log_buf, attr.log_size, QUOTE_0_TERMINATED);
351
352 /* kern_version field was added in Linux commit v4.1-rc1~84^2~50. */
353 if (len <= offsetof(struct BPF_PROG_LOAD_struct, kern_version))
354 break;
355 tprint_struct_next();
356 PRINT_FIELD_OBJ_VAL(attr, kern_version, print_kernel_version);
357
358 /* prog_flags field was added in Linux commit v4.12-rc2~34^2~29^2~2. */
359 if (len <= offsetof(struct BPF_PROG_LOAD_struct, prog_flags))
360 break;
361 tprint_struct_next();
362 PRINT_FIELD_FLAGS(attr, prog_flags, bpf_prog_flags, "BPF_F_???");
363
364 /* prog_name field was added in Linux commit v4.15-rc1~84^2~605^2~4. */
365 if (len <= offsetof(struct BPF_PROG_LOAD_struct, prog_name))
366 break;
367 tprint_struct_next();
368 PRINT_FIELD_CSTRING_SZ(attr, prog_name,
369 MIN(sizeof(attr.prog_name),
370 len - offsetof(struct BPF_PROG_LOAD_struct,
371 prog_name)));
372
373 /*
374 * prog_ifindex field was added as prog_target_ifindex in Linux commit
375 * v4.15-rc1~84^2~127^2~13 and renamed to its current name in
376 * v4.15-rc1~15^2~5^2~3^2~7.
377 */
378 if (len <= offsetof(struct BPF_PROG_LOAD_struct, prog_ifindex))
379 break;
380 tprint_struct_next();
381 PRINT_FIELD_IFINDEX(attr, prog_ifindex);
382
383 /*
384 * expected_attach_type was added in Linux commit
385 * v4.17-rc1~148^2~19^2^2~8.
386 */
387 if (len <= offsetof(struct BPF_PROG_LOAD_struct, expected_attach_type))
388 break;
389 tprint_struct_next();
390 PRINT_FIELD_XVAL(attr, expected_attach_type, bpf_attach_type,
391 "BPF_???");
392
393 /*
394 * The following seven fields were introduced by Linux commits
395 * v5.0-rc1~129^2~209^2~16^2~8 and v5.0-rc1~129^2~114^2~5^2~6.
396 */
397 if (len <= offsetof(struct BPF_PROG_LOAD_struct, prog_btf_fd))
398 break;
399 tprint_struct_next();
400 PRINT_FIELD_FD(attr, prog_btf_fd, tcp);
401 tprint_struct_next();
402 PRINT_FIELD_U(attr, func_info_rec_size);
403 tprint_struct_next();
404 PRINT_FIELD_ADDR64(attr, func_info);
405 tprint_struct_next();
406 PRINT_FIELD_U(attr, func_info_cnt);
407 tprint_struct_next();
408 PRINT_FIELD_U(attr, line_info_rec_size);
409 tprint_struct_next();
410 PRINT_FIELD_ADDR64(attr, line_info);
411 tprint_struct_next();
412 PRINT_FIELD_U(attr, line_info_cnt);
413
414 /* attach_btf_id was added in Linux commit v5.5-rc1~174^2~310^2~19^2~7 */
415 if (len <= offsetof(struct BPF_PROG_LOAD_struct, attach_btf_id))
416 break;
417 tprint_struct_next();
418 PRINT_FIELD_U(attr, attach_btf_id);
419
420 /* attach_prog_fd was added in Linux commit v5.5-rc1~174^2~49^2~12^2~3 */
421 if (len <= offsetof(struct BPF_PROG_LOAD_struct, attach_prog_fd))
422 break;
423 tprint_struct_next();
424 PRINT_FIELD_FD(attr, attach_prog_fd, tcp);
425
426 /* fd_array was added in Linux commit v5.14-rc1~119^2~501^2~2^2~13. */
427 if (len <= offsetof(struct BPF_PROG_LOAD_struct, fd_array))
428 break;
429 tprint_struct_next();
430 PRINT_FIELD_ADDR64(attr, fd_array);
431 }
432 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
433
434 BEGIN_BPF_CMD_DECODER(BPF_OBJ_PIN)
435 {
436 tprint_struct_begin();
437 tprints_field_name("pathname");
438 print_big_u64_addr(attr.pathname);
439 printpath(tcp, attr.pathname);
440
441 tprint_struct_next();
442 PRINT_FIELD_FD(attr, bpf_fd, tcp);
443
444 /* file_flags field was added in Linux v4.15-rc1~84^2~384^2~4 */
445 if (len <= offsetof(struct BPF_OBJ_PIN_struct, file_flags))
446 break;
447 tprint_struct_next();
448 PRINT_FIELD_FLAGS(attr, file_flags, bpf_file_flags, "BPF_F_???");
449
450 /* path_fd field was added in Linux v6.5-rc1~163^2~215^2~9 */
451 if (len <= offsetof(struct BPF_OBJ_PIN_struct, path_fd))
452 break;
453 tprint_struct_next();
454 PRINT_FIELD_DIRFD(attr, path_fd, tcp);
455 }
456 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
457
458 #define decode_BPF_OBJ_GET decode_BPF_OBJ_PIN
459
460 BEGIN_BPF_CMD_DECODER(BPF_PROG_ATTACH)
461 {
462 tprint_struct_begin();
463 PRINT_FIELD_FD(attr, target_fd, tcp);
464 tprint_struct_next();
465 PRINT_FIELD_FD(attr, attach_bpf_fd, tcp);
466 tprint_struct_next();
467 PRINT_FIELD_XVAL(attr, attach_type, bpf_attach_type, "BPF_???");
468 tprint_struct_next();
469 PRINT_FIELD_FLAGS(attr, attach_flags, bpf_attach_flags, "BPF_F_???");
470
471 /*
472 * The following field was introduced by Linux commit
473 * v5.6-rc1~151^2~199^2~7^2~3.
474 */
475 if (len <= offsetof(struct BPF_PROG_ATTACH_struct, replace_bpf_fd))
476 break;
477 tprint_struct_next();
478 PRINT_FIELD_FD(attr, replace_bpf_fd, tcp);
479 }
480 END_BPF_CMD_DECODER(RVAL_DECODED)
481
482 BEGIN_BPF_CMD_DECODER(BPF_PROG_DETACH)
483 {
484 tprint_struct_begin();
485 PRINT_FIELD_FD(attr, target_fd, tcp);
486 tprint_struct_next();
487 PRINT_FIELD_XVAL(attr, attach_type, bpf_attach_type, "BPF_???");
488 }
489 END_BPF_CMD_DECODER(RVAL_DECODED)
490
491 BEGIN_BPF_CMD_DECODER(BPF_PROG_TEST_RUN)
492 {
493 tprint_struct_begin();
494 tprints_field_name("test");
495 tprint_struct_begin();
496 PRINT_FIELD_FD(attr, prog_fd, tcp);
497 tprint_struct_next();
498 PRINT_FIELD_U(attr, retval);
499 tprint_struct_next();
500 PRINT_FIELD_U(attr, data_size_in);
501 tprint_struct_next();
502 PRINT_FIELD_U(attr, data_size_out);
503 tprint_struct_next();
504 PRINT_FIELD_ADDR64(attr, data_in);
505 tprint_struct_next();
506 PRINT_FIELD_ADDR64(attr, data_out);
507 tprint_struct_next();
508 PRINT_FIELD_U(attr, repeat);
509 tprint_struct_next();
510 PRINT_FIELD_U(attr, duration);
511 /*
512 * The following four fields were introduced by Linux commit
513 * v5.2-rc1~133^2~193^2~6.
514 */
515 if (len > offsetof(struct BPF_PROG_TEST_RUN_struct, ctx_size_in)) {
516 tprint_struct_next();
517 PRINT_FIELD_U(attr, ctx_size_in);
518 tprint_struct_next();
519 PRINT_FIELD_U(attr, ctx_size_out);
520 tprint_struct_next();
521 PRINT_FIELD_ADDR64(attr, ctx_in);
522 tprint_struct_next();
523 PRINT_FIELD_ADDR64(attr, ctx_out);
524 }
525 /*
526 * The following two fields were introduced in Linux commit
527 * v5.10-rc1~107^2~96^2~36.
528 */
529 if (len > offsetof(struct BPF_PROG_TEST_RUN_struct, flags)) {
530 tprint_struct_next();
531 PRINT_FIELD_FLAGS(attr, flags, bpf_test_run_flags, "BPF_F_???");
532 tprint_struct_next();
533 PRINT_FIELD_U(attr, cpu);
534 }
535 /*
536 * The batch_size field was introduced in Linux commit
537 * v5.18-rc1~136^2~11^2~58^2~4.
538 */
539 if (len > offsetof(struct BPF_PROG_TEST_RUN_struct, batch_size)) {
540 tprint_struct_next();
541 PRINT_FIELD_U(attr, batch_size);
542 }
543 tprint_struct_end();
544 }
545 END_BPF_CMD_DECODER(RVAL_DECODED)
546
547 BEGIN_BPF_CMD_DECODER(BPF_PROG_GET_NEXT_ID)
548 {
549 if (entering(tcp)) {
550 set_tcb_priv_ulong(tcp, attr.next_id);
551
552 tprint_struct_begin();
553 PRINT_FIELD_U(attr, start_id);
554 tprint_struct_next();
555 PRINT_FIELD_U(attr, next_id);
556
557 return 0;
558 }
559
560 uint32_t saved_next_id = get_tcb_priv_ulong(tcp);
561
562 if (saved_next_id != attr.next_id) {
563 tprint_value_changed();
564 PRINT_VAL_U(attr.next_id);
565 }
566
567 /* open_flags field has been added in Linux v4.15-rc1~84^2~384^2~4 */
568 if (len <= offsetof(struct BPF_PROG_GET_NEXT_ID_struct, open_flags))
569 break;
570 tprint_struct_next();
571 PRINT_FIELD_FLAGS(attr, open_flags, bpf_file_mode_flags, "BPF_F_???");
572 }
573 END_BPF_CMD_DECODER(RVAL_DECODED)
574
575 #define decode_BPF_MAP_GET_NEXT_ID decode_BPF_PROG_GET_NEXT_ID
576 #define decode_BPF_BTF_GET_NEXT_ID decode_BPF_PROG_GET_NEXT_ID
577 #define decode_BPF_LINK_GET_NEXT_ID decode_BPF_PROG_GET_NEXT_ID
578
579 BEGIN_BPF_CMD_DECODER(BPF_PROG_GET_FD_BY_ID)
580 {
581 tprint_struct_begin();
582 PRINT_FIELD_U(attr, prog_id);
583 tprint_struct_next();
584 PRINT_FIELD_U(attr, next_id);
585
586 /* open_flags field has been added in Linux v4.15-rc1~84^2~384^2~4 */
587 if (len <= offsetof(struct BPF_PROG_GET_FD_BY_ID_struct, open_flags))
588 break;
589 tprint_struct_next();
590 PRINT_FIELD_FLAGS(attr, open_flags, bpf_file_mode_flags, "BPF_F_???");
591 }
592 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
593
594 BEGIN_BPF_CMD_DECODER(BPF_MAP_GET_FD_BY_ID)
595 {
596 tprint_struct_begin();
597 PRINT_FIELD_U(attr, map_id);
598 tprint_struct_next();
599 PRINT_FIELD_U(attr, next_id);
600
601 /* open_flags field has been added in Linux v4.15-rc1~84^2~384^2~4 */
602 if (len <= offsetof(struct BPF_MAP_GET_FD_BY_ID_struct, open_flags))
603 break;
604 tprint_struct_next();
605 PRINT_FIELD_FLAGS(attr, open_flags, bpf_file_mode_flags, "BPF_F_???");
606 }
607 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
608
609 struct obj_get_info_saved;
610 typedef void (*print_bpf_obj_info_fn)(struct tcb *,
611 uint32_t bpf_fd,
612 const char *info_buf,
613 uint32_t size,
614 struct obj_get_info_saved *saved);
615
616 struct obj_get_info_saved {
617 print_bpf_obj_info_fn print_fn;
618
619 uint32_t info_len;
620
621 uint32_t jited_prog_len;
622 uint32_t xlated_prog_len;
623 uint32_t nr_map_ids;
624
625 uint32_t nr_jited_ksyms;
626 uint32_t nr_jited_func_lens;
627 uint64_t jited_ksyms;
628 uint64_t jited_func_lens;
629
630 uint32_t func_info_rec_size;
631 uint32_t nr_func_info;
632 uint32_t nr_line_info;
633 uint32_t nr_jited_line_info;
634 uint64_t jited_line_info;
635 uint32_t line_info_rec_size;
636 uint32_t jited_line_info_rec_size;
637 uint32_t nr_prog_tags;
638 };
639
640 static void
641 print_bpf_map_info(struct tcb * const tcp, uint32_t bpf_fd,
642 const char *info_buf, uint32_t size,
643 struct obj_get_info_saved *saved)
644 {
645 if (entering(tcp))
646 return;
647
648 struct bpf_map_info_struct info = { 0 };
649 const unsigned int len = MIN(size, bpf_map_info_struct_size);
650
651 memcpy(&info, info_buf, len);
652
653 tprint_struct_begin();
654 PRINT_FIELD_XVAL(info, type, bpf_map_types, "BPF_MAP_TYPE_???");
655 tprint_struct_next();
656 PRINT_FIELD_U(info, id);
657 tprint_struct_next();
658 PRINT_FIELD_U(info, key_size);
659 tprint_struct_next();
660 PRINT_FIELD_U(info, value_size);
661 tprint_struct_next();
662 PRINT_FIELD_U(info, max_entries);
663 tprint_struct_next();
664 PRINT_FIELD_FLAGS(info, map_flags, bpf_map_flags, "BPF_F_???");
665
666 /*
667 * "name" field was introduced by Linux commit v4.15-rc1~84^2~605^2~3.
668 */
669 if (len <= offsetof(struct bpf_map_info_struct, name))
670 goto print_bpf_map_info_end;
671 tprint_struct_next();
672 PRINT_FIELD_CSTRING(info, name);
673
674 /*
675 * ifindex, netns_dev, and netns_ino fields were introduced
676 * by Linux commit v4.16-rc1~123^2~109^2~5^2~4.
677 */
678 if (len <= offsetof(struct bpf_map_info_struct, ifindex))
679 goto print_bpf_map_info_end;
680 tprint_struct_next();
681 PRINT_FIELD_IFINDEX(info, ifindex);
682 /*
683 * btf_vmlinux_value_type_id field was crammed in
684 * by Linux commit v5.6-rc1~151^2~46^2~37^2~5.
685 */
686 tprint_struct_next();
687 PRINT_FIELD_U(info, btf_vmlinux_value_type_id);
688 tprint_struct_next();
689 PRINT_FIELD_DEV(info, netns_dev);
690 tprint_struct_next();
691 PRINT_FIELD_U(info, netns_ino);
692
693 /*
694 * The next three fields were introduced by Linux commits
695 * v4.18-rc1~114^2~223^2~21^2~4 and v4.18-rc1~114^2~148^2~7^2~2.
696 */
697 if (len <= offsetof(struct bpf_map_info_struct, btf_id))
698 goto print_bpf_map_info_end;
699 tprint_struct_next();
700 PRINT_FIELD_U(info, btf_id);
701 tprint_struct_next();
702 PRINT_FIELD_U(info, btf_key_type_id);
703 tprint_struct_next();
704 PRINT_FIELD_U(info, btf_value_type_id);
705
706 decode_attr_extra_data(tcp, info_buf, size, bpf_map_info_struct_size);
707
708 print_bpf_map_info_end:
709 tprint_struct_end();
710 }
711
712 /* Prints approximation of local time for a boot time */
713 static void
714 print_boottime(uint64_t boottime_ns)
715 {
716 if (xlat_verbose(xlat_verbosity) == XLAT_STYLE_RAW)
717 return;
718
719 static struct timespec ts_rtc;
720 struct timespec ts_boottime;
721
722 /*
723 * There is no good way to obtain RTC-boot time offset directly,
724 * it seems; there is some information present in /proc/stat,
725 * in "btime" field, but it has only second precision.
726 */
727 if (!ts_rtc.tv_sec) {
728 if (clock_gettime(CLOCK_BOOTTIME, &ts_boottime) ||
729 clock_gettime(CLOCK_REALTIME, &ts_rtc))
730 return;
731
732 /* Calculating offset */
733 ts_sub(&ts_rtc, &ts_rtc, &ts_boottime);
734 }
735
736 /* Converting boottime */
737 ts_boottime.tv_sec = boottime_ns / 1000000000;
738 ts_boottime.tv_nsec = boottime_ns % 1000000000;
739 ts_add(&ts_boottime, &ts_boottime, &ts_rtc);
740
741 /* Print only seconds, as the offset calculation is approximate */
742 tprints_comment(sprinttime(ts_boottime.tv_sec));
743 }
744
745 static void
746 print_bpf_prog_info(struct tcb * const tcp, uint32_t bpf_fd,
747 const char *info_buf, uint32_t size,
748 struct obj_get_info_saved *saved)
749 {
750 struct bpf_prog_info_struct info = { 0 };
751 const unsigned int len = MIN(size, bpf_prog_info_struct_size);
752 uint32_t map_id_buf;
753
754 memcpy(&info, info_buf, len);
755
756 if (entering(tcp)) {
757 saved->jited_prog_len = info.jited_prog_len;
758 saved->xlated_prog_len = info.xlated_prog_len;
759 saved->nr_map_ids = info.nr_map_ids;
760 saved->nr_jited_ksyms = info.nr_jited_ksyms;
761 saved->nr_jited_func_lens = info.nr_jited_func_lens;
762 saved->jited_ksyms = info.jited_ksyms;
763 saved->jited_func_lens = info.jited_func_lens;
764
765 saved->func_info_rec_size = info.func_info_rec_size;
766 saved->nr_func_info = info.nr_func_info;
767 saved->nr_line_info = info.nr_line_info;
768 saved->nr_jited_line_info = info.nr_jited_line_info;
769 saved->jited_line_info = info.jited_line_info;
770 saved->line_info_rec_size = info.line_info_rec_size;
771 saved->jited_line_info_rec_size = info.jited_line_info_rec_size;
772 saved->nr_prog_tags = info.nr_prog_tags;
773
774 return;
775 }
776
777 tprint_struct_begin();
778 PRINT_FIELD_XVAL(info, type, bpf_prog_types, "BPF_PROG_TYPE_???");
779 tprint_struct_next();
780 PRINT_FIELD_U(info, id);
781 tprint_struct_next();
782 PRINT_FIELD_HEX_ARRAY(info, tag);
783
784 tprint_struct_next();
785 tprints_field_name("jited_prog_len");
786 if (saved->jited_prog_len != info.jited_prog_len) {
787 PRINT_VAL_U(saved->jited_prog_len);
788 tprint_value_changed();
789 }
790 PRINT_VAL_U(info.jited_prog_len);
791
792 tprint_struct_next();
793 tprints_field_name("jited_prog_insns");
794 print_big_u64_addr(info.jited_prog_insns);
795 printstr_ex(tcp, info.jited_prog_insns, info.jited_prog_len,
796 QUOTE_FORCE_HEX);
797
798 tprint_struct_next();
799 tprints_field_name("xlated_prog_len");
800 if (saved->xlated_prog_len != info.xlated_prog_len) {
801 PRINT_VAL_U(saved->xlated_prog_len);
802 tprint_value_changed();
803 }
804 PRINT_VAL_U(info.xlated_prog_len);
805
806 tprint_struct_next();
807 PRINT_FIELD_OBJ_TCB_VAL(info, xlated_prog_insns,
808 tcp, print_ebpf_prog,
809 MIN(saved->xlated_prog_len, info.xlated_prog_len) / 8);
810
811 /*
812 * load_time, created_by_uid, nr_map_ids, map_ids, and name fields
813 * were introduced by Linux commit v4.15-rc1~84^2~605^2~4.
814 */
815 if (len <= offsetof(struct bpf_prog_info_struct, load_time))
816 goto print_bpf_prog_info_end;
817 tprint_struct_next();
818 PRINT_FIELD_U(info, load_time);
819 print_boottime(info.load_time);
820 tprint_struct_next();
821 PRINT_FIELD_ID(info, created_by_uid);
822
823 tprint_struct_next();
824 tprints_field_name("nr_map_ids");
825 if (saved->nr_map_ids != info.nr_map_ids) {
826 PRINT_VAL_U(saved->nr_map_ids);
827 tprint_value_changed();
828 }
829 PRINT_VAL_U(info.nr_map_ids);
830
831 tprint_struct_next();
832 tprints_field_name("map_ids");
833 print_big_u64_addr(info.map_ids);
834 print_array(tcp, info.map_ids, MIN(saved->nr_map_ids, info.nr_map_ids),
835 &map_id_buf, sizeof(map_id_buf),
836 tfetch_mem, print_uint_array_member, 0);
837
838 tprint_struct_next();
839 PRINT_FIELD_CSTRING(info, name);
840
841 /*
842 * ifindex, netns_dev, and netns_ino fields were introduced
843 * by Linux commit v4.16-rc1~123^2~227^2~5^2~2, and
844 * gpl_compatible was added later by Linux commit
845 * v4.18-rc1~114^2~376^2~6.
846 */
847 if (len <= offsetof(struct bpf_prog_info_struct, ifindex))
848 goto print_bpf_prog_info_end;
849 tprint_struct_next();
850 PRINT_FIELD_IFINDEX(info, ifindex);
851 tprint_struct_next();
852 PRINT_FIELD_U_CAST(info, gpl_compatible, unsigned int);
853 tprint_struct_next();
854 PRINT_FIELD_DEV(info, netns_dev);
855 tprint_struct_next();
856 PRINT_FIELD_U(info, netns_ino);
857
858 /*
859 * The next four fields were introduced by Linux commits
860 * v4.18-rc1~114^2~148^2~3^2~6 and v4.18-rc1~114^2~148^2~3^2~2.
861 */
862 if (len <= offsetof(struct bpf_prog_info_struct, nr_jited_ksyms))
863 goto print_bpf_prog_info_end;
864
865 tprint_struct_next();
866 tprints_field_name("nr_jited_ksyms");
867 if (saved->nr_jited_ksyms != info.nr_jited_ksyms) {
868 PRINT_VAL_U(saved->nr_jited_ksyms);
869 tprint_value_changed();
870 }
871 PRINT_VAL_U(info.nr_jited_ksyms);
872
873 tprint_struct_next();
874 tprints_field_name("nr_jited_func_lens");
875 if (saved->nr_jited_func_lens != info.nr_jited_func_lens) {
876 PRINT_VAL_U(saved->nr_jited_func_lens);
877 tprint_value_changed();
878 }
879 PRINT_VAL_U(info.nr_jited_func_lens);
880
881 tprint_struct_next();
882 tprints_field_name("jited_ksyms");
883 if (saved->jited_ksyms != info.jited_ksyms) {
884 printaddr64(saved->jited_ksyms);
885 tprint_value_changed();
886 }
887 printaddr64(info.jited_ksyms);
888
889 tprint_struct_next();
890 tprints_field_name("jited_func_lens");
891 if (saved->jited_func_lens != info.jited_func_lens) {
892 printaddr64(saved->jited_func_lens);
893 tprint_value_changed();
894 }
895 printaddr64(info.jited_func_lens);
896
897 /*
898 * The next twelve fields were introduced by Linux commits
899 * v5.0-rc1~129^2~209^2~16^2~8
900 * v5.0-rc1~129^2~114^2~5^2~6
901 * v5.0-rc1~129^2~114^2^2~2
902 * v5.0-rc1~129^2~15^2~22
903 */
904 if (len <= offsetof(struct bpf_prog_info_struct, btf_id))
905 goto print_bpf_prog_info_end;
906
907 tprint_struct_next();
908 PRINT_FIELD_U(info, btf_id);
909
910 tprint_struct_next();
911 tprints_field_name("func_info_rec_size");
912 if (saved->func_info_rec_size != info.func_info_rec_size) {
913 PRINT_VAL_U(saved->func_info_rec_size);
914 tprint_value_changed();
915 }
916 PRINT_VAL_U(info.func_info_rec_size);
917
918 tprint_struct_next();
919 PRINT_FIELD_ADDR64(info, func_info);
920
921 tprint_struct_next();
922 tprints_field_name("nr_func_info");
923 if (saved->nr_func_info != info.nr_func_info) {
924 PRINT_VAL_U(saved->nr_func_info);
925 tprint_value_changed();
926 }
927 PRINT_VAL_U(info.nr_func_info);
928
929 tprint_struct_next();
930 tprints_field_name("nr_line_info");
931 if (saved->nr_line_info != info.nr_line_info) {
932 PRINT_VAL_U(saved->nr_line_info);
933 tprint_value_changed();
934 }
935 PRINT_VAL_U(info.nr_line_info);
936
937 tprint_struct_next();
938 PRINT_FIELD_ADDR64(info, line_info);
939
940 tprint_struct_next();
941 tprints_field_name("jited_line_info");
942 if (saved->jited_line_info != info.jited_line_info) {
943 printaddr64(saved->jited_line_info);
944 tprint_value_changed();
945 }
946 printaddr64(info.jited_line_info);
947
948 tprint_struct_next();
949 tprints_field_name("nr_jited_line_info");
950 if (saved->nr_jited_line_info != info.nr_jited_line_info) {
951 PRINT_VAL_U(saved->nr_jited_line_info);
952 tprint_value_changed();
953 }
954 PRINT_VAL_U(info.nr_jited_line_info);
955
956 tprint_struct_next();
957 tprints_field_name("line_info_rec_size");
958 if (saved->line_info_rec_size != info.line_info_rec_size) {
959 PRINT_VAL_U(saved->line_info_rec_size);
960 tprint_value_changed();
961 }
962 PRINT_VAL_U(info.line_info_rec_size);
963
964 tprint_struct_next();
965 tprints_field_name("jited_line_info_rec_size");
966 if (saved->jited_line_info_rec_size != info.jited_line_info_rec_size) {
967 PRINT_VAL_U(saved->jited_line_info_rec_size);
968 tprint_value_changed();
969 }
970 PRINT_VAL_U(info.jited_line_info_rec_size);
971
972 tprint_struct_next();
973 tprints_field_name("nr_prog_tags");
974 if (saved->nr_prog_tags != info.nr_prog_tags) {
975 PRINT_VAL_U(saved->nr_prog_tags);
976 tprint_value_changed();
977 }
978 PRINT_VAL_U(info.nr_prog_tags);
979
980 tprint_struct_next();
981 PRINT_FIELD_ADDR64(info, prog_tags);
982
983 /*
984 * run_time_ns and run_cnt fields were introduced
985 * by Linux commit v5.1-rc1~178^2~17^2~15^2~2.
986 */
987 if (len <= offsetof(struct bpf_prog_info_struct, run_time_ns))
988 goto print_bpf_prog_info_end;
989
990 tprint_struct_next();
991 PRINT_FIELD_U(info, run_time_ns);
992 tprint_struct_next();
993 PRINT_FIELD_U(info, run_cnt);
994
995 /*
996 * The following field was introduced by Linux commit
997 * v5.12-rc1~200^2~28^2~28.
998 */
999 if (len <= offsetof(struct bpf_prog_info_struct, recursion_misses))
1000 goto print_bpf_prog_info_end;
1001
1002 tprint_struct_next();
1003 PRINT_FIELD_U64(info, recursion_misses);
1004
1005 /*
1006 * The following field was introduced by Linux commit
1007 * v5.16-rc1~159^2~2^2~43^2~1.
1008 */
1009 if (len <= offsetof(struct bpf_prog_info_struct, verified_insns))
1010 goto print_bpf_prog_info_end;
1011
1012 tprint_struct_next();
1013 PRINT_FIELD_U(info, verified_insns);
1014
1015 decode_attr_extra_data(tcp, info_buf, size, bpf_prog_info_struct_size);
1016
1017 print_bpf_prog_info_end:
1018 tprint_struct_end();
1019 }
1020
1021 static const char *
1022 fetch_bpf_obj_info(struct tcb * const tcp, uint64_t info, uint32_t size)
1023 {
1024 static char *info_buf;
1025
1026 if (!info_buf)
1027 info_buf = xmalloc(get_pagesize());
1028
1029 memset(info_buf, 0, get_pagesize());
1030
1031 if (size > 0 && size <= get_pagesize()
1032 && !umoven(tcp, info, size, info_buf))
1033 return info_buf;
1034
1035 return NULL;
1036 }
1037
1038 static void
1039 print_bpf_obj_info_addr(struct tcb * const tcp, uint64_t addr)
1040 {
1041 if (exiting(tcp))
1042 printaddr64(addr);
1043 }
1044
1045 static void
1046 print_bpf_obj_info(struct tcb * const tcp, uint32_t bpf_fd, uint64_t info,
1047 uint32_t size, struct obj_get_info_saved *saved)
1048 {
1049 if (abbrev(tcp)) {
1050 print_bpf_obj_info_addr(tcp, info);
1051 return;
1052 }
1053
1054 static struct {
1055 const char *id;
1056 print_bpf_obj_info_fn print_fn;
1057 } obj_printers[] = {
1058 { "anon_inode:bpf-map", print_bpf_map_info },
1059 { "anon_inode:bpf-prog", print_bpf_prog_info }
1060 };
1061
1062 if (entering(tcp)) {
1063 char path[PATH_MAX + 1];
1064
1065 if (getfdpath(tcp, bpf_fd, path, sizeof(path)) > 0) {
1066 for (size_t i = 0; i < ARRAY_SIZE(obj_printers); ++i) {
1067 if (!strcmp(path, obj_printers[i].id)) {
1068 saved->print_fn =
1069 obj_printers[i].print_fn;
1070 break;
1071 }
1072 }
1073 }
1074 }
1075
1076 if (!saved || !saved->print_fn) {
1077 print_bpf_obj_info_addr(tcp, info);
1078 return;
1079 }
1080
1081 const char *info_buf = fetch_bpf_obj_info(tcp, info, size);
1082
1083 if (info_buf)
1084 saved->print_fn(tcp, bpf_fd, info_buf, size, saved);
1085 else
1086 print_bpf_obj_info_addr(tcp, info);
1087 }
1088
1089 BEGIN_BPF_CMD_DECODER(BPF_OBJ_GET_INFO_BY_FD)
1090 {
1091 struct obj_get_info_saved *saved;
1092
1093 if (entering(tcp)) {
1094 saved = xzalloc(sizeof(*saved));
1095 saved->info_len = attr.info_len;
1096 set_tcb_priv_data(tcp, saved, free);
1097
1098 tprint_struct_begin();
1099 tprints_field_name("info");
1100 tprint_struct_begin();
1101 PRINT_FIELD_FD(attr, bpf_fd, tcp);
1102 tprint_struct_next();
1103 PRINT_FIELD_U(attr, info_len);
1104 } else {
1105 saved = get_tcb_priv_data(tcp);
1106
1107 if (saved && (saved->info_len != attr.info_len)) {
1108 tprint_value_changed();
1109 PRINT_VAL_U(attr.info_len);
1110 }
1111
1112 tprint_struct_next();
1113 tprints_field_name("info");
1114 }
1115
1116 print_bpf_obj_info(tcp, attr.bpf_fd, attr.info, attr.info_len, saved);
1117
1118 if (entering(tcp))
1119 return 0;
1120
1121 tprint_struct_end();
1122 }
1123 END_BPF_CMD_DECODER(RVAL_DECODED)
1124
1125 BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)
1126 {
1127 uint32_t prog_id_buf;
1128
1129 if (entering(tcp)) {
1130 tprint_struct_begin();
1131 tprints_field_name("query");
1132 tprint_struct_begin();
1133 PRINT_FIELD_FD(attr, target_fd, tcp);
1134 tprint_struct_next();
1135 PRINT_FIELD_XVAL(attr, attach_type, bpf_attach_type,
1136 "BPF_???");
1137 tprint_struct_next();
1138 PRINT_FIELD_FLAGS(attr, query_flags, bpf_query_flags,
1139 "BPF_F_QUERY_???");
1140 tprint_struct_next();
1141 PRINT_FIELD_FLAGS(attr, attach_flags, bpf_attach_flags,
1142 "BPF_F_???");
1143
1144 tprint_struct_next();
1145 tprints_field_name("prog_ids");
1146
1147 set_tcb_priv_ulong(tcp, attr.prog_cnt);
1148
1149 return 0;
1150 }
1151
1152 print_big_u64_addr(attr.prog_ids);
1153 print_array(tcp, attr.prog_ids, attr.prog_cnt, &prog_id_buf,
1154 sizeof(prog_id_buf), tfetch_mem,
1155 print_uint_array_member, 0);
1156
1157 tprint_struct_next();
1158 tprints_field_name("prog_cnt");
1159 const uint32_t prog_cnt_entering = get_tcb_priv_ulong(tcp);
1160 if (prog_cnt_entering != attr.prog_cnt) {
1161 PRINT_VAL_U(prog_cnt_entering);
1162 tprint_value_changed();
1163 }
1164 PRINT_VAL_U(attr.prog_cnt);
1165 tprint_struct_end();
1166 }
1167 END_BPF_CMD_DECODER(RVAL_DECODED)
1168
1169 BEGIN_BPF_CMD_DECODER(BPF_RAW_TRACEPOINT_OPEN)
1170 {
1171 enum { TP_NAME_SIZE = 128 };
1172
1173 tprint_struct_begin();
1174 tprints_field_name("raw_tracepoint");
1175 tprint_struct_begin();
1176 tprints_field_name("name");
1177 print_big_u64_addr(attr.name);
1178 printstr_ex(tcp, attr.name, TP_NAME_SIZE, QUOTE_0_TERMINATED);
1179
1180 tprint_struct_next();
1181 PRINT_FIELD_FD(attr, prog_fd, tcp);
1182
1183 tprint_struct_end();
1184 }
1185 END_BPF_CMD_DECODER(RVAL_DECODED)
1186
1187 BEGIN_BPF_CMD_DECODER(BPF_BTF_LOAD)
1188 {
1189 tprint_struct_begin();
1190 tprints_field_name("btf");
1191 print_big_u64_addr(attr.btf);
1192 printstrn(tcp, attr.btf, attr.btf_size);
1193 tprint_struct_next();
1194 PRINT_FIELD_ADDR64(attr, btf_log_buf);
1195 tprint_struct_next();
1196 PRINT_FIELD_U(attr, btf_size);
1197 tprint_struct_next();
1198 PRINT_FIELD_U(attr, btf_log_size);
1199 tprint_struct_next();
1200 PRINT_FIELD_U(attr, btf_log_level);
1201 }
1202 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
1203
1204 BEGIN_BPF_CMD_DECODER(BPF_BTF_GET_FD_BY_ID)
1205 {
1206 tprint_struct_begin();
1207 PRINT_FIELD_U(attr, btf_id);
1208 }
1209 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
1210
1211 BEGIN_BPF_CMD_DECODER(BPF_TASK_FD_QUERY)
1212 {
1213 if (entering(tcp)) {
1214 set_tcb_priv_ulong(tcp, attr.buf_len);
1215
1216 tprint_struct_begin();
1217 tprints_field_name("task_fd_query");
1218 tprint_struct_begin();
1219 PRINT_FIELD_TGID(attr, pid, tcp);
1220 tprint_struct_next();
1221 PRINT_FIELD_FD(attr, fd, tcp);
1222 tprint_struct_next();
1223 PRINT_FIELD_U(attr, flags);
1224 tprint_struct_next();
1225 PRINT_FIELD_U(attr, buf_len);
1226
1227 return 0;
1228 }
1229
1230 unsigned int saved_buf_len = get_tcb_priv_ulong(tcp);
1231
1232 if (saved_buf_len != attr.buf_len) {
1233 tprint_value_changed();
1234 PRINT_VAL_U(attr.buf_len);
1235 }
1236
1237 const unsigned int buf_len = MIN(saved_buf_len, attr.buf_len);
1238 tprint_struct_next();
1239 tprints_field_name("buf");
1240 print_big_u64_addr(attr.buf);
1241 printstr_ex(tcp, attr.buf, buf_len, QUOTE_0_TERMINATED);
1242 tprint_struct_next();
1243 PRINT_FIELD_U(attr, prog_id);
1244 tprint_struct_next();
1245 PRINT_FIELD_XVAL(attr, fd_type, bpf_task_fd_type, "BPF_FD_TYPE_???");
1246 tprint_struct_next();
1247 PRINT_FIELD_X(attr, probe_offset);
1248 tprint_struct_next();
1249 PRINT_FIELD_X(attr, probe_addr);
1250
1251 tprint_struct_end();
1252 }
1253 END_BPF_CMD_DECODER(RVAL_DECODED)
1254
1255 BEGIN_BPF_CMD_DECODER(BPF_MAP_LOOKUP_BATCH)
1256 {
1257 if (entering(tcp)) {
1258 set_tcb_priv_ulong(tcp, attr.count);
1259
1260 tprint_struct_begin();
1261 tprints_field_name("batch");
1262 tprint_struct_begin();
1263 PRINT_FIELD_ADDR64(attr, in_batch);
1264 tprint_struct_next();
1265 PRINT_FIELD_ADDR64(attr, out_batch);
1266 tprint_struct_next();
1267 PRINT_FIELD_ADDR64(attr, keys);
1268 tprint_struct_next();
1269 PRINT_FIELD_ADDR64(attr, values);
1270 tprint_struct_next();
1271 PRINT_FIELD_U(attr, count);
1272 tprint_struct_next();
1273 PRINT_FIELD_FD(attr, map_fd, tcp);
1274 tprint_struct_next();
1275 PRINT_FIELD_FLAGS(attr, elem_flags,
1276 bpf_map_lookup_elem_flags, "BPF_???");
1277 tprint_struct_next();
1278 PRINT_FIELD_X(attr, flags);
1279
1280 tprint_struct_end();
1281 } else {
1282 unsigned long count = get_tcb_priv_ulong(tcp);
1283
1284 if (count != attr.count) {
1285 tprint_value_changed();
1286 tprint_struct_begin();
1287 tprints_field_name("batch");
1288 tprint_struct_begin();
1289 PRINT_FIELD_U(attr, count);
1290 tprint_struct_end();
1291 tprint_struct_end();
1292 }
1293
1294 return RVAL_DECODED;
1295 }
1296 }
1297 END_BPF_CMD_DECODER(0)
1298
1299 #define decode_BPF_MAP_LOOKUP_AND_DELETE_BATCH decode_BPF_MAP_LOOKUP_BATCH
1300
1301 BEGIN_BPF_CMD_DECODER(BPF_MAP_UPDATE_BATCH)
1302 {
1303 if (entering(tcp)) {
1304 set_tcb_priv_ulong(tcp, attr.count);
1305
1306 tprint_struct_begin();
1307 tprints_field_name("batch");
1308 tprint_struct_begin();
1309 PRINT_FIELD_ADDR64(attr, keys);
1310 tprint_struct_next();
1311 PRINT_FIELD_ADDR64(attr, values);
1312 tprint_struct_next();
1313 PRINT_FIELD_U(attr, count);
1314 tprint_struct_next();
1315 PRINT_FIELD_FD(attr, map_fd, tcp);
1316 tprint_struct_next();
1317 PRINT_FIELD_FLAGS(attr, elem_flags,
1318 bpf_map_lookup_elem_flags, "BPF_???");
1319 tprint_struct_next();
1320 PRINT_FIELD_X(attr, flags);
1321
1322 tprint_struct_end();
1323 } else {
1324 unsigned long count = get_tcb_priv_ulong(tcp);
1325
1326 if (count != attr.count) {
1327 tprint_value_changed();
1328 tprint_struct_begin();
1329 tprints_field_name("batch");
1330 tprint_struct_begin();
1331 PRINT_FIELD_U(attr, count);
1332 tprint_struct_end();
1333 tprint_struct_end();
1334 }
1335
1336 return RVAL_DECODED;
1337 }
1338 }
1339 END_BPF_CMD_DECODER(0)
1340
1341 BEGIN_BPF_CMD_DECODER(BPF_MAP_DELETE_BATCH)
1342 {
1343 if (entering(tcp)) {
1344 set_tcb_priv_ulong(tcp, attr.count);
1345
1346 tprint_struct_begin();
1347 tprints_field_name("batch");
1348 tprint_struct_begin();
1349 PRINT_FIELD_ADDR64(attr, keys);
1350 tprint_struct_next();
1351 PRINT_FIELD_U(attr, count);
1352 tprint_struct_next();
1353 PRINT_FIELD_FD(attr, map_fd, tcp);
1354 tprint_struct_next();
1355 PRINT_FIELD_FLAGS(attr, elem_flags,
1356 bpf_map_lookup_elem_flags, "BPF_???");
1357 tprint_struct_next();
1358 PRINT_FIELD_X(attr, flags);
1359
1360 tprint_struct_end();
1361 } else {
1362 unsigned long count = get_tcb_priv_ulong(tcp);
1363
1364 if (count != attr.count) {
1365 tprint_value_changed();
1366 tprint_struct_begin();
1367 tprints_field_name("batch");
1368 tprint_struct_begin();
1369 PRINT_FIELD_U(attr, count);
1370 tprint_struct_end();
1371 tprint_struct_end();
1372 }
1373
1374 return RVAL_DECODED;
1375 }
1376 }
1377 END_BPF_CMD_DECODER(0)
1378
1379 union strace_bpf_iter_link_info {
1380 struct {
1381 uint32_t map_fd;
1382 } map;
1383 };
1384
1385 static bool
1386 print_iter_info_array_member(struct tcb *tcp, void *elem_buf,
1387 size_t elem_size, void *data)
1388 {
1389 union strace_bpf_iter_link_info *bili =
1390 (union strace_bpf_iter_link_info *) elem_buf;
1391
1392 tprint_struct_begin();
1393 tprints_field_name("map");
1394 tprint_struct_begin();
1395 PRINT_FIELD_FD(bili->map, map_fd, tcp);
1396 tprint_struct_end();
1397 tprint_struct_end();
1398
1399 return true;
1400 }
1401
1402 static bool
1403 print_str_array_member(struct tcb *tcp, void *elem_buf,
1404 size_t elem_size, void *data)
1405 {
1406 kernel_ulong_t ptr = opt_wordsize(*(uint64_t *) elem_buf,
1407 *(uint32_t *) elem_buf);
1408
1409 printstr(tcp, ptr);
1410
1411 return true;
1412 }
1413
1414 BEGIN_BPF_CMD_DECODER(BPF_LINK_CREATE)
1415 {
1416 tprint_struct_begin();
1417 tprints_field_name("link_create");
1418 tprint_struct_begin();
1419 PRINT_FIELD_FD(attr, prog_fd, tcp);
1420 tprint_struct_next();
1421 PRINT_FIELD_FD(attr, target_fd, tcp);
1422 tprint_struct_next();
1423 PRINT_FIELD_XVAL(attr, attach_type, bpf_attach_type, "BPF_???");
1424 tprint_struct_next();
1425 PRINT_FIELD_X(attr, flags);
1426
1427 if (len <= offsetof(struct BPF_LINK_CREATE_struct, target_btf_id))
1428 goto print_bpf_link_create_end;
1429
1430 /* Trying to guess the union decoding based on the attach type */
1431 switch (attr.attach_type) {
1432 /* TODO: check that prog type == BPF_PROG_TYPE_EXT */
1433 /*
1434 * Yes, it is BPF_CGROUP_INET_INGRESS, see the inconceivable genius
1435 * of the expected_attach_type check in v5.6-rc1~151^2~46^2~1^2~2.
1436 */
1437 case 0:
1438 /* Introduced in Linux commit v5.10-rc1~107^2~96^2~12^2~5 */
1439 if (attr.target_btf_id) {
1440 tprint_struct_next();
1441 PRINT_FIELD_U(attr, target_btf_id);
1442 }
1443 attr_size = offsetofend(typeof(attr), target_btf_id);
1444 break;
1445
1446 /* TODO: prog type == BPF_PROG_TYPE_TRACING */
1447 case BPF_TRACE_ITER: {
1448 /* Introduced in Linux commit v5.9-rc1~36^2~30^2~8^2~1 */
1449 union strace_bpf_iter_link_info buf;
1450
1451 tprint_struct_next();
1452 tprints_field_name("iter_info");
1453 print_big_u64_addr(attr.iter_info);
1454 print_array(tcp, attr.iter_info, attr.iter_info_len,
1455 &buf, sizeof(buf), tfetch_mem,
1456 print_iter_info_array_member, 0);
1457 tprint_struct_next();
1458 PRINT_FIELD_U(attr, iter_info_len);
1459 attr_size = offsetofend(typeof(attr), iter_info_len);
1460 break;
1461 }
1462
1463 /* TODO: prog type == BPF_PROG_TYPE_{KPROBE,PERF_EVENT,TRACEPOINT} */
1464 case BPF_PERF_EVENT:
1465 /* Introduced in Linux commit v5.15-rc1~157^2~22^2~33^2~11 */
1466 tprint_struct_next();
1467 tprints_field_name("perf_event");
1468 tprint_struct_begin();
1469 PRINT_FIELD_X(attr.perf_event, bpf_cookie);
1470 tprint_struct_end();
1471 attr_size = offsetofend(typeof(attr), perf_event.bpf_cookie);
1472 break;
1473
1474 /* TODO: prog type == BPF_PROG_TYPE_KPROBE */
1475 case BPF_TRACE_KPROBE_MULTI: {
1476 /* Introduced in Linux commit v5.18-rc1~136^2~11^2~28^2~10 */
1477 union {
1478 kernel_ulong_t ptr;
1479 uint64_t addr;
1480 uint64_t cookie;
1481 } buf;
1482
1483 tprint_struct_next();
1484 tprints_field_name("kprobe_multi");
1485 tprint_struct_begin();
1486 PRINT_FIELD_FLAGS(attr.kprobe_multi, flags,
1487 bpf_link_create_kprobe_multi_flags,
1488 "BPF_F_???");
1489 tprint_struct_next();
1490 PRINT_FIELD_U(attr.kprobe_multi, cnt);
1491 tprint_struct_next();
1492 tprints_field_name("syms");
1493 print_big_u64_addr(attr.kprobe_multi.syms);
1494 print_array(tcp, attr.kprobe_multi.syms, attr.kprobe_multi.cnt,
1495 &buf.ptr, current_wordsize,
1496 tfetch_mem, print_str_array_member, 0);
1497 tprint_struct_next();
1498 tprints_field_name("addrs");
1499 print_big_u64_addr(attr.kprobe_multi.addrs);
1500 print_array(tcp, attr.kprobe_multi.addrs, attr.kprobe_multi.cnt,
1501 &buf.ptr, sizeof(buf.addr),
1502 tfetch_mem, print_xint_array_member, 0);
1503 tprint_struct_next();
1504 tprints_field_name("cookies");
1505 print_big_u64_addr(attr.kprobe_multi.cookies);
1506 print_array(tcp, attr.kprobe_multi.cookies,
1507 attr.kprobe_multi.cnt,
1508 &buf.cookie, sizeof(buf.cookie),
1509 tfetch_mem, print_xint_array_member, 0);
1510 tprint_struct_end();
1511 attr_size = offsetofend(typeof(attr), kprobe_multi.cookies);
1512 break;
1513 }
1514
1515 default:
1516 /*
1517 * NB: resetting attr_size, so decode_attr_extra_data
1518 * can pick up non-zero values in the union at the end
1519 * of the link_create struct.
1520 */
1521 attr_size = offsetofend(typeof(attr), flags);
1522 }
1523
1524 print_bpf_link_create_end:
1525 tprint_struct_end();
1526 }
1527 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
1528
1529 BEGIN_BPF_CMD_DECODER(BPF_LINK_UPDATE)
1530 {
1531 tprint_struct_begin();
1532 tprints_field_name("link_update");
1533 tprint_struct_begin();
1534 PRINT_FIELD_FD(attr, link_fd, tcp);
1535 tprint_struct_next();
1536 PRINT_FIELD_FD(attr, new_prog_fd, tcp);
1537 tprint_struct_next();
1538 PRINT_FIELD_FLAGS(attr, flags, bpf_attach_flags, "BPF_F_???");
1539 if (attr.flags & BPF_F_REPLACE) {
1540 tprint_struct_next();
1541 PRINT_FIELD_FD(attr, old_prog_fd, tcp);
1542 }
1543 tprint_struct_end();
1544 }
1545 END_BPF_CMD_DECODER(RVAL_DECODED)
1546
1547 BEGIN_BPF_CMD_DECODER(BPF_LINK_GET_FD_BY_ID)
1548 {
1549 tprint_struct_begin();
1550 PRINT_FIELD_U(attr, link_id);
1551 }
1552 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
1553
1554 BEGIN_BPF_CMD_DECODER(BPF_ENABLE_STATS)
1555 {
1556 tprint_struct_begin();
1557 tprints_field_name("enable_stats");
1558 tprint_struct_begin();
1559 PRINT_FIELD_XVAL(attr, type, bpf_stats_type, "BPF_STATS_???");
1560 tprint_struct_end();
1561 }
1562 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
1563
1564 BEGIN_BPF_CMD_DECODER(BPF_ITER_CREATE)
1565 {
1566 tprint_struct_begin();
1567 tprints_field_name("iter_create");
1568 tprint_struct_begin();
1569 PRINT_FIELD_FD(attr, link_fd, tcp);
1570 tprint_struct_next();
1571 PRINT_FIELD_X(attr, flags);
1572 tprint_struct_end();
1573 }
1574 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
1575
1576 BEGIN_BPF_CMD_DECODER(BPF_LINK_DETACH)
1577 {
1578 tprint_struct_begin();
1579 tprints_field_name("link_detach");
1580 tprint_struct_begin();
1581 PRINT_FIELD_FD(attr, link_fd, tcp);
1582 tprint_struct_end();
1583 }
1584 END_BPF_CMD_DECODER(RVAL_DECODED)
1585
1586 BEGIN_BPF_CMD_DECODER(BPF_PROG_BIND_MAP)
1587 {
1588 tprint_struct_begin();
1589 tprints_field_name("prog_bind_map");
1590 tprint_struct_begin();
1591 PRINT_FIELD_FD(attr, prog_fd, tcp);
1592 tprint_struct_next();
1593 PRINT_FIELD_FD(attr, map_fd, tcp);
1594 tprint_struct_next();
1595 PRINT_FIELD_X(attr, flags);
1596 tprint_struct_end();
1597 }
1598 END_BPF_CMD_DECODER(RVAL_DECODED | RVAL_FD)
1599
1600 SYS_FUNC(bpf)
1601 {
1602 static const bpf_cmd_decoder_t bpf_cmd_decoders[] = {
1603 BPF_CMD_ENTRY(BPF_MAP_CREATE),
1604 BPF_CMD_ENTRY(BPF_MAP_LOOKUP_ELEM),
1605 BPF_CMD_ENTRY(BPF_MAP_UPDATE_ELEM),
1606 BPF_CMD_ENTRY(BPF_MAP_DELETE_ELEM),
1607 BPF_CMD_ENTRY(BPF_MAP_GET_NEXT_KEY),
1608 BPF_CMD_ENTRY(BPF_PROG_LOAD),
1609 BPF_CMD_ENTRY(BPF_OBJ_PIN),
1610 BPF_CMD_ENTRY(BPF_OBJ_GET),
1611 BPF_CMD_ENTRY(BPF_PROG_ATTACH),
1612 BPF_CMD_ENTRY(BPF_PROG_DETACH),
1613 BPF_CMD_ENTRY(BPF_PROG_TEST_RUN),
1614 BPF_CMD_ENTRY(BPF_PROG_GET_NEXT_ID),
1615 BPF_CMD_ENTRY(BPF_MAP_GET_NEXT_ID),
1616 BPF_CMD_ENTRY(BPF_PROG_GET_FD_BY_ID),
1617 BPF_CMD_ENTRY(BPF_MAP_GET_FD_BY_ID),
1618 BPF_CMD_ENTRY(BPF_OBJ_GET_INFO_BY_FD),
1619 BPF_CMD_ENTRY(BPF_PROG_QUERY),
1620 BPF_CMD_ENTRY(BPF_RAW_TRACEPOINT_OPEN),
1621 BPF_CMD_ENTRY(BPF_BTF_LOAD),
1622 BPF_CMD_ENTRY(BPF_BTF_GET_FD_BY_ID),
1623 BPF_CMD_ENTRY(BPF_TASK_FD_QUERY),
1624 BPF_CMD_ENTRY(BPF_MAP_LOOKUP_AND_DELETE_ELEM),
1625 BPF_CMD_ENTRY(BPF_MAP_FREEZE),
1626 BPF_CMD_ENTRY(BPF_BTF_GET_NEXT_ID),
1627 BPF_CMD_ENTRY(BPF_MAP_LOOKUP_BATCH),
1628 BPF_CMD_ENTRY(BPF_MAP_LOOKUP_AND_DELETE_BATCH),
1629 BPF_CMD_ENTRY(BPF_MAP_UPDATE_BATCH),
1630 BPF_CMD_ENTRY(BPF_MAP_DELETE_BATCH),
1631 BPF_CMD_ENTRY(BPF_LINK_CREATE),
1632 BPF_CMD_ENTRY(BPF_LINK_UPDATE),
1633 BPF_CMD_ENTRY(BPF_LINK_GET_NEXT_ID),
1634 BPF_CMD_ENTRY(BPF_LINK_GET_FD_BY_ID),
1635 BPF_CMD_ENTRY(BPF_ENABLE_STATS),
1636 BPF_CMD_ENTRY(BPF_ITER_CREATE),
1637 BPF_CMD_ENTRY(BPF_LINK_DETACH),
1638 BPF_CMD_ENTRY(BPF_PROG_BIND_MAP),
1639 };
1640
1641 const unsigned int cmd = tcp->u_arg[0];
1642 const kernel_ulong_t addr = tcp->u_arg[1];
1643 const unsigned int size = tcp->u_arg[2];
1644 int rc = RVAL_DECODED;
1645
1646 if (entering(tcp)) {
1647 /* cmd */
1648 printxval(bpf_commands, cmd, "BPF_???");
1649 tprint_arg_next();
1650 }
1651
1652 /* attr */
1653 if (size > 0
1654 && size <= get_pagesize()
1655 && cmd < ARRAY_SIZE(bpf_cmd_decoders)
1656 && bpf_cmd_decoders[cmd]) {
1657 static char *buf;
1658
1659 if (!buf)
1660 buf = xmalloc(get_pagesize());
1661
1662 if (!umoven_or_printaddr_ignore_syserror(tcp, addr, size, buf))
1663 rc = bpf_cmd_decoders[cmd](tcp, addr, size, buf);
1664 } else {
1665 printaddr(addr);
1666 }
1667
1668 if (exiting(tcp) || (rc & RVAL_DECODED)) {
1669 /* size */
1670 tprint_arg_next();
1671 PRINT_VAL_U(size);
1672 }
1673
1674 return rc;
1675 }