History

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Daniel Borkmann says: ==================== pull-request: bpf-next 2018-12-21 The following pull-request contains BPF updates for your *net-next* tree. There is a merge conflict in test_verifier.c. Result looks as follows: [...] }, { "calls: cross frame pruning", .insns = { [...] .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, .errstr_unpriv = "function calls to other bpf functions are allowed for root only", .result_unpriv = REJECT, .errstr = "!read_ok", .result = REJECT, }, { "jset: functional", .insns = { [...] { "jset: unknown const compare not taken", .insns = { BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32), BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1), BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0), BPF_EXIT_INSN(), }, .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, .errstr_unpriv = "!read_ok", .result_unpriv = REJECT, .errstr = "!read_ok", .result = REJECT, }, [...] { "jset: range", .insns = { [...] }, .prog_type = BPF_PROG_TYPE_SOCKET_FILTER, .result_unpriv = ACCEPT, .result = ACCEPT, }, The main changes are: 1) Various BTF related improvements in order to get line info working. Meaning, verifier will now annotate the corresponding BPF C code to the error log, from Martin and Yonghong. 2) Implement support for raw BPF tracepoints in modules, from Matt. 3) Add several improvements to verifier state logic, namely speeding up stacksafe check, optimizations for stack state equivalence test and safety checks for liveness analysis, from Alexei. 4) Teach verifier to make use of BPF_JSET instruction, add several test cases to kselftests and remove nfp specific JSET optimization now that verifier has awareness, from Jakub. 5) Improve BPF verifier's slot_type marking logic in order to allow more stack slot sharing, from Jiong. 6) Add sk_msg->size member for context access and add set of fixes and improvements to make sock_map with kTLS usable with openssl based applications, from John. 7) Several cleanups and documentation updates in bpftool as well as auto-mount of tracefs for "bpftool prog tracelog" command, from Quentin. 8) Include sub-program tags from now on in bpf_prog_info in order to have a reliable way for user space to get all tags of the program e.g. needed for kallsyms correlation, from Song. 9) Add BTF annotations for cgroup_local_storage BPF maps and implement bpf fs pretty print support, from Roman. 10) Fix bpftool in order to allow for cross-compilation, from Ivan. 11) Update of bpftool license to GPLv2-only + BSD-2-Clause in order to be compatible with libbfd and allow for Debian packaging, from Jakub. 12) Remove an obsolete prog->aux sanitation in dump and get rid of version check for prog load, from Daniel. 13) Fix a memory leak in libbpf's line info handling, from Prashant. 14) Fix cpumap's frame alignment for build_skb() so that skb_shared_info does not get unaligned, from Jesper. 15) Fix test_progs kselftest to work with older compilers which are less smart in optimizing (and thus throwing build error), from Stanislav. 16) Cleanup and simplify AF_XDP socket teardown, from Björn. 17) Fix sk lookup in BPF kselftest's test_sock_addr with regards to netns_id argument, from Andrey. ====================

David S. Miller committed 7 years ago

Commit 339bbff2 parents e770454 1cf4a0c64 files · +2331 −680Browse files

Unified · Split

64 files
  1. arch/arm64/net/bpf_jit_comp.c +1 −0
  2. arch/sparc/net/bpf_jit_comp_64.c +1 −0
  3. drivers/net/ethernet/netronome/nfp/bpf/jit.c +10 −17
  4. include/linux/bpf.h +3 −0
  5. include/linux/bpf_verifier.h +2 −0
  6. include/linux/btf.h +4 −1
  7. include/linux/module.h +4 −0
  8. include/linux/skmsg.h +9 −0
  9. include/linux/socket.h +1 −0
  10. include/linux/trace_events.h +6 −2
  11. include/net/tls.h +9 −0
  12. include/uapi/linux/bpf.h +12 −1
  13. include/uapi/linux/btf.h +18 −2
  14. kernel/bpf/arraymap.c +1 −0
  15. kernel/bpf/btf.c +348 −45
  16. kernel/bpf/cpumap.c +1 −1
  17. kernel/bpf/local_storage.c +83 −1
  18. kernel/bpf/lpm_trie.c +1 −0
  19. kernel/bpf/syscall.c +44 −36
  20. kernel/bpf/verifier.c +224 −17
  21. kernel/module.c +5 −0
  22. kernel/trace/bpf_trace.c +97 −2
  23. net/core/filter.c +23 −7
  24. net/core/skmsg.c +20 −3
  25. net/ipv4/tcp_bpf.c +13 −2
  26. net/tls/tls_main.c +12 −2
  27. net/tls/tls_sw.c +30 −13
  28. net/xdp/xsk.c +1 −15
  29. tools/bpf/bpftool/Documentation/bpftool-map.rst +59 −0
  30. tools/bpf/bpftool/Documentation/bpftool-prog.rst +60 −45
  31. tools/bpf/bpftool/Documentation/bpftool.rst +4 −0
  32. tools/bpf/bpftool/Makefile +0 −2
  33. tools/bpf/bpftool/bash-completion/bpftool +1 −30
  34. tools/bpf/bpftool/btf_dumper.c +47 −16
  35. tools/bpf/bpftool/cfg.c +1 −35
  36. tools/bpf/bpftool/cfg.h +2 −36
  37. tools/bpf/bpftool/cgroup.c +1 −1
  38. tools/bpf/bpftool/common.c +30 −39
  39. tools/bpf/bpftool/jit_disasm.c +1 −0
  40. tools/bpf/bpftool/json_writer.c +5 −2
  41. tools/bpf/bpftool/json_writer.h +1 −0
  42. tools/bpf/bpftool/main.c +9 −33
  43. tools/bpf/bpftool/main.h +8 −34
  44. tools/bpf/bpftool/map.c +2 −32
  45. tools/bpf/bpftool/map_perf_ring.c +1 −1
  46. tools/bpf/bpftool/net.c +1 −1
  47. tools/bpf/bpftool/netlink_dumper.c +1 −1
  48. tools/bpf/bpftool/netlink_dumper.h +1 −1
  49. tools/bpf/bpftool/perf.c +1 −1
  50. tools/bpf/bpftool/prog.c +4 −41
  51. tools/bpf/bpftool/tracelog.c +16 −7
  52. tools/bpf/bpftool/xlated_dumper.c +5 −38
  53. tools/bpf/bpftool/xlated_dumper.h +2 −36
  54. tools/include/uapi/linux/bpf.h +12 −1
  55. tools/include/uapi/linux/btf.h +18 −2
  56. tools/lib/bpf/bpf_prog_linfo.c +1 −5
  57. tools/lib/bpf/libbpf.c +1 −0
  58. tools/testing/selftests/bpf/.gitignore +1 −0
  59. tools/testing/selftests/bpf/connect4_prog.c +4 −2
  60. tools/testing/selftests/bpf/connect6_prog.c +4 −2
  61. tools/testing/selftests/bpf/netcnt_prog.c +6 −0
  62. tools/testing/selftests/bpf/test_btf.c +680 −28
  63. tools/testing/selftests/bpf/test_progs.c +4 −4
  64. tools/testing/selftests/bpf/test_verifier.c +354 −37
arch/arm64/net/bpf_jit_comp.c+1−0
@@ -932,6 +932,7 @@ skip_init_ctx: · 931 unmodified lines
932932 prog->jited_len = image_size;
933933
934934 if (!prog->is_func || extra_pass) {
935+ bpf_prog_fill_jited_linfo(prog, ctx.offset);
935936 out_off:
936937 kfree(ctx.offset);
937938 kfree(jit_data);
arch/sparc/net/bpf_jit_comp_64.c+1−0
@@ -1575,6 +1575,7 @@ skip_init_ctx: · 1574 unmodified lines
15751575 prog->jited_len = image_size;
15761576
15771577 if (!prog->is_func || extra_pass) {
1578+ bpf_prog_fill_jited_linfo(prog, ctx.offset);
15781579 out_off:
15791580 kfree(ctx.offset);
15801581 kfree(jit_data);
drivers/net/ethernet/netronome/nfp/bpf/jit.c+10−17
@@ -3052,26 +3052,19 @@ static int jset_imm(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) · 3051 unmodified lines
30523052 {
30533053 const struct bpf_insn *insn = &meta->insn;
30543054 u64 imm = insn->imm; /* sign extend */
3055+ u8 dst_gpr = insn->dst_reg * 2;
30553056 swreg tmp_reg;
30563057
3057− if (!imm) {
3058− meta->skip = true;
3059− return 0;
3060− }
3061−
3062− if (imm & ~0U) {
3063− tmp_reg = ur_load_imm_any(nfp_prog, imm & ~0U, imm_b(nfp_prog));
3064− emit_alu(nfp_prog, reg_none(),
3065− reg_a(insn->dst_reg * 2), ALU_OP_AND, tmp_reg);
3066− emit_br(nfp_prog, BR_BNE, insn->off, 0);
3067− }
3068−
3069− if (imm >> 32) {
3070− tmp_reg = ur_load_imm_any(nfp_prog, imm >> 32, imm_b(nfp_prog));
3058+ tmp_reg = ur_load_imm_any(nfp_prog, imm & ~0U, imm_b(nfp_prog));
3059+ emit_alu(nfp_prog, imm_b(nfp_prog),
3060+ reg_a(dst_gpr), ALU_OP_AND, tmp_reg);
3061+ /* Upper word of the mask can only be 0 or ~0 from sign extension,
3062+ * so either ignore it or OR the whole thing in.
3063+ */
3064+ if (imm >> 32)
30713065 emit_alu(nfp_prog, reg_none(),
3072− reg_a(insn->dst_reg * 2 + 1), ALU_OP_AND, tmp_reg);
3073− emit_br(nfp_prog, BR_BNE, insn->off, 0);
3074− }
3066+ reg_a(dst_gpr + 1), ALU_OP_OR, imm_b(nfp_prog));
3067+ emit_br(nfp_prog, BR_BNE, insn->off, 0);
30753068
30763069 return 0;
30773070 }
include/linux/bpf.h+3−0
@@ -23,6 +23,7 @@ struct bpf_prog; · 22 unmodified lines
2323 struct bpf_map;
2424 struct sock;
2525 struct seq_file;
26+struct btf;
2627 struct btf_type;
2728
2829 /* map is generic key/value storage optionally accesible by eBPF programs */
@@ -52,6 +53,7 @@ struct bpf_map_ops { · 23 unmodified lines
5253 void (*map_seq_show_elem)(struct bpf_map *map, void *key,
5354 struct seq_file *m);
5455 int (*map_check_btf)(const struct bpf_map *map,
56+ const struct btf *btf,
5557 const struct btf_type *key_type,
5658 const struct btf_type *value_type);
5759 };
@@ -126,6 +128,7 @@ static inline bool bpf_map_support_seq_show(const struct bpf_map *map) · 68 unmodified lines
126128 }
127129
128130 int map_check_no_btf(const struct bpf_map *map,
131+ const struct btf *btf,
129132 const struct btf_type *key_type,
130133 const struct btf_type *value_type);
131134
include/linux/bpf_verifier.h+2−0
@@ -38,6 +38,7 @@ enum bpf_reg_liveness { · 37 unmodified lines
3838 REG_LIVE_NONE = 0, /* reg hasn't been read or written this branch */
3939 REG_LIVE_READ, /* reg was read, so we're sensitive to initial value */
4040 REG_LIVE_WRITTEN, /* reg was written first, screening off later reads */
41+ REG_LIVE_DONE = 4, /* liveness won't be updating this register anymore */
4142 };
4243
4344 struct bpf_reg_state {
@@ -224,6 +225,7 @@ struct bpf_verifier_env { · 180 unmodified lines
224225 bool allow_ptr_leaks;
225226 bool seen_direct_write;
226227 struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */
228+ const struct bpf_line_info *prev_linfo;
227229 struct bpf_verifier_log log;
228230 struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 1];
229231 u32 subprog_cnt;
include/linux/btf.h+4−1
@@ -7,6 +7,7 @@ · 6 unmodified lines
77 #include <linux/types.h>
88
99 struct btf;
10+struct btf_member;
1011 struct btf_type;
1112 union bpf_attr;
1213
@@ -46,7 +47,9 @@ void btf_type_seq_show(const struct btf *btf, u32 type_id, void *obj, · 33 unmodified lines
4647 struct seq_file *m);
4748 int btf_get_fd_by_id(u32 id);
4849 u32 btf_id(const struct btf *btf);
49−bool btf_name_offset_valid(const struct btf *btf, u32 offset);
50+bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
51+ const struct btf_member *m,
52+ u32 expected_offset, u32 expected_size);
5053
5154 #ifdef CONFIG_BPF_SYSCALL
5255 const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id);
include/linux/module.h+4−0
@@ -432,6 +432,10 @@ struct module { · 431 unmodified lines
432432 unsigned int num_tracepoints;
433433 tracepoint_ptr_t *tracepoints_ptrs;
434434 #endif
435+#ifdef CONFIG_BPF_EVENTS
436+ unsigned int num_bpf_raw_events;
437+ struct bpf_raw_event_map *bpf_raw_events;
438+#endif
435439 #ifdef HAVE_JUMP_LABEL
436440 struct jump_entry *jump_entries;
437441 unsigned int num_jump_entries;
include/linux/skmsg.h+9−0
@@ -36,6 +36,7 @@ struct sk_msg_sg { · 35 unmodified lines
3636 struct scatterlist data[MAX_MSG_FRAGS + 1];
3737 };
3838
39+/* UAPI in filter.c depends on struct sk_msg_sg being first element. */
3940 struct sk_msg {
4041 struct sk_msg_sg sg;
4142 void *data;
@@ -416,6 +417,14 @@ static inline void sk_psock_put(struct sock *sk, struct sk_psock *psock) · 374 unmodified lines
416417 sk_psock_drop(sk, psock);
417418 }
418419
420+static inline void sk_psock_data_ready(struct sock *sk, struct sk_psock *psock)
421+{
422+ if (psock->parser.enabled)
423+ psock->parser.saved_data_ready(sk);
424+ else
425+ sk->sk_data_ready(sk);
426+}
427+
419428 static inline void psock_set_prog(struct bpf_prog **pprog,
420429 struct bpf_prog *prog)
421430 {
include/linux/socket.h+1−0
@@ -286,6 +286,7 @@ struct ucred { · 285 unmodified lines
286286 #define MSG_NOSIGNAL 0x4000 /* Do not generate SIGPIPE */
287287 #define MSG_MORE 0x8000 /* Sender will send more */
288288 #define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */
289+#define MSG_SENDPAGE_NOPOLICY 0x10000 /* sendpage() internal : do no apply policy */
289290 #define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
290291 #define MSG_BATCH 0x40000 /* sendmmsg(): more messages coming */
291292 #define MSG_EOF MSG_FIN
include/linux/trace_events.h+6−2
@@ -471,7 +471,8 @@ void perf_event_detach_bpf_prog(struct perf_event *event); · 470 unmodified lines
471471 int perf_event_query_prog_array(struct perf_event *event, void __user *info);
472472 int bpf_probe_register(struct bpf_raw_event_map *btp, struct bpf_prog *prog);
473473 int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog);
474−struct bpf_raw_event_map *bpf_find_raw_tracepoint(const char *name);
474+struct bpf_raw_event_map *bpf_get_raw_tracepoint(const char *name);
475+void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp);
475476 int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
476477 u32 *fd_type, const char **buf,
477478 u64 *probe_offset, u64 *probe_addr);
@@ -502,10 +503,13 @@ static inline int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf · 24 unmodified lines
502503 {
503504 return -EOPNOTSUPP;
504505 }
505−static inline struct bpf_raw_event_map *bpf_find_raw_tracepoint(const char *name)
506+static inline struct bpf_raw_event_map *bpf_get_raw_tracepoint(const char *name)
506507 {
507508 return NULL;
508509 }
510+static inline void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp)
511+{
512+}
509513 static inline int bpf_get_perf_event_info(const struct perf_event *event,
510514 u32 *prog_id, u32 *fd_type,
511515 const char **buf, u64 *probe_offset,
include/net/tls.h+9−0
@@ -460,6 +460,15 @@ tls_offload_ctx_tx(const struct tls_context *tls_ctx) · 459 unmodified lines
460460 return (struct tls_offload_context_tx *)tls_ctx->priv_ctx_tx;
461461 }
462462
463+static inline bool tls_sw_has_ctx_tx(const struct sock *sk)
464+{
465+ struct tls_context *ctx = tls_get_ctx(sk);
466+
467+ if (!ctx)
468+ return false;
469+ return !!tls_sw_ctx_tx(ctx);
470+}
471+
463472 static inline struct tls_offload_context_rx *
464473 tls_offload_ctx_rx(const struct tls_context *tls_ctx)
465474 {
include/uapi/linux/bpf.h+12−1
@@ -133,6 +133,14 @@ enum bpf_map_type { · 132 unmodified lines
133133 BPF_MAP_TYPE_STACK,
134134 };
135135
136+/* Note that tracing related programs such as
137+ * BPF_PROG_TYPE_{KPROBE,TRACEPOINT,PERF_EVENT,RAW_TRACEPOINT}
138+ * are not subject to a stable API since kernel internal data
139+ * structures can change from release to release and may
140+ * therefore break existing tracing BPF programs. Tracing BPF
141+ * programs correspond to /a/ specific kernel which is to be
142+ * analyzed, and not /a/ specific kernel /and/ all future ones.
143+ */
136144 enum bpf_prog_type {
137145 BPF_PROG_TYPE_UNSPEC,
138146 BPF_PROG_TYPE_SOCKET_FILTER,
@@ -343,7 +351,7 @@ union bpf_attr { · 204 unmodified lines
343351 __u32 log_level; /* verbosity level of verifier */
344352 __u32 log_size; /* size of user buffer */
345353 __aligned_u64 log_buf; /* user supplied buffer */
346− __u32 kern_version; /* checked when prog_type=kprobe */
354+ __u32 kern_version; /* not used */
347355 __u32 prog_flags;
348356 char prog_name[BPF_OBJ_NAME_LEN];
349357 __u32 prog_ifindex; /* ifindex of netdev to prep for */
@@ -2657,6 +2665,7 @@ struct sk_msg_md { · 2307 unmodified lines
26572665 __u32 local_ip6[4]; /* Stored in network byte order */
26582666 __u32 remote_port; /* Stored in network byte order */
26592667 __u32 local_port; /* stored in host byte order */
2668+ __u32 size; /* Total size of sk_msg */
26602669 };
26612670
26622671 struct sk_reuseport_md {
@@ -2717,6 +2726,8 @@ struct bpf_prog_info { · 54 unmodified lines
27172726 __u32 nr_jited_line_info;
27182727 __u32 line_info_rec_size;
27192728 __u32 jited_line_info_rec_size;
2729+ __u32 nr_prog_tags;
2730+ __aligned_u64 prog_tags;
27202731 } __attribute__((aligned(8)));
27212732
27222733 struct bpf_map_info {
include/uapi/linux/btf.h+18−2
@@ -34,7 +34,9 @@ struct btf_type { · 33 unmodified lines
3434 * bits 0-15: vlen (e.g. # of struct's members)
3535 * bits 16-23: unused
3636 * bits 24-27: kind (e.g. int, ptr, array...etc)
37− * bits 28-31: unused
37+ * bits 28-30: unused
38+ * bit 31: kind_flag, currently used by
39+ * struct, union and fwd
3840 */
3941 __u32 info;
4042 /* "size" is used by INT, ENUM, STRUCT and UNION.
@@ -52,6 +54,7 @@ struct btf_type { · 11 unmodified lines
5254
5355 #define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f)
5456 #define BTF_INFO_VLEN(info) ((info) & 0xffff)
57+#define BTF_INFO_KFLAG(info) ((info) >> 31)
5558
5659 #define BTF_KIND_UNKN 0 /* Unknown */
5760 #define BTF_KIND_INT 1 /* Integer */
@@ -110,9 +113,22 @@ struct btf_array { · 52 unmodified lines
110113 struct btf_member {
111114 __u32 name_off;
112115 __u32 type;
113− __u32 offset; /* offset in bits */
116+ /* If the type info kind_flag is set, the btf_member offset
117+ * contains both member bitfield size and bit offset. The
118+ * bitfield size is set for bitfield members. If the type
119+ * info kind_flag is not set, the offset contains only bit
120+ * offset.
121+ */
122+ __u32 offset;
114123 };
115124
125+/* If the struct/union type info kind_flag is set, the
126+ * following two macros are used to access bitfield_size
127+ * and bit_offset from btf_member.offset.
128+ */
129+#define BTF_MEMBER_BITFIELD_SIZE(val) ((val) >> 24)
130+#define BTF_MEMBER_BIT_OFFSET(val) ((val) & 0xffffff)
131+
116132 /* BTF_KIND_FUNC_PROTO is followed by multiple "struct btf_param".
117133 * The exact number of btf_param is stored in the vlen (of the
118134 * info in "struct btf_type").
kernel/bpf/arraymap.c+1−0
@@ -382,6 +382,7 @@ static void percpu_array_map_seq_show_elem(struct bpf_map *map, void *key, · 381 unmodified lines
382382 }
383383
384384 static int array_map_check_btf(const struct bpf_map *map,
385+ const struct btf *btf,
385386 const struct btf_type *key_type,
386387 const struct btf_type *value_type)
387388 {
kernel/bpf/btf.c+348−45
@@ -164,7 +164,7 @@ · 163 unmodified lines
164164 #define BITS_ROUNDUP_BYTES(bits) \
165165 (BITS_ROUNDDOWN_BYTES(bits) + !!BITS_PER_BYTE_MASKED(bits))
166166
167−#define BTF_INFO_MASK 0x0f00ffff
167+#define BTF_INFO_MASK 0x8f00ffff
168168 #define BTF_INT_MASK 0x0fffffff
169169 #define BTF_TYPE_ID_VALID(type_id) ((type_id) <= BTF_MAX_TYPE)
170170 #define BTF_STR_OFFSET_VALID(name_off) ((name_off) <= BTF_MAX_NAME_OFFSET)
@@ -274,6 +274,10 @@ struct btf_kind_operations { · 103 unmodified lines
274274 const struct btf_type *struct_type,
275275 const struct btf_member *member,
276276 const struct btf_type *member_type);
277+ int (*check_kflag_member)(struct btf_verifier_env *env,
278+ const struct btf_type *struct_type,
279+ const struct btf_member *member,
280+ const struct btf_type *member_type);
277281 void (*log_details)(struct btf_verifier_env *env,
278282 const struct btf_type *t);
279283 void (*seq_show)(const struct btf *btf, const struct btf_type *t,
@@ -419,6 +423,25 @@ static u16 btf_type_vlen(const struct btf_type *t) · 139 unmodified lines
419423 return BTF_INFO_VLEN(t->info);
420424 }
421425
426+static bool btf_type_kflag(const struct btf_type *t)
427+{
428+ return BTF_INFO_KFLAG(t->info);
429+}
430+
431+static u32 btf_member_bit_offset(const struct btf_type *struct_type,
432+ const struct btf_member *member)
433+{
434+ return btf_type_kflag(struct_type) ? BTF_MEMBER_BIT_OFFSET(member->offset)
435+ : member->offset;
436+}
437+
438+static u32 btf_member_bitfield_size(const struct btf_type *struct_type,
439+ const struct btf_member *member)
440+{
441+ return btf_type_kflag(struct_type) ? BTF_MEMBER_BITFIELD_SIZE(member->offset)
442+ : 0;
443+}
444+
422445 static u32 btf_type_int(const struct btf_type *t)
423446 {
424447 return *(u32 *)(t + 1);
@@ -474,7 +497,7 @@ static bool btf_name_valid_identifier(const struct btf *btf, u32 offset) · 49 unmodified lines
474497 return !*src;
475498 }
476499
477−const char *btf_name_by_offset(const struct btf *btf, u32 offset)
500+static const char *__btf_name_by_offset(const struct btf *btf, u32 offset)
478501 {
479502 if (!offset)
480503 return "(anon)";
@@ -484,6 +507,14 @@ const char *btf_name_by_offset(const struct btf *btf, u32 offset) · 3 unmodified lines
484507 return "(invalid-name-offset)";
485508 }
486509
510+const char *btf_name_by_offset(const struct btf *btf, u32 offset)
511+{
512+ if (offset < btf->hdr.str_len)
513+ return &btf->strings[offset];
514+
515+ return NULL;
516+}
517+
487518 const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id)
488519 {
489520 if (type_id > btf->nr_types)
@@ -514,6 +545,47 @@ static bool btf_type_int_is_regular(const struct btf_type *t) · 24 unmodified lines
514545 return true;
515546 }
516547
548+/*
549+ * Check that given struct member is a regular int with expected
550+ * offset and size.
551+ */
552+bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s,
553+ const struct btf_member *m,
554+ u32 expected_offset, u32 expected_size)
555+{
556+ const struct btf_type *t;
557+ u32 id, int_data;
558+ u8 nr_bits;
559+
560+ id = m->type;
561+ t = btf_type_id_size(btf, &id, NULL);
562+ if (!t || !btf_type_is_int(t))
563+ return false;
564+
565+ int_data = btf_type_int(t);
566+ nr_bits = BTF_INT_BITS(int_data);
567+ if (btf_type_kflag(s)) {
568+ u32 bitfield_size = BTF_MEMBER_BITFIELD_SIZE(m->offset);
569+ u32 bit_offset = BTF_MEMBER_BIT_OFFSET(m->offset);
570+
571+ /* if kflag set, int should be a regular int and
572+ * bit offset should be at byte boundary.
573+ */
574+ return !bitfield_size &&
575+ BITS_ROUNDUP_BYTES(bit_offset) == expected_offset &&
576+ BITS_ROUNDUP_BYTES(nr_bits) == expected_size;
577+ }
578+
579+ if (BTF_INT_OFFSET(int_data) ||
580+ BITS_PER_BYTE_MASKED(m->offset) ||
581+ BITS_ROUNDUP_BYTES(m->offset) != expected_offset ||
582+ BITS_PER_BYTE_MASKED(nr_bits) ||
583+ BITS_ROUNDUP_BYTES(nr_bits) != expected_size)
584+ return false;
585+
586+ return true;
587+}
588+
517589 __printf(2, 3) static void __btf_verifier_log(struct bpf_verifier_log *log,
518590 const char *fmt, ...)
519591 {
@@ -554,7 +626,7 @@ __printf(4, 5) static void __btf_verifier_log_type(struct btf_verifier_env *env, · 34 unmodified lines
554626 __btf_verifier_log(log, "[%u] %s %s%s",
555627 env->log_type_id,
556628 btf_kind_str[kind],
557− btf_name_by_offset(btf, t->name_off),
629+ __btf_name_by_offset(btf, t->name_off),
558630 log_details ? " " : "");
559631
560632 if (log_details)
@@ -597,9 +669,17 @@ static void btf_verifier_log_member(struct btf_verifier_env *env, · 36 unmodified lines
597669 if (env->phase != CHECK_META)
598670 btf_verifier_log_type(env, struct_type, NULL);
599671
600− __btf_verifier_log(log, "\t%s type_id=%u bits_offset=%u",
601− btf_name_by_offset(btf, member->name_off),
602− member->type, member->offset);
672+ if (btf_type_kflag(struct_type))
673+ __btf_verifier_log(log,
674+ "\t%s type_id=%u bitfield_size=%u bits_offset=%u",
675+ __btf_name_by_offset(btf, member->name_off),
676+ member->type,
677+ BTF_MEMBER_BITFIELD_SIZE(member->offset),
678+ BTF_MEMBER_BIT_OFFSET(member->offset));
679+ else
680+ __btf_verifier_log(log, "\t%s type_id=%u bits_offset=%u",
681+ __btf_name_by_offset(btf, member->name_off),
682+ member->type, member->offset);
603683
604684 if (fmt && *fmt) {
605685 __btf_verifier_log(log, " ");
@@ -915,6 +995,38 @@ static int btf_df_check_member(struct btf_verifier_env *env, · 309 unmodified lines
915995 return -EINVAL;
916996 }
917997
998+static int btf_df_check_kflag_member(struct btf_verifier_env *env,
999+ const struct btf_type *struct_type,
1000+ const struct btf_member *member,
1001+ const struct btf_type *member_type)
1002+{
1003+ btf_verifier_log_basic(env, struct_type,
1004+ "Unsupported check_kflag_member");
1005+ return -EINVAL;
1006+}
1007+
1008+/* Used for ptr, array and struct/union type members.
1009+ * int, enum and modifier types have their specific callback functions.
1010+ */
1011+static int btf_generic_check_kflag_member(struct btf_verifier_env *env,
1012+ const struct btf_type *struct_type,
1013+ const struct btf_member *member,
1014+ const struct btf_type *member_type)
1015+{
1016+ if (BTF_MEMBER_BITFIELD_SIZE(member->offset)) {
1017+ btf_verifier_log_member(env, struct_type, member,
1018+ "Invalid member bitfield_size");
1019+ return -EINVAL;
1020+ }
1021+
1022+ /* bitfield size is 0, so member->offset represents bit offset only.
1023+ * It is safe to call non kflag check_member variants.
1024+ */
1025+ return btf_type_ops(member_type)->check_member(env, struct_type,
1026+ member,
1027+ member_type);
1028+}
1029+
9181030 static int btf_df_resolve(struct btf_verifier_env *env,
9191031 const struct resolve_vertex *v)
9201032 {
@@ -967,6 +1079,62 @@ static int btf_int_check_member(struct btf_verifier_env *env, · 46 unmodified lines
9671079 return 0;
9681080 }
9691081
1082+static int btf_int_check_kflag_member(struct btf_verifier_env *env,
1083+ const struct btf_type *struct_type,
1084+ const struct btf_member *member,
1085+ const struct btf_type *member_type)
1086+{
1087+ u32 struct_bits_off, nr_bits, nr_int_data_bits, bytes_offset;
1088+ u32 int_data = btf_type_int(member_type);
1089+ u32 struct_size = struct_type->size;
1090+ u32 nr_copy_bits;
1091+
1092+ /* a regular int type is required for the kflag int member */
1093+ if (!btf_type_int_is_regular(member_type)) {
1094+ btf_verifier_log_member(env, struct_type, member,
1095+ "Invalid member base type");
1096+ return -EINVAL;
1097+ }
1098+
1099+ /* check sanity of bitfield size */
1100+ nr_bits = BTF_MEMBER_BITFIELD_SIZE(member->offset);
1101+ struct_bits_off = BTF_MEMBER_BIT_OFFSET(member->offset);
1102+ nr_int_data_bits = BTF_INT_BITS(int_data);
1103+ if (!nr_bits) {
1104+ /* Not a bitfield member, member offset must be at byte
1105+ * boundary.
1106+ */
1107+ if (BITS_PER_BYTE_MASKED(struct_bits_off)) {
1108+ btf_verifier_log_member(env, struct_type, member,
1109+ "Invalid member offset");
1110+ return -EINVAL;
1111+ }
1112+
1113+ nr_bits = nr_int_data_bits;
1114+ } else if (nr_bits > nr_int_data_bits) {
1115+ btf_verifier_log_member(env, struct_type, member,
1116+ "Invalid member bitfield_size");
1117+ return -EINVAL;
1118+ }
1119+
1120+ bytes_offset = BITS_ROUNDDOWN_BYTES(struct_bits_off);
1121+ nr_copy_bits = nr_bits + BITS_PER_BYTE_MASKED(struct_bits_off);
1122+ if (nr_copy_bits > BITS_PER_U64) {
1123+ btf_verifier_log_member(env, struct_type, member,
1124+ "nr_copy_bits exceeds 64");
1125+ return -EINVAL;
1126+ }
1127+
1128+ if (struct_size < bytes_offset ||
1129+ struct_size - bytes_offset < BITS_ROUNDUP_BYTES(nr_copy_bits)) {
1130+ btf_verifier_log_member(env, struct_type, member,
1131+ "Member exceeds struct_size");
1132+ return -EINVAL;
1133+ }
1134+
1135+ return 0;
1136+}
1137+
9701138 static s32 btf_int_check_meta(struct btf_verifier_env *env,
9711139 const struct btf_type *t,
9721140 u32 meta_left)
@@ -986,6 +1154,11 @@ static s32 btf_int_check_meta(struct btf_verifier_env *env, · 13 unmodified lines
9861154 return -EINVAL;
9871155 }
9881156
1157+ if (btf_type_kflag(t)) {
1158+ btf_verifier_log_type(env, t, "Invalid btf_info kind_flag");
1159+ return -EINVAL;
1160+ }
1161+
9891162 int_data = btf_type_int(t);
9901163 if (int_data & ~BTF_INT_MASK) {
9911164 btf_verifier_log_basic(env, t, "Invalid int_data:%x",
@@ -1038,26 +1211,16 @@ static void btf_int_log(struct btf_verifier_env *env, · 46 unmodified lines
10381211 btf_int_encoding_str(BTF_INT_ENCODING(int_data)));
10391212 }
10401213
1041−static void btf_int_bits_seq_show(const struct btf *btf,
1042− const struct btf_type *t,
1043− void *data, u8 bits_offset,
1044− struct seq_file *m)
1214+static void btf_bitfield_seq_show(void *data, u8 bits_offset,
1215+ u8 nr_bits, struct seq_file *m)
10451216 {
10461217 u16 left_shift_bits, right_shift_bits;
1047− u32 int_data = btf_type_int(t);
1048− u8 nr_bits = BTF_INT_BITS(int_data);
1049− u8 total_bits_offset;
10501218 u8 nr_copy_bytes;
10511219 u8 nr_copy_bits;
10521220 u64 print_num;
10531221
1054− /*
1055− * bits_offset is at most 7.
1056− * BTF_INT_OFFSET() cannot exceed 64 bits.
1057− */
1058− total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data);
1059− data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
1060− bits_offset = BITS_PER_BYTE_MASKED(total_bits_offset);
1222+ data += BITS_ROUNDDOWN_BYTES(bits_offset);
1223+ bits_offset = BITS_PER_BYTE_MASKED(bits_offset);
10611224 nr_copy_bits = nr_bits + bits_offset;
10621225 nr_copy_bytes = BITS_ROUNDUP_BYTES(nr_copy_bits);
10631226
@@ -1077,6 +1240,24 @@ static void btf_int_bits_seq_show(const struct btf *btf, · 13 unmodified lines
10771240 seq_printf(m, "0x%llx", print_num);
10781241 }
10791242
1243+
1244+static void btf_int_bits_seq_show(const struct btf *btf,
1245+ const struct btf_type *t,
1246+ void *data, u8 bits_offset,
1247+ struct seq_file *m)
1248+{
1249+ u32 int_data = btf_type_int(t);
1250+ u8 nr_bits = BTF_INT_BITS(int_data);
1251+ u8 total_bits_offset;
1252+
1253+ /*
1254+ * bits_offset is at most 7.
1255+ * BTF_INT_OFFSET() cannot exceed 64 bits.
1256+ */
1257+ total_bits_offset = bits_offset + BTF_INT_OFFSET(int_data);
1258+ btf_bitfield_seq_show(data, total_bits_offset, nr_bits, m);
1259+}
1260+
10801261 static void btf_int_seq_show(const struct btf *btf, const struct btf_type *t,
10811262 u32 type_id, void *data, u8 bits_offset,
10821263 struct seq_file *m)
@@ -1126,6 +1307,7 @@ static const struct btf_kind_operations int_ops = { · 43 unmodified lines
11261307 .check_meta = btf_int_check_meta,
11271308 .resolve = btf_df_resolve,
11281309 .check_member = btf_int_check_member,
1310+ .check_kflag_member = btf_int_check_kflag_member,
11291311 .log_details = btf_int_log,
11301312 .seq_show = btf_int_seq_show,
11311313 };
@@ -1155,6 +1337,31 @@ static int btf_modifier_check_member(struct btf_verifier_env *env, · 23 unmodified lines
11551337 resolved_type);
11561338 }
11571339
1340+static int btf_modifier_check_kflag_member(struct btf_verifier_env *env,
1341+ const struct btf_type *struct_type,
1342+ const struct btf_member *member,
1343+ const struct btf_type *member_type)
1344+{
1345+ const struct btf_type *resolved_type;
1346+ u32 resolved_type_id = member->type;
1347+ struct btf_member resolved_member;
1348+ struct btf *btf = env->btf;
1349+
1350+ resolved_type = btf_type_id_size(btf, &resolved_type_id, NULL);
1351+ if (!resolved_type) {
1352+ btf_verifier_log_member(env, struct_type, member,
1353+ "Invalid member");
1354+ return -EINVAL;
1355+ }
1356+
1357+ resolved_member = *member;
1358+ resolved_member.type = resolved_type_id;
1359+
1360+ return btf_type_ops(resolved_type)->check_kflag_member(env, struct_type,
1361+ &resolved_member,
1362+ resolved_type);
1363+}
1364+
11581365 static int btf_ptr_check_member(struct btf_verifier_env *env,
11591366 const struct btf_type *struct_type,
11601367 const struct btf_member *member,
@@ -1190,6 +1397,11 @@ static int btf_ref_type_check_meta(struct btf_verifier_env *env, · 29 unmodified lines
11901397 return -EINVAL;
11911398 }
11921399
1400+ if (btf_type_kflag(t)) {
1401+ btf_verifier_log_type(env, t, "Invalid btf_info kind_flag");
1402+ return -EINVAL;
1403+ }
1404+
11931405 if (!BTF_TYPE_ID_VALID(t->type)) {
11941406 btf_verifier_log_type(env, t, "Invalid type_id");
11951407 return -EINVAL;
@@ -1343,6 +1555,7 @@ static struct btf_kind_operations modifier_ops = { · 147 unmodified lines
13431555 .check_meta = btf_ref_type_check_meta,
13441556 .resolve = btf_modifier_resolve,
13451557 .check_member = btf_modifier_check_member,
1558+ .check_kflag_member = btf_modifier_check_kflag_member,
13461559 .log_details = btf_ref_type_log,
13471560 .seq_show = btf_modifier_seq_show,
13481561 };
@@ -1351,6 +1564,7 @@ static struct btf_kind_operations ptr_ops = { · 2 unmodified lines
13511564 .check_meta = btf_ref_type_check_meta,
13521565 .resolve = btf_ptr_resolve,
13531566 .check_member = btf_ptr_check_member,
1567+ .check_kflag_member = btf_generic_check_kflag_member,
13541568 .log_details = btf_ref_type_log,
13551569 .seq_show = btf_ptr_seq_show,
13561570 };
@@ -1381,11 +1595,18 @@ static s32 btf_fwd_check_meta(struct btf_verifier_env *env, · 24 unmodified lines
13811595 return 0;
13821596 }
13831597
1598+static void btf_fwd_type_log(struct btf_verifier_env *env,
1599+ const struct btf_type *t)
1600+{
1601+ btf_verifier_log(env, "%s", btf_type_kflag(t) ? "union" : "struct");
1602+}
1603+
13841604 static struct btf_kind_operations fwd_ops = {
13851605 .check_meta = btf_fwd_check_meta,
13861606 .resolve = btf_df_resolve,
13871607 .check_member = btf_df_check_member,
1388− .log_details = btf_ref_type_log,
1608+ .check_kflag_member = btf_df_check_kflag_member,
1609+ .log_details = btf_fwd_type_log,
13891610 .seq_show = btf_df_seq_show,
13901611 };
13911612
@@ -1443,6 +1664,11 @@ static s32 btf_array_check_meta(struct btf_verifier_env *env, · 51 unmodified lines
14431664 return -EINVAL;
14441665 }
14451666
1667+ if (btf_type_kflag(t)) {
1668+ btf_verifier_log_type(env, t, "Invalid btf_info kind_flag");
1669+ return -EINVAL;
1670+ }
1671+
14461672 if (t->size) {
14471673 btf_verifier_log_type(env, t, "size != 0");
14481674 return -EINVAL;
@@ -1566,6 +1792,7 @@ static struct btf_kind_operations array_ops = { · 117 unmodified lines
15661792 .check_meta = btf_array_check_meta,
15671793 .resolve = btf_array_resolve,
15681794 .check_member = btf_array_check_member,
1795+ .check_kflag_member = btf_generic_check_kflag_member,
15691796 .log_details = btf_array_log,
15701797 .seq_show = btf_array_seq_show,
15711798 };
@@ -1604,6 +1831,7 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, · 32 unmodified lines
16041831 u32 meta_needed, last_offset;
16051832 struct btf *btf = env->btf;
16061833 u32 struct_size = t->size;
1834+ u32 offset;
16071835 u16 i;
16081836
16091837 meta_needed = btf_type_vlen(t) * sizeof(*member);
@@ -1645,7 +1873,8 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, · 35 unmodified lines
16451873 return -EINVAL;
16461874 }
16471875
1648− if (is_union && member->offset) {
1876+ offset = btf_member_bit_offset(t, member);
1877+ if (is_union && offset) {
16491878 btf_verifier_log_member(env, t, member,
16501879 "Invalid member bits_offset");
16511880 return -EINVAL;
@@ -1655,20 +1884,20 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env, · 3 unmodified lines
16551884 * ">" instead of ">=" because the last member could be
16561885 * "char a[0];"
16571886 */
1658− if (last_offset > member->offset) {
1887+ if (last_offset > offset) {
16591888 btf_verifier_log_member(env, t, member,
16601889 "Invalid member bits_offset");
16611890 return -EINVAL;
16621891 }
16631892
1664− if (BITS_ROUNDUP_BYTES(member->offset) > struct_size) {
1893+ if (BITS_ROUNDUP_BYTES(offset) > struct_size) {
16651894 btf_verifier_log_member(env, t, member,
16661895 "Member bits_offset exceeds its struct size");
16671896 return -EINVAL;
16681897 }
16691898
16701899 btf_verifier_log_member(env, t, member, NULL);
1671− last_offset = member->offset;
1900+ last_offset = offset;
16721901 }
16731902
16741903 return meta_needed;
@@ -1698,9 +1927,14 @@ static int btf_struct_resolve(struct btf_verifier_env *env, · 23 unmodified lines
16981927
16991928 last_member_type = btf_type_by_id(env->btf,
17001929 last_member_type_id);
1701− err = btf_type_ops(last_member_type)->check_member(env, v->t,
1702− last_member,
1703− last_member_type);
1930+ if (btf_type_kflag(v->t))
1931+ err = btf_type_ops(last_member_type)->check_kflag_member(env, v->t,
1932+ last_member,
1933+ last_member_type);
1934+ else
1935+ err = btf_type_ops(last_member_type)->check_member(env, v->t,
1936+ last_member,
1937+ last_member_type);
17041938 if (err)
17051939 return err;
17061940 }
@@ -1722,9 +1956,14 @@ static int btf_struct_resolve(struct btf_verifier_env *env, · 15 unmodified lines
17221956 return env_stack_push(env, member_type, member_type_id);
17231957 }
17241958
1725− err = btf_type_ops(member_type)->check_member(env, v->t,
1726− member,
1727− member_type);
1959+ if (btf_type_kflag(v->t))
1960+ err = btf_type_ops(member_type)->check_kflag_member(env, v->t,
1961+ member,
1962+ member_type);
1963+ else
1964+ err = btf_type_ops(member_type)->check_member(env, v->t,
1965+ member,
1966+ member_type);
17281967 if (err)
17291968 return err;
17301969 }
@@ -1752,17 +1991,26 @@ static void btf_struct_seq_show(const struct btf *btf, const struct btf_type *t, · 21 unmodified lines
17521991 for_each_member(i, t, member) {
17531992 const struct btf_type *member_type = btf_type_by_id(btf,
17541993 member->type);
1755− u32 member_offset = member->offset;
1756− u32 bytes_offset = BITS_ROUNDDOWN_BYTES(member_offset);
1757− u8 bits8_offset = BITS_PER_BYTE_MASKED(member_offset);
17581994 const struct btf_kind_operations *ops;
1995+ u32 member_offset, bitfield_size;
1996+ u32 bytes_offset;
1997+ u8 bits8_offset;
17591998
17601999 if (i)
17612000 seq_puts(m, seq);
17622001
1763− ops = btf_type_ops(member_type);
1764− ops->seq_show(btf, member_type, member->type,
1765− data + bytes_offset, bits8_offset, m);
2002+ member_offset = btf_member_bit_offset(t, member);
2003+ bitfield_size = btf_member_bitfield_size(t, member);
2004+ if (bitfield_size) {
2005+ btf_bitfield_seq_show(data, member_offset,
2006+ bitfield_size, m);
2007+ } else {
2008+ bytes_offset = BITS_ROUNDDOWN_BYTES(member_offset);
2009+ bits8_offset = BITS_PER_BYTE_MASKED(member_offset);
2010+ ops = btf_type_ops(member_type);
2011+ ops->seq_show(btf, member_type, member->type,
2012+ data + bytes_offset, bits8_offset, m);
2013+ }
17662014 }
17672015 seq_puts(m, "}");
17682016 }
@@ -1771,6 +2019,7 @@ static struct btf_kind_operations struct_ops = { · 2 unmodified lines
17712019 .check_meta = btf_struct_check_meta,
17722020 .resolve = btf_struct_resolve,
17732021 .check_member = btf_struct_check_member,
2022+ .check_kflag_member = btf_generic_check_kflag_member,
17742023 .log_details = btf_struct_log,
17752024 .seq_show = btf_struct_seq_show,
17762025 };
@@ -1800,6 +2049,41 @@ static int btf_enum_check_member(struct btf_verifier_env *env, · 23 unmodified lines
18002049 return 0;
18012050 }
18022051
2052+static int btf_enum_check_kflag_member(struct btf_verifier_env *env,
2053+ const struct btf_type *struct_type,
2054+ const struct btf_member *member,
2055+ const struct btf_type *member_type)
2056+{
2057+ u32 struct_bits_off, nr_bits, bytes_end, struct_size;
2058+ u32 int_bitsize = sizeof(int) * BITS_PER_BYTE;
2059+
2060+ struct_bits_off = BTF_MEMBER_BIT_OFFSET(member->offset);
2061+ nr_bits = BTF_MEMBER_BITFIELD_SIZE(member->offset);
2062+ if (!nr_bits) {
2063+ if (BITS_PER_BYTE_MASKED(struct_bits_off)) {
2064+ btf_verifier_log_member(env, struct_type, member,
2065+ "Member is not byte aligned");
2066+ return -EINVAL;
2067+ }
2068+
2069+ nr_bits = int_bitsize;
2070+ } else if (nr_bits > int_bitsize) {
2071+ btf_verifier_log_member(env, struct_type, member,
2072+ "Invalid member bitfield_size");
2073+ return -EINVAL;
2074+ }
2075+
2076+ struct_size = struct_type->size;
2077+ bytes_end = BITS_ROUNDUP_BYTES(struct_bits_off + nr_bits);
2078+ if (struct_size < bytes_end) {
2079+ btf_verifier_log_member(env, struct_type, member,
2080+ "Member exceeds struct_size");
2081+ return -EINVAL;
2082+ }
2083+
2084+ return 0;
2085+}
2086+
18032087 static s32 btf_enum_check_meta(struct btf_verifier_env *env,
18042088 const struct btf_type *t,
18052089 u32 meta_left)
@@ -1819,6 +2103,11 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env, · 13 unmodified lines
18192103 return -EINVAL;
18202104 }
18212105
2106+ if (btf_type_kflag(t)) {
2107+ btf_verifier_log_type(env, t, "Invalid btf_info kind_flag");
2108+ return -EINVAL;
2109+ }
2110+
18222111 if (t->size != sizeof(int)) {
18232112 btf_verifier_log_type(env, t, "Expected size:%zu",
18242113 sizeof(int));
@@ -1850,7 +2139,7 @@ static s32 btf_enum_check_meta(struct btf_verifier_env *env, · 25 unmodified lines
18502139
18512140
18522141 btf_verifier_log(env, "\t%s val=%d\n",
1853− btf_name_by_offset(btf, enums[i].name_off),
2142+ __btf_name_by_offset(btf, enums[i].name_off),
18542143 enums[i].val);
18552144 }
18562145
@@ -1874,7 +2163,8 @@ static void btf_enum_seq_show(const struct btf *btf, const struct btf_type *t, · 17 unmodified lines
18742163 for (i = 0; i < nr_enums; i++) {
18752164 if (v == enums[i].val) {
18762165 seq_printf(m, "%s",
1877− btf_name_by_offset(btf, enums[i].name_off));
2166+ __btf_name_by_offset(btf,
2167+ enums[i].name_off));
18782168 return;
18792169 }
18802170 }
@@ -1886,6 +2176,7 @@ static struct btf_kind_operations enum_ops = { · 5 unmodified lines
18862176 .check_meta = btf_enum_check_meta,
18872177 .resolve = btf_df_resolve,
18882178 .check_member = btf_enum_check_member,
2179+ .check_kflag_member = btf_enum_check_kflag_member,
18892180 .log_details = btf_enum_log,
18902181 .seq_show = btf_enum_seq_show,
18912182 };
@@ -1908,6 +2199,11 @@ static s32 btf_func_proto_check_meta(struct btf_verifier_env *env, · 16 unmodified lines
19082199 return -EINVAL;
19092200 }
19102201
2202+ if (btf_type_kflag(t)) {
2203+ btf_verifier_log_type(env, t, "Invalid btf_info kind_flag");
2204+ return -EINVAL;
2205+ }
2206+
19112207 btf_verifier_log_type(env, t, NULL);
19122208
19132209 return meta_needed;
@@ -1932,20 +2228,20 @@ static void btf_func_proto_log(struct btf_verifier_env *env, · 18 unmodified lines
19322228 }
19332229
19342230 btf_verifier_log(env, "%u %s", args[0].type,
1935− btf_name_by_offset(env->btf,
1936− args[0].name_off));
2231+ __btf_name_by_offset(env->btf,
2232+ args[0].name_off));
19372233 for (i = 1; i < nr_args - 1; i++)
19382234 btf_verifier_log(env, ", %u %s", args[i].type,
1939− btf_name_by_offset(env->btf,
1940− args[i].name_off));
2235+ __btf_name_by_offset(env->btf,
2236+ args[i].name_off));
19412237
19422238 if (nr_args > 1) {
19432239 const struct btf_param *last_arg = &args[nr_args - 1];
19442240
19452241 if (last_arg->type)
19462242 btf_verifier_log(env, ", %u %s", last_arg->type,
1947− btf_name_by_offset(env->btf,
1948− last_arg->name_off));
2243+ __btf_name_by_offset(env->btf,
2244+ last_arg->name_off));
19492245 else
19502246 btf_verifier_log(env, ", vararg");
19512247 }
@@ -1967,6 +2263,7 @@ static struct btf_kind_operations func_proto_ops = { · 15 unmodified lines
19672263 * Hence, there is no btf_func_check_member().
19682264 */
19692265 .check_member = btf_df_check_member,
2266+ .check_kflag_member = btf_df_check_kflag_member,
19702267 .log_details = btf_func_proto_log,
19712268 .seq_show = btf_df_seq_show,
19722269 };
@@ -1986,6 +2283,11 @@ static s32 btf_func_check_meta(struct btf_verifier_env *env, · 13 unmodified lines
19862283 return -EINVAL;
19872284 }
19882285
2286+ if (btf_type_kflag(t)) {
2287+ btf_verifier_log_type(env, t, "Invalid btf_info kind_flag");
2288+ return -EINVAL;
2289+ }
2290+
19892291 btf_verifier_log_type(env, t, NULL);
19902292
19912293 return 0;
@@ -1995,6 +2297,7 @@ static struct btf_kind_operations func_ops = { · 3 unmodified lines
19952297 .check_meta = btf_func_check_meta,
19962298 .resolve = btf_df_resolve,
19972299 .check_member = btf_df_check_member,
2300+ .check_kflag_member = btf_df_check_kflag_member,
19982301 .log_details = btf_ref_type_log,
19992302 .seq_show = btf_df_seq_show,
20002303 };
kernel/bpf/cpumap.c+1−1
@@ -183,7 +183,7 @@ static struct sk_buff *cpu_map_build_skb(struct bpf_cpu_map_entry *rcpu, · 182 unmodified lines
183183 * is not at a fixed memory location, with mixed length
184184 * packets, which is bad for cache-line hotness.
185185 */
186− frame_size = SKB_DATA_ALIGN(xdpf->len) + xdpf->headroom +
186+ frame_size = SKB_DATA_ALIGN(xdpf->len + xdpf->headroom) +
187187 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
188188
189189 pkt_data_start = xdpf->data - xdpf->headroom;
kernel/bpf/local_storage.c+83−1
@@ -1,11 +1,13 @@
11 //SPDX-License-Identifier: GPL-2.0
22 #include <linux/bpf-cgroup.h>
33 #include <linux/bpf.h>
4+#include <linux/btf.h>
45 #include <linux/bug.h>
56 #include <linux/filter.h>
67 #include <linux/mm.h>
78 #include <linux/rbtree.h>
89 #include <linux/slab.h>
10+#include <uapi/linux/btf.h>
911
1012 DEFINE_PER_CPU(struct bpf_cgroup_storage*, bpf_cgroup_storage[MAX_BPF_CGROUP_STORAGE_TYPE]);
1113
@@ -308,6 +310,85 @@ static int cgroup_storage_delete_elem(struct bpf_map *map, void *key) · 296 unmodified lines
308310 return -EINVAL;
309311 }
310312
313+static int cgroup_storage_check_btf(const struct bpf_map *map,
314+ const struct btf *btf,
315+ const struct btf_type *key_type,
316+ const struct btf_type *value_type)
317+{
318+ struct btf_member *m;
319+ u32 offset, size;
320+
321+ /* Key is expected to be of struct bpf_cgroup_storage_key type,
322+ * which is:
323+ * struct bpf_cgroup_storage_key {
324+ * __u64 cgroup_inode_id;
325+ * __u32 attach_type;
326+ * };
327+ */
328+
329+ /*
330+ * Key_type must be a structure with two fields.
331+ */
332+ if (BTF_INFO_KIND(key_type->info) != BTF_KIND_STRUCT ||
333+ BTF_INFO_VLEN(key_type->info) != 2)
334+ return -EINVAL;
335+
336+ /*
337+ * The first field must be a 64 bit integer at 0 offset.
338+ */
339+ m = (struct btf_member *)(key_type + 1);
340+ size = FIELD_SIZEOF(struct bpf_cgroup_storage_key, cgroup_inode_id);
341+ if (!btf_member_is_reg_int(btf, key_type, m, 0, size))
342+ return -EINVAL;
343+
344+ /*
345+ * The second field must be a 32 bit integer at 64 bit offset.
346+ */
347+ m++;
348+ offset = offsetof(struct bpf_cgroup_storage_key, attach_type);
349+ size = FIELD_SIZEOF(struct bpf_cgroup_storage_key, attach_type);
350+ if (!btf_member_is_reg_int(btf, key_type, m, offset, size))
351+ return -EINVAL;
352+
353+ return 0;
354+}
355+
356+static void cgroup_storage_seq_show_elem(struct bpf_map *map, void *_key,
357+ struct seq_file *m)
358+{
359+ enum bpf_cgroup_storage_type stype = cgroup_storage_type(map);
360+ struct bpf_cgroup_storage_key *key = _key;
361+ struct bpf_cgroup_storage *storage;
362+ int cpu;
363+
364+ rcu_read_lock();
365+ storage = cgroup_storage_lookup(map_to_storage(map), key, false);
366+ if (!storage) {
367+ rcu_read_unlock();
368+ return;
369+ }
370+
371+ btf_type_seq_show(map->btf, map->btf_key_type_id, key, m);
372+ stype = cgroup_storage_type(map);
373+ if (stype == BPF_CGROUP_STORAGE_SHARED) {
374+ seq_puts(m, ": ");
375+ btf_type_seq_show(map->btf, map->btf_value_type_id,
376+ &READ_ONCE(storage->buf)->data[0], m);
377+ seq_puts(m, "\n");
378+ } else {
379+ seq_puts(m, ": {\n");
380+ for_each_possible_cpu(cpu) {
381+ seq_printf(m, "\tcpu%d: ", cpu);
382+ btf_type_seq_show(map->btf, map->btf_value_type_id,
383+ per_cpu_ptr(storage->percpu_buf, cpu),
384+ m);
385+ seq_puts(m, "\n");
386+ }
387+ seq_puts(m, "}\n");
388+ }
389+ rcu_read_unlock();
390+}
391+
311392 const struct bpf_map_ops cgroup_storage_map_ops = {
312393 .map_alloc = cgroup_storage_map_alloc,
313394 .map_free = cgroup_storage_map_free,
@@ -315,7 +396,8 @@ const struct bpf_map_ops cgroup_storage_map_ops = { · 1 unmodified line
315396 .map_lookup_elem = cgroup_storage_lookup_elem,
316397 .map_update_elem = cgroup_storage_update_elem,
317398 .map_delete_elem = cgroup_storage_delete_elem,
318− .map_check_btf = map_check_no_btf,
399+ .map_check_btf = cgroup_storage_check_btf,
400+ .map_seq_show_elem = cgroup_storage_seq_show_elem,
319401 };
320402
321403 int bpf_cgroup_storage_assign(struct bpf_prog *prog, struct bpf_map *_map)
kernel/bpf/lpm_trie.c+1−0
@@ -728,6 +728,7 @@ free_stack: · 727 unmodified lines
728728 }
729729
730730 static int trie_check_btf(const struct bpf_map *map,
731+ const struct btf *btf,
731732 const struct btf_type *key_type,
732733 const struct btf_type *value_type)
733734 {
kernel/bpf/syscall.c+44−36
@@ -456,6 +456,7 @@ static int bpf_obj_name_cpy(char *dst, const char *src) · 455 unmodified lines
456456 }
457457
458458 int map_check_no_btf(const struct bpf_map *map,
459+ const struct btf *btf,
459460 const struct btf_type *key_type,
460461 const struct btf_type *value_type)
461462 {
@@ -478,7 +479,7 @@ static int map_check_btf(const struct bpf_map *map, const struct btf *btf, · 16 unmodified lines
478479 return -EINVAL;
479480
480481 if (map->ops->map_check_btf)
481− ret = map->ops->map_check_btf(map, key_type, value_type);
482+ ret = map->ops->map_check_btf(map, btf, key_type, value_type);
482483
483484 return ret;
484485 }
@@ -1472,11 +1473,6 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr) · 987 unmodified lines
14721473
14731474 if (attr->insn_cnt == 0 || attr->insn_cnt > BPF_MAXINSNS)
14741475 return -E2BIG;
1475−
1476− if (type == BPF_PROG_TYPE_KPROBE &&
1477− attr->kern_version != LINUX_VERSION_CODE)
1478− return -EINVAL;
1479−
14801476 if (type != BPF_PROG_TYPE_SOCKET_FILTER &&
14811477 type != BPF_PROG_TYPE_CGROUP_SKB &&
14821478 !capable(CAP_SYS_ADMIN))
@@ -1608,6 +1604,7 @@ static int bpf_raw_tracepoint_release(struct inode *inode, struct file *filp) · 125 unmodified lines
16081604 bpf_probe_unregister(raw_tp->btp, raw_tp->prog);
16091605 bpf_prog_put(raw_tp->prog);
16101606 }
1607+ bpf_put_raw_tracepoint(raw_tp->btp);
16111608 kfree(raw_tp);
16121609 return 0;
16131610 }
@@ -1633,13 +1630,15 @@ static int bpf_raw_tracepoint_open(const union bpf_attr *attr) · 19 unmodified lines
16331630 return -EFAULT;
16341631 tp_name[sizeof(tp_name) - 1] = 0;
16351632
1636− btp = bpf_find_raw_tracepoint(tp_name);
1633+ btp = bpf_get_raw_tracepoint(tp_name);
16371634 if (!btp)
16381635 return -ENOENT;
16391636
16401637 raw_tp = kzalloc(sizeof(*raw_tp), GFP_USER);
1641− if (!raw_tp)
1642− return -ENOMEM;
1638+ if (!raw_tp) {
1639+ err = -ENOMEM;
1640+ goto out_put_btp;
1641+ }
16431642 raw_tp->btp = btp;
16441643
16451644 prog = bpf_prog_get_type(attr->raw_tracepoint.prog_fd,
@@ -1667,6 +1666,8 @@ out_put_prog: · 21 unmodified lines
16671666 bpf_prog_put(prog);
16681667 out_free_tp:
16691668 kfree(raw_tp);
1669+out_put_btp:
1670+ bpf_put_raw_tracepoint(btp);
16701671 return err;
16711672 }
16721673
@@ -2031,13 +2032,6 @@ static struct bpf_insn *bpf_insn_prepare_dump(const struct bpf_prog *prog) · 358 unmodified lines
20312032 insns[i + 1].imm = 0;
20322033 continue;
20332034 }
2034−
2035− if (!bpf_dump_raw_ok() &&
2036− imm == (unsigned long)prog->aux) {
2037− insns[i].imm = 0;
2038− insns[i + 1].imm = 0;
2039− continue;
2040− }
20412035 }
20422036
20432037 return insns;
@@ -2271,33 +2265,25 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, · 227 unmodified lines
22712265 ulen = info.nr_func_info;
22722266 info.nr_func_info = prog->aux->func_info_cnt;
22732267 if (info.nr_func_info && ulen) {
2274− if (bpf_dump_raw_ok()) {
2275− char __user *user_finfo;
2268+ char __user *user_finfo;
22762269
2277− user_finfo = u64_to_user_ptr(info.func_info);
2278− ulen = min_t(u32, info.nr_func_info, ulen);
2279− if (copy_to_user(user_finfo, prog->aux->func_info,
2280− info.func_info_rec_size * ulen))
2281− return -EFAULT;
2282− } else {
2283− info.func_info = 0;
2284− }
2270+ user_finfo = u64_to_user_ptr(info.func_info);
2271+ ulen = min_t(u32, info.nr_func_info, ulen);
2272+ if (copy_to_user(user_finfo, prog->aux->func_info,
2273+ info.func_info_rec_size * ulen))
2274+ return -EFAULT;
22852275 }
22862276
22872277 ulen = info.nr_line_info;
22882278 info.nr_line_info = prog->aux->nr_linfo;
22892279 if (info.nr_line_info && ulen) {
2290− if (bpf_dump_raw_ok()) {
2291− __u8 __user *user_linfo;
2280+ __u8 __user *user_linfo;
22922281
2293− user_linfo = u64_to_user_ptr(info.line_info);
2294− ulen = min_t(u32, info.nr_line_info, ulen);
2295− if (copy_to_user(user_linfo, prog->aux->linfo,
2296− info.line_info_rec_size * ulen))
2297− return -EFAULT;
2298− } else {
2299− info.line_info = 0;
2300− }
2282+ user_linfo = u64_to_user_ptr(info.line_info);
2283+ ulen = min_t(u32, info.nr_line_info, ulen);
2284+ if (copy_to_user(user_linfo, prog->aux->linfo,
2285+ info.line_info_rec_size * ulen))
2286+ return -EFAULT;
23012287 }
23022288
23032289 ulen = info.nr_jited_line_info;
@@ -2322,6 +2308,28 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, · 18 unmodified lines
23222308 }
23232309 }
23242310
2311+ ulen = info.nr_prog_tags;
2312+ info.nr_prog_tags = prog->aux->func_cnt ? : 1;
2313+ if (ulen) {
2314+ __u8 __user (*user_prog_tags)[BPF_TAG_SIZE];
2315+ u32 i;
2316+
2317+ user_prog_tags = u64_to_user_ptr(info.prog_tags);
2318+ ulen = min_t(u32, info.nr_prog_tags, ulen);
2319+ if (prog->aux->func_cnt) {
2320+ for (i = 0; i < ulen; i++) {
2321+ if (copy_to_user(user_prog_tags[i],
2322+ prog->aux->func[i]->tag,
2323+ BPF_TAG_SIZE))
2324+ return -EFAULT;
2325+ }
2326+ } else {
2327+ if (copy_to_user(user_prog_tags[0],
2328+ prog->tag, BPF_TAG_SIZE))
2329+ return -EFAULT;
2330+ }
2331+ }
2332+
23252333 done:
23262334 if (copy_to_user(uinfo, &info, info_len) ||
23272335 put_user(info_len, &uattr->info.info_len))
kernel/bpf/verifier.c+224−17
@@ -26,6 +26,7 @@ · 25 unmodified lines
2626 #include <linux/bsearch.h>
2727 #include <linux/sort.h>
2828 #include <linux/perf_event.h>
29+#include <linux/ctype.h>
2930
3031 #include "disasm.h"
3132
@@ -216,6 +217,27 @@ struct bpf_call_arg_meta { · 184 unmodified lines
216217
217218 static DEFINE_MUTEX(bpf_verifier_lock);
218219
220+static const struct bpf_line_info *
221+find_linfo(const struct bpf_verifier_env *env, u32 insn_off)
222+{
223+ const struct bpf_line_info *linfo;
224+ const struct bpf_prog *prog;
225+ u32 i, nr_linfo;
226+
227+ prog = env->prog;
228+ nr_linfo = prog->aux->nr_linfo;
229+
230+ if (!nr_linfo || insn_off >= prog->len)
231+ return NULL;
232+
233+ linfo = prog->aux->linfo;
234+ for (i = 1; i < nr_linfo; i++)
235+ if (insn_off < linfo[i].insn_off)
236+ break;
237+
238+ return &linfo[i - 1];
239+}
240+
219241 void bpf_verifier_vlog(struct bpf_verifier_log *log, const char *fmt,
220242 va_list args)
221243 {
@@ -266,6 +288,42 @@ __printf(2, 3) static void verbose(void *private_data, const char *fmt, ...) · 44 unmodified lines
266288 va_end(args);
267289 }
268290
291+static const char *ltrim(const char *s)
292+{
293+ while (isspace(*s))
294+ s++;
295+
296+ return s;
297+}
298+
299+__printf(3, 4) static void verbose_linfo(struct bpf_verifier_env *env,
300+ u32 insn_off,
301+ const char *prefix_fmt, ...)
302+{
303+ const struct bpf_line_info *linfo;
304+
305+ if (!bpf_verifier_log_needed(&env->log))
306+ return;
307+
308+ linfo = find_linfo(env, insn_off);
309+ if (!linfo || linfo == env->prev_linfo)
310+ return;
311+
312+ if (prefix_fmt) {
313+ va_list args;
314+
315+ va_start(args, prefix_fmt);
316+ bpf_verifier_vlog(&env->log, prefix_fmt, args);
317+ va_end(args);
318+ }
319+
320+ verbose(env, "%s\n",
321+ ltrim(btf_name_by_offset(env->prog->aux->btf,
322+ linfo->line_off)));
323+
324+ env->prev_linfo = linfo;
325+}
326+
269327 static bool type_is_pkt_pointer(enum bpf_reg_type type)
270328 {
271329 return type == PTR_TO_PACKET ||
@@ -339,12 +397,14 @@ static char slot_type_char[] = { · 67 unmodified lines
339397 static void print_liveness(struct bpf_verifier_env *env,
340398 enum bpf_reg_liveness live)
341399 {
342− if (live & (REG_LIVE_READ | REG_LIVE_WRITTEN))
400+ if (live & (REG_LIVE_READ | REG_LIVE_WRITTEN | REG_LIVE_DONE))
343401 verbose(env, "_");
344402 if (live & REG_LIVE_READ)
345403 verbose(env, "r");
346404 if (live & REG_LIVE_WRITTEN)
347405 verbose(env, "w");
406+ if (live & REG_LIVE_DONE)
407+ verbose(env, "D");
348408 }
349409
350410 static struct bpf_func_state *func(struct bpf_verifier_env *env,
@@ -1074,6 +1134,12 @@ static int mark_reg_read(struct bpf_verifier_env *env, · 723 unmodified lines
10741134 /* if read wasn't screened by an earlier write ... */
10751135 if (writes && state->live & REG_LIVE_WRITTEN)
10761136 break;
1137+ if (parent->live & REG_LIVE_DONE) {
1138+ verbose(env, "verifier BUG type %s var_off %lld off %d\n",
1139+ reg_type_str[parent->type],
1140+ parent->var_off.value, parent->off);
1141+ return -EFAULT;
1142+ }
10771143 /* ... then we depend on parent's value */
10781144 parent->live |= REG_LIVE_READ;
10791145 state = parent;
@@ -1220,6 +1286,10 @@ static int check_stack_write(struct bpf_verifier_env *env, · 140 unmodified lines
12201286
12211287 /* regular write of data into stack destroys any spilled ptr */
12221288 state->stack[spi].spilled_ptr.type = NOT_INIT;
1289+ /* Mark slots as STACK_MISC if they belonged to spilled ptr. */
1290+ if (state->stack[spi].slot_type[0] == STACK_SPILL)
1291+ for (i = 0; i < BPF_REG_SIZE; i++)
1292+ state->stack[spi].slot_type[i] = STACK_MISC;
12231293
12241294 /* only mark the slot as written if all 8 bytes were written
12251295 * otherwise read propagation may incorrectly stop too soon
@@ -1237,6 +1307,7 @@ static int check_stack_write(struct bpf_verifier_env *env, · 11 unmodified lines
12371307 register_is_null(&cur->regs[value_regno]))
12381308 type = STACK_ZERO;
12391309
1310+ /* Mark slots affected by this stack write. */
12401311 for (i = 0; i < size; i++)
12411312 state->stack[spi].slot_type[(slot - i) % BPF_REG_SIZE] =
12421313 type;
@@ -3788,6 +3859,12 @@ static int is_branch_taken(struct bpf_reg_state *reg, u64 val, u8 opcode) · 2545 unmodified lines
37883859 if (tnum_is_const(reg->var_off))
37893860 return !tnum_equals_const(reg->var_off, val);
37903861 break;
3862+ case BPF_JSET:
3863+ if ((~reg->var_off.mask & reg->var_off.value) & val)
3864+ return 1;
3865+ if (!((reg->var_off.mask | reg->var_off.value) & val))
3866+ return 0;
3867+ break;
37913868 case BPF_JGT:
37923869 if (reg->umin_value > val)
37933870 return 1;
@@ -3872,6 +3949,13 @@ static void reg_set_min_max(struct bpf_reg_state *true_reg, · 78 unmodified lines
38723949 */
38733950 __mark_reg_known(false_reg, val);
38743951 break;
3952+ case BPF_JSET:
3953+ false_reg->var_off = tnum_and(false_reg->var_off,
3954+ tnum_const(~val));
3955+ if (is_power_of_2(val))
3956+ true_reg->var_off = tnum_or(true_reg->var_off,
3957+ tnum_const(val));
3958+ break;
38753959 case BPF_JGT:
38763960 false_reg->umax_value = min(false_reg->umax_value, val);
38773961 true_reg->umin_value = max(true_reg->umin_value, val + 1);
@@ -3944,6 +4028,13 @@ static void reg_set_min_max_inv(struct bpf_reg_state *true_reg, · 66 unmodified lines
39444028 */
39454029 __mark_reg_known(false_reg, val);
39464030 break;
4031+ case BPF_JSET:
4032+ false_reg->var_off = tnum_and(false_reg->var_off,
4033+ tnum_const(~val));
4034+ if (is_power_of_2(val))
4035+ true_reg->var_off = tnum_or(true_reg->var_off,
4036+ tnum_const(val));
4037+ break;
39474038 case BPF_JGT:
39484039 true_reg->umax_value = min(true_reg->umax_value, val - 1);
39494040 false_reg->umin_value = max(false_reg->umin_value, val);
@@ -4561,6 +4652,7 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env) · 611 unmodified lines
45614652 return 0;
45624653
45634654 if (w < 0 || w >= env->prog->len) {
4655+ verbose_linfo(env, t, "%d: ", t);
45644656 verbose(env, "jump out of range from insn %d to %d\n", t, w);
45654657 return -EINVAL;
45664658 }
@@ -4578,6 +4670,8 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env) · 11 unmodified lines
45784670 insn_stack[cur_stack++] = w;
45794671 return 1;
45804672 } else if ((insn_state[w] & 0xF0) == DISCOVERED) {
4673+ verbose_linfo(env, t, "%d: ", t);
4674+ verbose_linfo(env, w, "%d: ", w);
45814675 verbose(env, "back-edge from insn %d to %d\n", t, w);
45824676 return -EINVAL;
45834677 } else if (insn_state[w] == EXPLORED) {
@@ -4600,10 +4694,6 @@ static int check_cfg(struct bpf_verifier_env *env) · 16 unmodified lines
46004694 int ret = 0;
46014695 int i, t;
46024696
4603− ret = check_subprogs(env);
4604− if (ret < 0)
4605− return ret;
4606−
46074697 insn_state = kcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
46084698 if (!insn_state)
46094699 return -ENOMEM;
@@ -4910,8 +5000,16 @@ static int check_btf_line(struct bpf_verifier_env *env, · 300 unmodified lines
49105000 goto err_free;
49115001 }
49125002
4913− if (!btf_name_offset_valid(btf, linfo[i].line_off) ||
4914− !btf_name_offset_valid(btf, linfo[i].file_name_off)) {
5003+ if (!prog->insnsi[linfo[i].insn_off].code) {
5004+ verbose(env,
5005+ "Invalid insn code at line_info[%u].insn_off\n",
5006+ i);
5007+ err = -EINVAL;
5008+ goto err_free;
5009+ }
5010+
5011+ if (!btf_name_by_offset(btf, linfo[i].line_off) ||
5012+ !btf_name_by_offset(btf, linfo[i].file_name_off)) {
49155013 verbose(env, "Invalid line_info[%u].line_off or .file_name_off\n", i);
49165014 err = -EINVAL;
49175015 goto err_free;
@@ -5021,6 +5119,102 @@ static bool check_ids(u32 old_id, u32 cur_id, struct idpair *idmap) · 103 unmodified lines
50215119 return false;
50225120 }
50235121
5122+static void clean_func_state(struct bpf_verifier_env *env,
5123+ struct bpf_func_state *st)
5124+{
5125+ enum bpf_reg_liveness live;
5126+ int i, j;
5127+
5128+ for (i = 0; i < BPF_REG_FP; i++) {
5129+ live = st->regs[i].live;
5130+ /* liveness must not touch this register anymore */
5131+ st->regs[i].live |= REG_LIVE_DONE;
5132+ if (!(live & REG_LIVE_READ))
5133+ /* since the register is unused, clear its state
5134+ * to make further comparison simpler
5135+ */
5136+ __mark_reg_not_init(&st->regs[i]);
5137+ }
5138+
5139+ for (i = 0; i < st->allocated_stack / BPF_REG_SIZE; i++) {
5140+ live = st->stack[i].spilled_ptr.live;
5141+ /* liveness must not touch this stack slot anymore */
5142+ st->stack[i].spilled_ptr.live |= REG_LIVE_DONE;
5143+ if (!(live & REG_LIVE_READ)) {
5144+ __mark_reg_not_init(&st->stack[i].spilled_ptr);
5145+ for (j = 0; j < BPF_REG_SIZE; j++)
5146+ st->stack[i].slot_type[j] = STACK_INVALID;
5147+ }
5148+ }
5149+}
5150+
5151+static void clean_verifier_state(struct bpf_verifier_env *env,
5152+ struct bpf_verifier_state *st)
5153+{
5154+ int i;
5155+
5156+ if (st->frame[0]->regs[0].live & REG_LIVE_DONE)
5157+ /* all regs in this state in all frames were already marked */
5158+ return;
5159+
5160+ for (i = 0; i <= st->curframe; i++)
5161+ clean_func_state(env, st->frame[i]);
5162+}
5163+
5164+/* the parentage chains form a tree.
5165+ * the verifier states are added to state lists at given insn and
5166+ * pushed into state stack for future exploration.
5167+ * when the verifier reaches bpf_exit insn some of the verifer states
5168+ * stored in the state lists have their final liveness state already,
5169+ * but a lot of states will get revised from liveness point of view when
5170+ * the verifier explores other branches.
5171+ * Example:
5172+ * 1: r0 = 1
5173+ * 2: if r1 == 100 goto pc+1
5174+ * 3: r0 = 2
5175+ * 4: exit
5176+ * when the verifier reaches exit insn the register r0 in the state list of
5177+ * insn 2 will be seen as !REG_LIVE_READ. Then the verifier pops the other_branch
5178+ * of insn 2 and goes exploring further. At the insn 4 it will walk the
5179+ * parentage chain from insn 4 into insn 2 and will mark r0 as REG_LIVE_READ.
5180+ *
5181+ * Since the verifier pushes the branch states as it sees them while exploring
5182+ * the program the condition of walking the branch instruction for the second
5183+ * time means that all states below this branch were already explored and
5184+ * their final liveness markes are already propagated.
5185+ * Hence when the verifier completes the search of state list in is_state_visited()
5186+ * we can call this clean_live_states() function to mark all liveness states
5187+ * as REG_LIVE_DONE to indicate that 'parent' pointers of 'struct bpf_reg_state'
5188+ * will not be used.
5189+ * This function also clears the registers and stack for states that !READ
5190+ * to simplify state merging.
5191+ *
5192+ * Important note here that walking the same branch instruction in the callee
5193+ * doesn't meant that the states are DONE. The verifier has to compare
5194+ * the callsites
5195+ */
5196+static void clean_live_states(struct bpf_verifier_env *env, int insn,
5197+ struct bpf_verifier_state *cur)
5198+{
5199+ struct bpf_verifier_state_list *sl;
5200+ int i;
5201+
5202+ sl = env->explored_states[insn];
5203+ if (!sl)
5204+ return;
5205+
5206+ while (sl != STATE_LIST_MARK) {
5207+ if (sl->state.curframe != cur->curframe)
5208+ goto next;
5209+ for (i = 0; i <= cur->curframe; i++)
5210+ if (sl->state.frame[i]->callsite != cur->frame[i]->callsite)
5211+ goto next;
5212+ clean_verifier_state(env, &sl->state);
5213+next:
5214+ sl = sl->next;
5215+ }
5216+}
5217+
50245218 /* Returns true if (rold safe implies rcur safe) */
50255219 static bool regsafe(struct bpf_reg_state *rold, struct bpf_reg_state *rcur,
50265220 struct idpair *idmap)
@@ -5134,12 +5328,6 @@ static bool stacksafe(struct bpf_func_state *old, · 107 unmodified lines
51345328 {
51355329 int i, spi;
51365330
5137− /* if explored stack has more populated slots than current stack
5138− * such stacks are not equivalent
5139− */
5140− if (old->allocated_stack > cur->allocated_stack)
5141− return false;
5142−
51435331 /* walk slots of the explored stack and ignore any additional
51445332 * slots in the current stack, since explored(safe) state
51455333 * didn't use them
@@ -5147,12 +5335,21 @@ static bool stacksafe(struct bpf_func_state *old, · 1 unmodified line
51475335 for (i = 0; i < old->allocated_stack; i++) {
51485336 spi = i / BPF_REG_SIZE;
51495337
5150− if (!(old->stack[spi].spilled_ptr.live & REG_LIVE_READ))
5338+ if (!(old->stack[spi].spilled_ptr.live & REG_LIVE_READ)) {
5339+ i += BPF_REG_SIZE - 1;
51515340 /* explored state didn't use this */
51525341 continue;
5342+ }
51535343
51545344 if (old->stack[spi].slot_type[i % BPF_REG_SIZE] == STACK_INVALID)
51555345 continue;
5346+
5347+ /* explored stack has more populated slots than current stack
5348+ * and these slots were used
5349+ */
5350+ if (i >= cur->allocated_stack)
5351+ return false;
5352+
51565353 /* if old state was safe with misc data in the stack
51575354 * it will be safe with zero-initialized stack.
51585355 * The opposite is not true
@@ -5336,6 +5533,8 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) · 177 unmodified lines
53365533 */
53375534 return 0;
53385535
5536+ clean_live_states(env, insn_idx, cur);
5537+
53395538 while (sl != STATE_LIST_MARK) {
53405539 if (states_equal(env, &sl->state, cur)) {
53415540 /* reached equivalent register/stack state,
@@ -5455,6 +5654,8 @@ static int do_check(struct bpf_verifier_env *env) · 113 unmodified lines
54555654 int insn_processed = 0;
54565655 bool do_print_state = false;
54575656
5657+ env->prev_linfo = NULL;
5658+
54585659 state = kzalloc(sizeof(struct bpf_verifier_state), GFP_KERNEL);
54595660 if (!state)
54605661 return -ENOMEM;
@@ -5528,6 +5729,7 @@ static int do_check(struct bpf_verifier_env *env) · 67 unmodified lines
55285729 .private_data = env,
55295730 };
55305731
5732+ verbose_linfo(env, insn_idx, "; ");
55315733 verbose(env, "%d: ", insn_idx);
55325734 print_bpf_insn(&cbs, insn, env->allow_ptr_leaks);
55335735 }
@@ -6762,7 +6964,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, · 1228 unmodified lines
67626964
67636965 env->allow_ptr_leaks = capable(CAP_SYS_ADMIN);
67646966
6765− ret = check_cfg(env);
6967+ ret = check_subprogs(env);
67666968 if (ret < 0)
67676969 goto skip_full_check;
67686970
@@ -6770,6 +6972,10 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, · 1 unmodified line
67706972 if (ret < 0)
67716973 goto skip_full_check;
67726974
6975+ ret = check_cfg(env);
6976+ if (ret < 0)
6977+ goto skip_full_check;
6978+
67736979 ret = do_check(env);
67746980 if (env->cur_state) {
67756981 free_verifier_state(env->cur_state, true);
@@ -6784,10 +6990,11 @@ skip_full_check: · 8 unmodified lines
67846990 free_states(env);
67856991
67866992 if (ret == 0)
6787− sanitize_dead_code(env);
6993+ ret = check_max_stack_depth(env);
67886994
6995+ /* instruction rewrites happen after this point */
67896996 if (ret == 0)
6790− ret = check_max_stack_depth(env);
6997+ sanitize_dead_code(env);
67916998
67926999 if (ret == 0)
67937000 /* program is valid, convert *(u32*)(ctx + off) accesses */
kernel/module.c+5−0
@@ -3093,6 +3093,11 @@ static int find_module_sections(struct module *mod, struct load_info *info) · 3092 unmodified lines
30933093 sizeof(*mod->tracepoints_ptrs),
30943094 &mod->num_tracepoints);
30953095 #endif
3096+#ifdef CONFIG_BPF_EVENTS
3097+ mod->bpf_raw_events = section_objs(info, "__bpf_raw_tp_map",
3098+ sizeof(*mod->bpf_raw_events),
3099+ &mod->num_bpf_raw_events);
3100+#endif
30963101 #ifdef HAVE_JUMP_LABEL
30973102 mod->jump_entries = section_objs(info, "__jump_table",
30983103 sizeof(*mod->jump_entries),
kernel/trace/bpf_trace.c+97−2
@@ -17,6 +17,43 @@ · 16 unmodified lines
1717 #include "trace_probe.h"
1818 #include "trace.h"
1919
20+#ifdef CONFIG_MODULES
21+struct bpf_trace_module {
22+ struct module *module;
23+ struct list_head list;
24+};
25+
26+static LIST_HEAD(bpf_trace_modules);
27+static DEFINE_MUTEX(bpf_module_mutex);
28+
29+static struct bpf_raw_event_map *bpf_get_raw_tracepoint_module(const char *name)
30+{
31+ struct bpf_raw_event_map *btp, *ret = NULL;
32+ struct bpf_trace_module *btm;
33+ unsigned int i;
34+
35+ mutex_lock(&bpf_module_mutex);
36+ list_for_each_entry(btm, &bpf_trace_modules, list) {
37+ for (i = 0; i < btm->module->num_bpf_raw_events; ++i) {
38+ btp = &btm->module->bpf_raw_events[i];
39+ if (!strcmp(btp->tp->name, name)) {
40+ if (try_module_get(btm->module))
41+ ret = btp;
42+ goto out;
43+ }
44+ }
45+ }
46+out:
47+ mutex_unlock(&bpf_module_mutex);
48+ return ret;
49+}
50+#else
51+static struct bpf_raw_event_map *bpf_get_raw_tracepoint_module(const char *name)
52+{
53+ return NULL;
54+}
55+#endif /* CONFIG_MODULES */
56+
2057 u64 bpf_get_stackid(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
2158 u64 bpf_get_stack(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5);
2259
@@ -1076,7 +1113,7 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info) · 1053 unmodified lines
10761113 extern struct bpf_raw_event_map __start__bpf_raw_tp[];
10771114 extern struct bpf_raw_event_map __stop__bpf_raw_tp[];
10781115
1079−struct bpf_raw_event_map *bpf_find_raw_tracepoint(const char *name)
1116+struct bpf_raw_event_map *bpf_get_raw_tracepoint(const char *name)
10801117 {
10811118 struct bpf_raw_event_map *btp = __start__bpf_raw_tp;
10821119
@@ -1084,7 +1121,16 @@ struct bpf_raw_event_map *bpf_find_raw_tracepoint(const char *name) · 1 unmodified line
10841121 if (!strcmp(btp->tp->name, name))
10851122 return btp;
10861123 }
1087− return NULL;
1124+
1125+ return bpf_get_raw_tracepoint_module(name);
1126+}
1127+
1128+void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp)
1129+{
1130+ struct module *mod = __module_address((unsigned long)btp);
1131+
1132+ if (mod)
1133+ module_put(mod);
10881134 }
10891135
10901136 static __always_inline
@@ -1222,3 +1268,52 @@ int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, · 131 unmodified lines
12221268
12231269 return err;
12241270 }
1271+
1272+#ifdef CONFIG_MODULES
1273+int bpf_event_notify(struct notifier_block *nb, unsigned long op, void *module)
1274+{
1275+ struct bpf_trace_module *btm, *tmp;
1276+ struct module *mod = module;
1277+
1278+ if (mod->num_bpf_raw_events == 0 ||
1279+ (op != MODULE_STATE_COMING && op != MODULE_STATE_GOING))
1280+ return 0;
1281+
1282+ mutex_lock(&bpf_module_mutex);
1283+
1284+ switch (op) {
1285+ case MODULE_STATE_COMING:
1286+ btm = kzalloc(sizeof(*btm), GFP_KERNEL);
1287+ if (btm) {
1288+ btm->module = module;
1289+ list_add(&btm->list, &bpf_trace_modules);
1290+ }
1291+ break;
1292+ case MODULE_STATE_GOING:
1293+ list_for_each_entry_safe(btm, tmp, &bpf_trace_modules, list) {
1294+ if (btm->module == module) {
1295+ list_del(&btm->list);
1296+ kfree(btm);
1297+ break;
1298+ }
1299+ }
1300+ break;
1301+ }
1302+
1303+ mutex_unlock(&bpf_module_mutex);
1304+
1305+ return 0;
1306+}
1307+
1308+static struct notifier_block bpf_module_nb = {
1309+ .notifier_call = bpf_event_notify,
1310+};
1311+
1312+int __init bpf_event_init(void)
1313+{
1314+ register_module_notifier(&bpf_module_nb);
1315+ return 0;
1316+}
1317+
1318+fs_initcall(bpf_event_init);
1319+#endif /* CONFIG_MODULES */
net/core/filter.c+23−7
@@ -6313,6 +6313,9 @@ static bool sk_msg_is_valid_access(int off, int size, · 6312 unmodified lines
63136313 if (type == BPF_WRITE)
63146314 return false;
63156315
6316+ if (off % size != 0)
6317+ return false;
6318+
63166319 switch (off) {
63176320 case offsetof(struct sk_msg_md, data):
63186321 info->reg_type = PTR_TO_PACKET;
@@ -6324,16 +6327,20 @@ static bool sk_msg_is_valid_access(int off, int size, · 5 unmodified lines
63246327 if (size != sizeof(__u64))
63256328 return false;
63266329 break;
6327− default:
6330+ case bpf_ctx_range(struct sk_msg_md, family):
6331+ case bpf_ctx_range(struct sk_msg_md, remote_ip4):
6332+ case bpf_ctx_range(struct sk_msg_md, local_ip4):
6333+ case bpf_ctx_range_till(struct sk_msg_md, remote_ip6[0], remote_ip6[3]):
6334+ case bpf_ctx_range_till(struct sk_msg_md, local_ip6[0], local_ip6[3]):
6335+ case bpf_ctx_range(struct sk_msg_md, remote_port):
6336+ case bpf_ctx_range(struct sk_msg_md, local_port):
6337+ case bpf_ctx_range(struct sk_msg_md, size):
63286338 if (size != sizeof(__u32))
63296339 return false;
6330− }
6331−
6332− if (off < 0 || off >= sizeof(struct sk_msg_md))
6333− return false;
6334− if (off % size != 0)
6340+ break;
6341+ default:
63356342 return false;
6336−
6343+ }
63376344 return true;
63386345 }
63396346
@@ -7418,6 +7425,9 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type, · 1078 unmodified lines
74187425 int off;
74197426 #endif
74207427
7428+ /* convert ctx uses the fact sg element is first in struct */
7429+ BUILD_BUG_ON(offsetof(struct sk_msg, sg) != 0);
7430+
74217431 switch (si->off) {
74227432 case offsetof(struct sk_msg_md, data):
74237433 *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_msg, data),
@@ -7530,6 +7540,12 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type, · 106 unmodified lines
75307540 *insn++ = BPF_LDX_MEM(BPF_H, si->dst_reg, si->dst_reg,
75317541 offsetof(struct sock_common, skc_num));
75327542 break;
7543+
7544+ case offsetof(struct sk_msg_md, size):
7545+ *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_msg_sg, size),
7546+ si->dst_reg, si->src_reg,
7547+ offsetof(struct sk_msg_sg, size));
7548+ break;
75337549 }
75347550
75357551 return insn - insn_buf;
net/core/skmsg.c+20−3
@@ -403,7 +403,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb) · 402 unmodified lines
403403 msg->skb = skb;
404404
405405 sk_psock_queue_msg(psock, msg);
406− sk->sk_data_ready(sk);
406+ sk_psock_data_ready(sk, psock);
407407 return copied;
408408 }
409409
@@ -572,6 +572,7 @@ void sk_psock_drop(struct sock *sk, struct sk_psock *psock) · 162 unmodified lines
572572 {
573573 rcu_assign_sk_user_data(sk, NULL);
574574 sk_psock_cork_free(psock);
575+ sk_psock_zap_ingress(psock);
575576 sk_psock_restore_proto(sk, psock);
576577
577578 write_lock_bh(&sk->sk_callback_lock);
@@ -669,6 +670,22 @@ static void sk_psock_verdict_apply(struct sk_psock *psock, · 91 unmodified lines
669670 bool ingress;
670671
671672 switch (verdict) {
673+ case __SK_PASS:
674+ sk_other = psock->sk;
675+ if (sock_flag(sk_other, SOCK_DEAD) ||
676+ !sk_psock_test_state(psock, SK_PSOCK_TX_ENABLED)) {
677+ goto out_free;
678+ }
679+ if (atomic_read(&sk_other->sk_rmem_alloc) <=
680+ sk_other->sk_rcvbuf) {
681+ struct tcp_skb_cb *tcp = TCP_SKB_CB(skb);
682+
683+ tcp->bpf.flags |= BPF_F_INGRESS;
684+ skb_queue_tail(&psock->ingress_skb, skb);
685+ schedule_work(&psock->work);
686+ break;
687+ }
688+ goto out_free;
672689 case __SK_REDIRECT:
673690 sk_other = tcp_skb_bpf_redirect_fetch(skb);
674691 if (unlikely(!sk_other))
@@ -735,7 +752,7 @@ static int sk_psock_strp_parse(struct strparser *strp, struct sk_buff *skb) · 60 unmodified lines
735752 }
736753
737754 /* Called with socket lock held. */
738−static void sk_psock_data_ready(struct sock *sk)
755+static void sk_psock_strp_data_ready(struct sock *sk)
739756 {
740757 struct sk_psock *psock;
741758
@@ -783,7 +800,7 @@ void sk_psock_start_strp(struct sock *sk, struct sk_psock *psock) · 41 unmodified lines
783800 return;
784801
785802 parser->saved_data_ready = sk->sk_data_ready;
786− sk->sk_data_ready = sk_psock_data_ready;
803+ sk->sk_data_ready = sk_psock_strp_data_ready;
787804 sk->sk_write_space = sk_psock_write_space;
788805 parser->enabled = true;
789806 }
net/ipv4/tcp_bpf.c+13−2
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/wait.h>
99
1010 #include <net/inet_common.h>
11+#include <net/tls.h>
1112
1213 static bool tcp_bpf_stream_read(const struct sock *sk)
1314 {
@@ -198,7 +199,7 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock, · 184 unmodified lines
198199 msg->sg.start = i;
199200 msg->sg.size -= apply_bytes;
200201 sk_psock_queue_msg(psock, tmp);
201− sk->sk_data_ready(sk);
202+ sk_psock_data_ready(sk, psock);
202203 } else {
203204 sk_msg_free(sk, tmp);
204205 kfree(tmp);
@@ -218,6 +219,8 @@ static int tcp_bpf_push(struct sock *sk, struct sk_msg *msg, u32 apply_bytes, · 13 unmodified lines
218219 u32 off;
219220
220221 while (1) {
222+ bool has_tx_ulp;
223+
221224 sge = sk_msg_elem(msg, msg->sg.start);
222225 size = (apply && apply_bytes < sge->length) ?
223226 apply_bytes : sge->length;
@@ -226,7 +229,15 @@ static int tcp_bpf_push(struct sock *sk, struct sk_msg *msg, u32 apply_bytes, · 2 unmodified lines
226229
227230 tcp_rate_check_app_limited(sk);
228231 retry:
229− ret = do_tcp_sendpages(sk, page, off, size, flags);
232+ has_tx_ulp = tls_sw_has_ctx_tx(sk);
233+ if (has_tx_ulp) {
234+ flags |= MSG_SENDPAGE_NOPOLICY;
235+ ret = kernel_sendpage_locked(sk,
236+ page, off, size, flags);
237+ } else {
238+ ret = do_tcp_sendpages(sk, page, off, size, flags);
239+ }
240+
230241 if (ret <= 0)
231242 return ret;
232243 if (apply)
net/tls/tls_main.c+12−2
@@ -55,6 +55,8 @@ enum { · 54 unmodified lines
5555
5656 static struct proto *saved_tcpv6_prot;
5757 static DEFINE_MUTEX(tcpv6_prot_mutex);
58+static struct proto *saved_tcpv4_prot;
59+static DEFINE_MUTEX(tcpv4_prot_mutex);
5860 static LIST_HEAD(device_list);
5961 static DEFINE_SPINLOCK(device_spinlock);
6062 static struct proto tls_prots[TLS_NUM_PROTS][TLS_NUM_CONFIG][TLS_NUM_CONFIG];
@@ -700,6 +702,16 @@ static int tls_init(struct sock *sk) · 639 unmodified lines
700702 mutex_unlock(&tcpv6_prot_mutex);
701703 }
702704
705+ if (ip_ver == TLSV4 &&
706+ unlikely(sk->sk_prot != smp_load_acquire(&saved_tcpv4_prot))) {
707+ mutex_lock(&tcpv4_prot_mutex);
708+ if (likely(sk->sk_prot != saved_tcpv4_prot)) {
709+ build_protos(tls_prots[TLSV4], sk->sk_prot);
710+ smp_store_release(&saved_tcpv4_prot, sk->sk_prot);
711+ }
712+ mutex_unlock(&tcpv4_prot_mutex);
713+ }
714+
703715 ctx->tx_conf = TLS_BASE;
704716 ctx->rx_conf = TLS_BASE;
705717 update_sk_prot(sk, ctx);
@@ -731,8 +743,6 @@ static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = { · 25 unmodified lines
731743
732744 static int __init tls_register(void)
733745 {
734− build_protos(tls_prots[TLSV4], &tcp_prot);
735−
736746 tls_sw_proto_ops = inet_stream_ops;
737747 tls_sw_proto_ops.splice_read = tls_sw_splice_read;
738748
net/tls/tls_sw.c+30−13
@@ -686,12 +686,13 @@ static int bpf_exec_tx_verdict(struct sk_msg *msg, struct sock *sk, · 685 unmodified lines
686686 struct sk_psock *psock;
687687 struct sock *sk_redir;
688688 struct tls_rec *rec;
689+ bool enospc, policy;
689690 int err = 0, send;
690691 u32 delta = 0;
691− bool enospc;
692692
693+ policy = !(flags & MSG_SENDPAGE_NOPOLICY);
693694 psock = sk_psock_get(sk);
694− if (!psock)
695+ if (!psock || !policy)
695696 return tls_push_record(sk, flags, record_type);
696697 more_data:
697698 enospc = sk_msg_full(msg);
@@ -1017,8 +1018,8 @@ send_end: · 319 unmodified lines
10171018 return copied ? copied : ret;
10181019 }
10191020
1020−int tls_sw_sendpage(struct sock *sk, struct page *page,
1021− int offset, size_t size, int flags)
1021+int tls_sw_do_sendpage(struct sock *sk, struct page *page,
1022+ int offset, size_t size, int flags)
10221023 {
10231024 long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
10241025 struct tls_context *tls_ctx = tls_get_ctx(sk);
@@ -1033,15 +1034,7 @@ int tls_sw_sendpage(struct sock *sk, struct page *page, · 8 unmodified lines
10331034 int ret = 0;
10341035 bool eor;
10351036
1036− if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
1037− MSG_SENDPAGE_NOTLAST))
1038− return -ENOTSUPP;
1039−
1040− /* No MSG_EOR from splice, only look at MSG_MORE */
10411037 eor = !(flags & (MSG_MORE | MSG_SENDPAGE_NOTLAST));
1042−
1043− lock_sock(sk);
1044−
10451038 sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
10461039
10471040 /* Wait till there is any pending write on socket */
@@ -1145,10 +1138,34 @@ wait_for_memory: · 97 unmodified lines
11451138 }
11461139 sendpage_end:
11471140 ret = sk_stream_error(sk, flags, ret);
1148− release_sock(sk);
11491141 return copied ? copied : ret;
11501142 }
11511143
1144+int tls_sw_sendpage_locked(struct sock *sk, struct page *page,
1145+ int offset, size_t size, int flags)
1146+{
1147+ if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
1148+ MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY))
1149+ return -ENOTSUPP;
1150+
1151+ return tls_sw_do_sendpage(sk, page, offset, size, flags);
1152+}
1153+
1154+int tls_sw_sendpage(struct sock *sk, struct page *page,
1155+ int offset, size_t size, int flags)
1156+{
1157+ int ret;
1158+
1159+ if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL |
1160+ MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY))
1161+ return -ENOTSUPP;
1162+
1163+ lock_sock(sk);
1164+ ret = tls_sw_do_sendpage(sk, page, offset, size, flags);
1165+ release_sock(sk);
1166+ return ret;
1167+}
1168+
11521169 static struct sk_buff *tls_wait_data(struct sock *sk, struct sk_psock *psock,
11531170 int flags, long timeo, int *err)
11541171 {
net/xdp/xsk.c+1−15
@@ -366,6 +366,7 @@ static int xsk_release(struct socket *sock) · 365 unmodified lines
366366
367367 xskq_destroy(xs->rx);
368368 xskq_destroy(xs->tx);
369+ xdp_put_umem(xs->umem);
369370
370371 sock_orphan(sk);
371372 sock->sk = NULL;
@@ -713,18 +714,6 @@ static const struct proto_ops xsk_proto_ops = { · 341 unmodified lines
713714 .sendpage = sock_no_sendpage,
714715 };
715716
716−static void xsk_destruct(struct sock *sk)
717−{
718− struct xdp_sock *xs = xdp_sk(sk);
719−
720− if (!sock_flag(sk, SOCK_DEAD))
721− return;
722−
723− xdp_put_umem(xs->umem);
724−
725− sk_refcnt_debug_dec(sk);
726−}
727−
728717 static int xsk_create(struct net *net, struct socket *sock, int protocol,
729718 int kern)
730719 {
@@ -751,9 +740,6 @@ static int xsk_create(struct net *net, struct socket *sock, int protocol, · 20 unmodified lines
751740
752741 sk->sk_family = PF_XDP;
753742
754− sk->sk_destruct = xsk_destruct;
755− sk_refcnt_debug_inc(sk);
756−
757743 sock_set_flag(sk, SOCK_RCU_FREE);
758744
759745 xs = xdp_sk(sk);
tools/bpf/bpftool/Documentation/bpftool-map.rst+59−0
@@ -128,6 +128,10 @@ OPTIONS · 127 unmodified lines
128128 -f, --bpffs
129129 Show file names of pinned maps.
130130
131+ -n, --nomount
132+ Do not automatically attempt to mount any virtual file system
133+ (such as tracefs or BPF virtual file system) when necessary.
134+
131135 EXAMPLES
132136 ========
133137 **# bpftool map show**
@@ -170,6 +174,61 @@ The following three commands are equivalent: · 36 unmodified lines
170174 | **# bpftool map pin id 10 /sys/fs/bpf/map**
171175 | **# bpftool map del pinned /sys/fs/bpf/map key 13 00 07 00**
172176
177+Note that map update can also be used in order to change the program references
178+hold by a program array map. This can be used, for example, to change the
179+programs used for tail-call jumps at runtime, without having to reload the
180+entry-point program. Below is an example for this use case: we load a program
181+defining a prog array map, and with a main function that contains a tail call
182+to other programs that can be used either to "process" packets or to "debug"
183+processing. Note that the prog array map MUST be pinned into the BPF virtual
184+file system for the map update to work successfully, as kernel flushes prog
185+array maps when they have no more references from user space (and the update
186+would be lost as soon as bpftool exits).
187+
188+|
189+| **# bpftool prog loadall tail_calls.o /sys/fs/bpf/foo type xdp**
190+| **# bpftool prog --bpffs**
191+
192+::
193+
194+ 545: xdp name main_func tag 674b4b5597193dc3 gpl
195+ loaded_at 2018-12-12T15:02:58+0000 uid 0
196+ xlated 240B jited 257B memlock 4096B map_ids 294
197+ pinned /sys/fs/bpf/foo/xdp
198+ 546: xdp name bpf_func_process tag e369a529024751fc gpl
199+ loaded_at 2018-12-12T15:02:58+0000 uid 0
200+ xlated 200B jited 164B memlock 4096B
201+ pinned /sys/fs/bpf/foo/process
202+ 547: xdp name bpf_func_debug tag 0b597868bc7f0976 gpl
203+ loaded_at 2018-12-12T15:02:58+0000 uid 0
204+ xlated 200B jited 164B memlock 4096B
205+ pinned /sys/fs/bpf/foo/debug
206+
207+**# bpftool map**
208+
209+::
210+
211+ 294: prog_array name jmp_table flags 0x0
212+ key 4B value 4B max_entries 1 memlock 4096B
213+ owner_prog_type xdp owner jited
214+
215+|
216+| **# bpftool map pin id 294 /sys/fs/bpf/bar**
217+| **# bpftool map dump pinned /sys/fs/bpf/bar**
218+
219+::
220+
221+ Found 0 elements
222+
223+|
224+| **# bpftool map update pinned /sys/fs/bpf/bar key 0 0 0 0 value pinned /sys/fs/bpf/foo/debug**
225+| **# bpftool map dump pinned /sys/fs/bpf/bar**
226+
227+::
228+
229+ key: 00 00 00 00 value: 22 02 00 00
230+ Found 1 element
231+
173232 SEE ALSO
174233 ========
175234 **bpf**\ (2),
tools/bpf/bpftool/Documentation/bpftool-prog.rst+60−45
@@ -158,83 +158,98 @@ OPTIONS · 157 unmodified lines
158158 When showing BPF programs, show file names of pinned
159159 programs.
160160
161+ -m, --mapcompat
162+ Allow loading maps with unknown map definitions.
163+
164+ -n, --nomount
165+ Do not automatically attempt to mount any virtual file system
166+ (such as tracefs or BPF virtual file system) when necessary.
167+
161168 EXAMPLES
162169 ========
163170 **# bpftool prog show**
171+
164172 ::
165173
166− 10: xdp name some_prog tag 005a3d2123620c8b gpl
167− loaded_at Sep 29/20:11 uid 0
168− xlated 528B jited 370B memlock 4096B map_ids 10
174+ 10: xdp name some_prog tag 005a3d2123620c8b gpl
175+ loaded_at 2017-09-29T20:11:00+0000 uid 0
176+ xlated 528B jited 370B memlock 4096B map_ids 10
169177
170178 **# bpftool --json --pretty prog show**
171179
172180 ::
173181
174− {
175− "programs": [{
176− "id": 10,
177− "type": "xdp",
178− "tag": "005a3d2123620c8b",
179− "gpl_compatible": true,
180− "loaded_at": "Sep 29/20:11",
181− "uid": 0,
182− "bytes_xlated": 528,
183− "jited": true,
184− "bytes_jited": 370,
185− "bytes_memlock": 4096,
186− "map_ids": [10
187− ]
188− }
189− ]
190− }
182+ [{
183+ "id": 10,
184+ "type": "xdp",
185+ "tag": "005a3d2123620c8b",
186+ "gpl_compatible": true,
187+ "loaded_at": 1506715860,
188+ "uid": 0,
189+ "bytes_xlated": 528,
190+ "jited": true,
191+ "bytes_jited": 370,
192+ "bytes_memlock": 4096,
193+ "map_ids": [10
194+ ]
195+ }
196+ ]
191197
192198 |
193199 | **# bpftool prog dump xlated id 10 file /tmp/t**
194200 | **# ls -l /tmp/t**
195−| -rw------- 1 root root 560 Jul 22 01:42 /tmp/t
196201
197−**# bpftool prog dum jited tag 005a3d2123620c8b**
202+::
203+
204+ -rw------- 1 root root 560 Jul 22 01:42 /tmp/t
205+
206+**# bpftool prog dump jited tag 005a3d2123620c8b**
198207
199208 ::
200209
201− push %rbp
202− mov %rsp,%rbp
203− sub $0x228,%rsp
204− sub $0x28,%rbp
205− mov %rbx,0x0(%rbp)
210+ 0: push %rbp
211+ 1: mov %rsp,%rbp
212+ 2: sub $0x228,%rsp
213+ 3: sub $0x28,%rbp
214+ 4: mov %rbx,0x0(%rbp)
206215
207216 |
208217 | **# mount -t bpf none /sys/fs/bpf/**
209218 | **# bpftool prog pin id 10 /sys/fs/bpf/prog**
210219 | **# bpftool prog load ./my_prog.o /sys/fs/bpf/prog2**
211220 | **# ls -l /sys/fs/bpf/**
212−| -rw------- 1 root root 0 Jul 22 01:43 prog
213−| -rw------- 1 root root 0 Jul 22 01:44 prog2
214221
215−**# bpftool prog dum jited pinned /sys/fs/bpf/prog opcodes**
222+::
223+
224+ -rw------- 1 root root 0 Jul 22 01:43 prog
225+ -rw------- 1 root root 0 Jul 22 01:44 prog2
226+
227+**# bpftool prog dump jited pinned /sys/fs/bpf/prog opcodes**
216228
217229 ::
218230
219− push %rbp
220− 55
221− mov %rsp,%rbp
222− 48 89 e5
223− sub $0x228,%rsp
224− 48 81 ec 28 02 00 00
225− sub $0x28,%rbp
226− 48 83 ed 28
227− mov %rbx,0x0(%rbp)
228− 48 89 5d 00
231+ 0: push %rbp
232+ 55
233+ 1: mov %rsp,%rbp
234+ 48 89 e5
235+ 4: sub $0x228,%rsp
236+ 48 81 ec 28 02 00 00
237+ b: sub $0x28,%rbp
238+ 48 83 ed 28
239+ f: mov %rbx,0x0(%rbp)
240+ 48 89 5d 00
229241
230242 |
231243 | **# bpftool prog load xdp1_kern.o /sys/fs/bpf/xdp1 type xdp map name rxcnt id 7**
232244 | **# bpftool prog show pinned /sys/fs/bpf/xdp1**
233−| 9: xdp name xdp_prog1 tag 539ec6ce11b52f98 gpl
234−| loaded_at 2018-06-25T16:17:31-0700 uid 0
235−| xlated 488B jited 336B memlock 4096B map_ids 7
236−| **# rm /sys/fs/bpf/xdp1**
237−|
245+
246+::
247+
248+ 9: xdp name xdp_prog1 tag 539ec6ce11b52f98 gpl
249+ loaded_at 2018-06-25T16:17:31-0700 uid 0
250+ xlated 488B jited 336B memlock 4096B map_ids 7
251+
252+**# rm /sys/fs/bpf/xdp1**
238253
239254 SEE ALSO
240255 ========
tools/bpf/bpftool/Documentation/bpftool.rst+4−0
@@ -60,6 +60,10 @@ OPTIONS · 59 unmodified lines
6060 -m, --mapcompat
6161 Allow loading maps with unknown map definitions.
6262
63+ -n, --nomount
64+ Do not automatically attempt to mount any virtual file system
65+ (such as tracefs or BPF virtual file system) when necessary.
66+
6367
6468 SEE ALSO
6569 ========
tools/bpf/bpftool/Makefile+0−2
@@ -35,8 +35,6 @@ $(LIBBPF)-clean: · 34 unmodified lines
3535 prefix ?= /usr/local
3636 bash_compdir ?= /usr/share/bash-completion/completions
3737
38−CC = gcc
39−
4038 CFLAGS += -O2
4139 CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wshadow -Wno-missing-field-initializers
4240 CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ \
tools/bpf/bpftool/bash-completion/bpftool+1−30
@@ -1,37 +1,8 @@
11 # bpftool(8) bash completion -*- shell-script -*-
22 #
3+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
34 # Copyright (C) 2017-2018 Netronome Systems, Inc.
45 #
5−# This software is dual licensed under the GNU General License
6−# Version 2, June 1991 as shown in the file COPYING in the top-level
7−# directory of this source tree or the BSD 2-Clause License provided
8−# below. You have the option to license this software under the
9−# complete terms of either license.
10−#
11−# The BSD 2-Clause License:
12−#
13−# Redistribution and use in source and binary forms, with or
14−# without modification, are permitted provided that the following
15−# conditions are met:
16−#
17−# 1. Redistributions of source code must retain the above
18−# copyright notice, this list of conditions and the following
19−# disclaimer.
20−#
21−# 2. Redistributions in binary form must reproduce the above
22−# copyright notice, this list of conditions and the following
23−# disclaimer in the documentation and/or other materials
24−# provided with the distribution.
25−#
26−# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27−# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28−# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29−# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30−# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31−# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32−# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33−# SOFTWARE.
34−#
356 # Author: Quentin Monnet <quentin.monnet@netronome.com>
367
378 # Takes a list of words in argument; each one of them is added to COMPREPLY if
tools/bpf/bpftool/btf_dumper.c+47−16
@@ -1,4 +1,4 @@
1−// SPDX-License-Identifier: GPL-2.0
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22 /* Copyright (c) 2018 Facebook */
33
44 #include <ctype.h>
@@ -73,20 +73,17 @@ static int btf_dumper_array(const struct btf_dumper *d, __u32 type_id, · 68 unmodified lines
7373 return ret;
7474 }
7575
76−static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset,
76+static void btf_dumper_bitfield(__u32 nr_bits, __u8 bit_offset,
7777 const void *data, json_writer_t *jw,
7878 bool is_plain_text)
7979 {
8080 int left_shift_bits, right_shift_bits;
81− int nr_bits = BTF_INT_BITS(int_type);
82− int total_bits_offset;
8381 int bytes_to_copy;
8482 int bits_to_copy;
8583 __u64 print_num;
8684
87− total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type);
88− data += BITS_ROUNDDOWN_BYTES(total_bits_offset);
89− bit_offset = BITS_PER_BYTE_MASKED(total_bits_offset);
85+ data += BITS_ROUNDDOWN_BYTES(bit_offset);
86+ bit_offset = BITS_PER_BYTE_MASKED(bit_offset);
9087 bits_to_copy = bit_offset + nr_bits;
9188 bytes_to_copy = BITS_ROUNDUP_BYTES(bits_to_copy);
9289
@@ -109,6 +106,22 @@ static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset, · 16 unmodified lines
109106 jsonw_printf(jw, "%llu", print_num);
110107 }
111108
109+
110+static void btf_dumper_int_bits(__u32 int_type, __u8 bit_offset,
111+ const void *data, json_writer_t *jw,
112+ bool is_plain_text)
113+{
114+ int nr_bits = BTF_INT_BITS(int_type);
115+ int total_bits_offset;
116+
117+ /* bits_offset is at most 7.
118+ * BTF_INT_OFFSET() cannot exceed 64 bits.
119+ */
120+ total_bits_offset = bit_offset + BTF_INT_OFFSET(int_type);
121+ btf_dumper_bitfield(nr_bits, total_bits_offset, data, jw,
122+ is_plain_text);
123+}
124+
112125 static int btf_dumper_int(const struct btf_type *t, __u8 bit_offset,
113126 const void *data, json_writer_t *jw,
114127 bool is_plain_text)
@@ -180,6 +193,7 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id, · 65 unmodified lines
180193 const struct btf_type *t;
181194 struct btf_member *m;
182195 const void *data_off;
196+ int kind_flag;
183197 int ret = 0;
184198 int i, vlen;
185199
@@ -187,18 +201,32 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id, · 1 unmodified line
187201 if (!t)
188202 return -EINVAL;
189203
204+ kind_flag = BTF_INFO_KFLAG(t->info);
190205 vlen = BTF_INFO_VLEN(t->info);
191206 jsonw_start_object(d->jw);
192207 m = (struct btf_member *)(t + 1);
193208
194209 for (i = 0; i < vlen; i++) {
195− data_off = data + BITS_ROUNDDOWN_BYTES(m[i].offset);
210+ __u32 bit_offset = m[i].offset;
211+ __u32 bitfield_size = 0;
212+
213+ if (kind_flag) {
214+ bitfield_size = BTF_MEMBER_BITFIELD_SIZE(bit_offset);
215+ bit_offset = BTF_MEMBER_BIT_OFFSET(bit_offset);
216+ }
217+
196218 jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off));
197− ret = btf_dumper_do_type(d, m[i].type,
198− BITS_PER_BYTE_MASKED(m[i].offset),
199− data_off);
200− if (ret)
201− break;
219+ if (bitfield_size) {
220+ btf_dumper_bitfield(bitfield_size, bit_offset,
221+ data, d->jw, d->is_plain_text);
222+ } else {
223+ data_off = data + BITS_ROUNDDOWN_BYTES(bit_offset);
224+ ret = btf_dumper_do_type(d, m[i].type,
225+ BITS_PER_BYTE_MASKED(bit_offset),
226+ data_off);
227+ if (ret)
228+ break;
229+ }
202230 }
203231
204232 jsonw_end_object(d->jw);
@@ -285,6 +313,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id, · 80 unmodified lines
285313
286314 switch (BTF_INFO_KIND(t->info)) {
287315 case BTF_KIND_INT:
316+ case BTF_KIND_TYPEDEF:
288317 BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off));
289318 break;
290319 case BTF_KIND_STRUCT:
@@ -308,10 +337,11 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id, · 17 unmodified lines
308337 BTF_PRINT_TYPE(t->type);
309338 BTF_PRINT_ARG("* ");
310339 break;
311− case BTF_KIND_UNKN:
312340 case BTF_KIND_FWD:
313− case BTF_KIND_TYPEDEF:
314− return -1;
341+ BTF_PRINT_ARG("%s %s ",
342+ BTF_INFO_KFLAG(t->info) ? "union" : "struct",
343+ btf__name_by_offset(btf, t->name_off));
344+ break;
315345 case BTF_KIND_VOLATILE:
316346 BTF_PRINT_ARG("volatile ");
317347 BTF_PRINT_TYPE(t->type);
@@ -335,6 +365,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id, · 17 unmodified lines
335365 if (pos == -1)
336366 return -1;
337367 break;
368+ case BTF_KIND_UNKN:
338369 default:
339370 return -1;
340371 }
tools/bpf/bpftool/cfg.c+1−35
@@ -1,39 +1,5 @@
11 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2−/*
3− * Copyright (C) 2018 Netronome Systems, Inc.
4− *
5− * This software is dual licensed under the GNU General License Version 2,
6− * June 1991 as shown in the file COPYING in the top-level directory of this
7− * source tree or the BSD 2-Clause License provided below. You have the
8− * option to license this software under the complete terms of either license.
9− *
10− * The BSD 2-Clause License:
11− *
12− * Redistribution and use in source and binary forms, with or
13− * without modification, are permitted provided that the following
14− * conditions are met:
15− *
16− * 1. Redistributions of source code must retain the above
17− * copyright notice, this list of conditions and the following
18− * disclaimer.
19− *
20− * 2. Redistributions in binary form must reproduce the above
21− * copyright notice, this list of conditions and the following
22− * disclaimer in the documentation and/or other materials
23− * provided with the distribution.
24− *
25− * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26− * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27− * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28− * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29− * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30− * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31− * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32− * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33− * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34− * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35− * POSSIBILITY OF SUCH DAMAGE.
36− */
2+/* Copyright (C) 2018 Netronome Systems, Inc. */
373
384 #include <linux/list.h>
395 #include <stdlib.h>
tools/bpf/bpftool/cfg.h+2−36
@@ -1,39 +1,5 @@
1−// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2−/*
3− * Copyright (C) 2018 Netronome Systems, Inc.
4− *
5− * This software is dual licensed under the GNU General License Version 2,
6− * June 1991 as shown in the file COPYING in the top-level directory of this
7− * source tree or the BSD 2-Clause License provided below. You have the
8− * option to license this software under the complete terms of either license.
9− *
10− * The BSD 2-Clause License:
11− *
12− * Redistribution and use in source and binary forms, with or
13− * without modification, are permitted provided that the following
14− * conditions are met:
15− *
16− * 1. Redistributions of source code must retain the above
17− * copyright notice, this list of conditions and the following
18− * disclaimer.
19− *
20− * 2. Redistributions in binary form must reproduce the above
21− * copyright notice, this list of conditions and the following
22− * disclaimer in the documentation and/or other materials
23− * provided with the distribution.
24− *
25− * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26− * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27− * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28− * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29− * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30− * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31− * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32− * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33− * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34− * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35− * POSSIBILITY OF SUCH DAMAGE.
36− */
1+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2+/* Copyright (C) 2018 Netronome Systems, Inc. */
373
384 #ifndef __BPF_TOOL_CFG_H
395 #define __BPF_TOOL_CFG_H
tools/bpf/bpftool/cgroup.c+1−1
@@ -1,4 +1,4 @@
1−// SPDX-License-Identifier: GPL-2.0+
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22 // Copyright (C) 2017 Facebook
33 // Author: Roman Gushchin <guro@fb.com>
44
tools/bpf/bpftool/common.c+30−39
@@ -1,35 +1,5 @@
1−/*
2− * Copyright (C) 2017-2018 Netronome Systems, Inc.
3− *
4− * This software is dual licensed under the GNU General License Version 2,
5− * June 1991 as shown in the file COPYING in the top-level directory of this
6− * source tree or the BSD 2-Clause License provided below. You have the
7− * option to license this software under the complete terms of either license.
8− *
9− * The BSD 2-Clause License:
10− *
11− * Redistribution and use in source and binary forms, with or
12− * without modification, are permitted provided that the following
13− * conditions are met:
14− *
15− * 1. Redistributions of source code must retain the above
16− * copyright notice, this list of conditions and the following
17− * disclaimer.
18− *
19− * 2. Redistributions in binary form must reproduce the above
20− * copyright notice, this list of conditions and the following
21− * disclaimer in the documentation and/or other materials
22− * provided with the distribution.
23− *
24− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25− * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26− * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27− * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28− * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29− * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30− * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31− * SOFTWARE.
32− */
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
333
344 #include <ctype.h>
355 #include <errno.h>
@@ -58,7 +28,7 @@ · 22 unmodified lines
5828 #define BPF_FS_MAGIC 0xcafe4a11
5929 #endif
6030
61−void p_err(const char *fmt, ...)
31+void __printf(1, 2) p_err(const char *fmt, ...)
6232 {
6333 va_list ap;
6434
@@ -76,7 +46,7 @@ void p_err(const char *fmt, ...) · 11 unmodified lines
7646 va_end(ap);
7747 }
7848
79−void p_info(const char *fmt, ...)
49+void __printf(1, 2) p_info(const char *fmt, ...)
8050 {
8151 va_list ap;
8252
@@ -106,7 +76,8 @@ void set_max_rlimit(void) · 23 unmodified lines
10676 setrlimit(RLIMIT_MEMLOCK, &rinf);
10777 }
10878
109−static int mnt_bpffs(const char *target, char *buff, size_t bufflen)
79+static int
80+mnt_fs(const char *target, const char *type, char *buff, size_t bufflen)
11081 {
11182 bool bind_done = false;
11283
@@ -128,15 +99,29 @@ static int mnt_bpffs(const char *target, char *buff, size_t bufflen) · 15 unmodified lines
12899 bind_done = true;
129100 }
130101
131− if (mount("bpf", target, "bpf", 0, "mode=0700")) {
132− snprintf(buff, bufflen, "mount -t bpf bpf %s failed: %s",
133− target, strerror(errno));
102+ if (mount(type, target, type, 0, "mode=0700")) {
103+ snprintf(buff, bufflen, "mount -t %s %s %s failed: %s",
104+ type, type, target, strerror(errno));
134105 return -1;
135106 }
136107
137108 return 0;
138109 }
139110
111+int mount_tracefs(const char *target)
112+{
113+ char err_str[ERR_MAX_LEN];
114+ int err;
115+
116+ err = mnt_fs(target, "tracefs", err_str, ERR_MAX_LEN);
117+ if (err) {
118+ err_str[ERR_MAX_LEN - 1] = '\0';
119+ p_err("can't mount tracefs: %s", err_str);
120+ }
121+
122+ return err;
123+}
124+
140125 int open_obj_pinned(char *path, bool quiet)
141126 {
142127 int fd;
@@ -192,7 +177,13 @@ int mount_bpffs_for_pin(const char *name) · 49 unmodified lines
192177 /* nothing to do if already mounted */
193178 goto out_free;
194179
195− err = mnt_bpffs(dir, err_str, ERR_MAX_LEN);
180+ if (block_mount) {
181+ p_err("no BPF file system found, not mounting it due to --nomount option");
182+ err = -1;
183+ goto out_free;
184+ }
185+
186+ err = mnt_fs(dir, "bpf", err_str, ERR_MAX_LEN);
196187 if (err) {
197188 err_str[ERR_MAX_LEN - 1] = '\0';
198189 p_err("can't mount BPF file system to pin the object (%s): %s",
tools/bpf/bpftool/jit_disasm.c+1−0
@@ -1,3 +1,4 @@
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
12 /*
23 * Based on:
34 *
tools/bpf/bpftool/json_writer.c+5−2
@@ -1,3 +1,4 @@
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
12 /*
23 * Simple streaming JSON writer
34 *
@@ -19,6 +20,7 @@ · 15 unmodified lines
1920 #include <malloc.h>
2021 #include <inttypes.h>
2122 #include <stdint.h>
23+#include <linux/compiler.h>
2224
2325 #include "json_writer.h"
2426
@@ -156,7 +158,8 @@ void jsonw_name(json_writer_t *self, const char *name) · 131 unmodified lines
156158 putc(' ', self->out);
157159 }
158160
159−void jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap)
161+void __printf(2, 0)
162+jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap)
160163 {
161164 jsonw_eor(self);
162165 putc('"', self->out);
@@ -164,7 +167,7 @@ void jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap) · 1 unmodified line
164167 putc('"', self->out);
165168 }
166169
167−void jsonw_printf(json_writer_t *self, const char *fmt, ...)
170+void __printf(2, 3) jsonw_printf(json_writer_t *self, const char *fmt, ...)
168171 {
169172 va_list ap;
170173
tools/bpf/bpftool/json_writer.h+1−0
@@ -1,3 +1,4 @@
1+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
12 /*
23 * Simple streaming JSON writer
34 *
tools/bpf/bpftool/main.c+9−33
@@ -1,35 +1,5 @@
1−/*
2− * Copyright (C) 2017-2018 Netronome Systems, Inc.
3− *
4− * This software is dual licensed under the GNU General License Version 2,
5− * June 1991 as shown in the file COPYING in the top-level directory of this
6− * source tree or the BSD 2-Clause License provided below. You have the
7− * option to license this software under the complete terms of either license.
8− *
9− * The BSD 2-Clause License:
10− *
11− * Redistribution and use in source and binary forms, with or
12− * without modification, are permitted provided that the following
13− * conditions are met:
14− *
15− * 1. Redistributions of source code must retain the above
16− * copyright notice, this list of conditions and the following
17− * disclaimer.
18− *
19− * 2. Redistributions in binary form must reproduce the above
20− * copyright notice, this list of conditions and the following
21− * disclaimer in the documentation and/or other materials
22− * provided with the distribution.
23− *
24− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25− * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26− * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27− * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28− * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29− * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30− * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31− * SOFTWARE.
32− */
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
333
344 #include <ctype.h>
355 #include <errno.h>
@@ -54,6 +24,7 @@ json_writer_t *json_wtr; · 18 unmodified lines
5424 bool pretty_output;
5525 bool json_output;
5626 bool show_pinned;
27+bool block_mount;
5728 int bpf_flags;
5829 struct pinned_obj_table prog_table;
5930 struct pinned_obj_table map_table;
@@ -343,6 +314,7 @@ int main(int argc, char **argv) · 283 unmodified lines
343314 { "version", no_argument, NULL, 'V' },
344315 { "bpffs", no_argument, NULL, 'f' },
345316 { "mapcompat", no_argument, NULL, 'm' },
317+ { "nomount", no_argument, NULL, 'n' },
346318 { 0 }
347319 };
348320 int opt, ret;
@@ -351,13 +323,14 @@ int main(int argc, char **argv) · 2 unmodified lines
351323 pretty_output = false;
352324 json_output = false;
353325 show_pinned = false;
326+ block_mount = false;
354327 bin_name = argv[0];
355328
356329 hash_init(prog_table.table);
357330 hash_init(map_table.table);
358331
359332 opterr = 0;
360− while ((opt = getopt_long(argc, argv, "Vhpjfm",
333+ while ((opt = getopt_long(argc, argv, "Vhpjfmn",
361334 options, NULL)) >= 0) {
362335 switch (opt) {
363336 case 'V':
@@ -384,6 +357,9 @@ int main(int argc, char **argv) · 20 unmodified lines
384357 case 'm':
385358 bpf_flags = MAPS_RELAX_COMPAT;
386359 break;
360+ case 'n':
361+ block_mount = true;
362+ break;
387363 default:
388364 p_err("unrecognized option '%s'", argv[optind - 1]);
389365 if (json_output)
tools/bpf/bpftool/main.h+8−34
@@ -1,35 +1,5 @@
1−/*
2− * Copyright (C) 2017-2018 Netronome Systems, Inc.
3− *
4− * This software is dual licensed under the GNU General License Version 2,
5− * June 1991 as shown in the file COPYING in the top-level directory of this
6− * source tree or the BSD 2-Clause License provided below. You have the
7− * option to license this software under the complete terms of either license.
8− *
9− * The BSD 2-Clause License:
10− *
11− * Redistribution and use in source and binary forms, with or
12− * without modification, are permitted provided that the following
13− * conditions are met:
14− *
15− * 1. Redistributions of source code must retain the above
16− * copyright notice, this list of conditions and the following
17− * disclaimer.
18− *
19− * 2. Redistributions in binary form must reproduce the above
20− * copyright notice, this list of conditions and the following
21− * disclaimer in the documentation and/or other materials
22− * provided with the distribution.
23− *
24− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25− * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26− * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27− * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28− * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29− * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30− * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31− * SOFTWARE.
32− */
1+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2+/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
333
344 #ifndef __BPF_TOOL_H
355 #define __BPF_TOOL_H
@@ -74,7 +44,8 @@ · 38 unmodified lines
7444 #define HELP_SPEC_PROGRAM \
7545 "PROG := { id PROG_ID | pinned FILE | tag PROG_TAG }"
7646 #define HELP_SPEC_OPTIONS \
77− "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} | {-m|--mapcompat}"
47+ "OPTIONS := { {-j|--json} [{-p|--pretty}] | {-f|--bpffs} |\n" \
48+ "\t {-m|--mapcompat} | {-n|--nomount} }"
7849 #define HELP_SPEC_MAP \
7950 "MAP := { id MAP_ID | pinned FILE }"
8051
@@ -115,6 +86,7 @@ extern const char *bin_name; · 34 unmodified lines
11586 extern json_writer_t *json_wtr;
11687 extern bool json_output;
11788 extern bool show_pinned;
89+extern bool block_mount;
11890 extern int bpf_flags;
11991 extern struct pinned_obj_table prog_table;
12092 extern struct pinned_obj_table map_table;
@@ -128,6 +100,8 @@ void usage(void) __noreturn; · 7 unmodified lines
128100
129101 void set_max_rlimit(void);
130102
103+int mount_tracefs(const char *target);
104+
131105 struct pinned_obj_table {
132106 DECLARE_HASHTABLE(table, 16);
133107 };
@@ -177,8 +151,8 @@ int prog_parse_fd(int *argc, char ***argv); · 43 unmodified lines
177151 int map_parse_fd(int *argc, char ***argv);
178152 int map_parse_fd_and_info(int *argc, char ***argv, void *info, __u32 *info_len);
179153
180−#ifdef HAVE_LIBBFD_SUPPORT
181154 struct bpf_prog_linfo;
155+#ifdef HAVE_LIBBFD_SUPPORT
182156 void disasm_print_insn(unsigned char *image, ssize_t len, int opcodes,
183157 const char *arch, const char *disassembler_options,
184158 const struct btf *btf,
tools/bpf/bpftool/map.c+2−32
@@ -1,35 +1,5 @@
1−/*
2− * Copyright (C) 2017-2018 Netronome Systems, Inc.
3− *
4− * This software is dual licensed under the GNU General License Version 2,
5− * June 1991 as shown in the file COPYING in the top-level directory of this
6− * source tree or the BSD 2-Clause License provided below. You have the
7− * option to license this software under the complete terms of either license.
8− *
9− * The BSD 2-Clause License:
10− *
11− * Redistribution and use in source and binary forms, with or
12− * without modification, are permitted provided that the following
13− * conditions are met:
14− *
15− * 1. Redistributions of source code must retain the above
16− * copyright notice, this list of conditions and the following
17− * disclaimer.
18− *
19− * 2. Redistributions in binary form must reproduce the above
20− * copyright notice, this list of conditions and the following
21− * disclaimer in the documentation and/or other materials
22− * provided with the distribution.
23− *
24− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25− * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26− * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27− * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28− * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29− * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30− * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31− * SOFTWARE.
32− */
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
333
344 #include <assert.h>
355 #include <errno.h>
tools/bpf/bpftool/map_perf_ring.c+1−1
@@ -1,4 +1,4 @@
1−// SPDX-License-Identifier: GPL-2.0-only
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22 /* Copyright (C) 2018 Netronome Systems, Inc. */
33 /* This program is free software; you can redistribute it and/or
44 * modify it under the terms of version 2 of the GNU General Public
tools/bpf/bpftool/net.c+1−1
@@ -1,4 +1,4 @@
1−// SPDX-License-Identifier: GPL-2.0+
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22 // Copyright (C) 2018 Facebook
33
44 #define _GNU_SOURCE
tools/bpf/bpftool/netlink_dumper.c+1−1
@@ -1,4 +1,4 @@
1−// SPDX-License-Identifier: GPL-2.0+
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22 // Copyright (C) 2018 Facebook
33
44 #include <stdlib.h>
tools/bpf/bpftool/netlink_dumper.h+1−1
@@ -1,4 +1,4 @@
1−// SPDX-License-Identifier: GPL-2.0+
1+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
22 // Copyright (C) 2018 Facebook
33
44 #ifndef _NETLINK_DUMPER_H_
tools/bpf/bpftool/perf.c+1−1
@@ -1,4 +1,4 @@
1−// SPDX-License-Identifier: GPL-2.0+
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22 // Copyright (C) 2018 Facebook
33 // Author: Yonghong Song <yhs@fb.com>
44
tools/bpf/bpftool/prog.c+4−41
@@ -1,35 +1,5 @@
1−/*
2− * Copyright (C) 2017-2018 Netronome Systems, Inc.
3− *
4− * This software is dual licensed under the GNU General License Version 2,
5− * June 1991 as shown in the file COPYING in the top-level directory of this
6− * source tree or the BSD 2-Clause License provided below. You have the
7− * option to license this software under the complete terms of either license.
8− *
9− * The BSD 2-Clause License:
10− *
11− * Redistribution and use in source and binary forms, with or
12− * without modification, are permitted provided that the following
13− * conditions are met:
14− *
15− * 1. Redistributions of source code must retain the above
16− * copyright notice, this list of conditions and the following
17− * disclaimer.
18− *
19− * 2. Redistributions in binary form must reproduce the above
20− * copyright notice, this list of conditions and the following
21− * disclaimer in the documentation and/or other materials
22− * provided with the distribution.
23− *
24− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25− * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26− * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27− * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28− * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29− * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30− * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31− * SOFTWARE.
32− */
1+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
333
344 #define _GNU_SOURCE
355 #include <errno.h>
@@ -62,7 +32,7 @@ static const char * const attach_type_strings[] = { · 26 unmodified lines
6232 [__MAX_BPF_ATTACH_TYPE] = NULL,
6333 };
6434
65−enum bpf_attach_type parse_attach_type(const char *str)
35+static enum bpf_attach_type parse_attach_type(const char *str)
6636 {
6737 enum bpf_attach_type type;
6838
@@ -626,13 +596,6 @@ static int do_dump(int argc, char **argv) · 557 unmodified lines
626596 goto err_free;
627597 }
628598
629− if (func_info && !info.func_info) {
630− /* kernel.kptr_restrict is set. No func_info available. */
631− free(func_info);
632− func_info = NULL;
633− nr_finfo = 0;
634− }
635−
636599 if (linfo && info.nr_line_info != nr_linfo) {
637600 p_err("incorrect nr_line_info %u vs. expected %u",
638601 info.nr_line_info, nr_linfo);
@@ -835,7 +798,7 @@ struct map_replace { · 196 unmodified lines
835798 char *name;
836799 };
837800
838−int map_replace_compar(const void *p1, const void *p2)
801+static int map_replace_compar(const void *p1, const void *p2)
839802 {
840803 const struct map_replace *a = p1, *b = p2;
841804
tools/bpf/bpftool/tracelog.c+16−7
@@ -54,7 +54,7 @@ find_tracefs_mnt_single(unsigned long magic, char *mnt, const char *mntpt) · 53 unmodified lines
5454 return true;
5555 }
5656
57−static bool find_tracefs_pipe(char *mnt)
57+static bool get_tracefs_pipe(char *mnt)
5858 {
5959 static const char * const known_mnts[] = {
6060 "/sys/kernel/debug/tracing",
@@ -88,7 +88,20 @@ static bool find_tracefs_pipe(char *mnt) · 27 unmodified lines
8888 fclose(fp);
8989
9090 /* The string from fscanf() might be truncated, check mnt is valid */
91− if (!found || validate_tracefs_mnt(mnt, TRACEFS_MAGIC))
91+ if (found && validate_tracefs_mnt(mnt, TRACEFS_MAGIC))
92+ goto exit_found;
93+
94+ if (block_mount)
95+ return false;
96+
97+ p_info("could not find tracefs, attempting to mount it now");
98+ /* Most of the time, tracefs is automatically mounted by debugfs at
99+ * /sys/kernel/debug/tracing when we try to access it. If we could not
100+ * find it, it is likely that debugfs is not mounted. Let's give one
101+ * attempt at mounting just tracefs at /sys/kernel/tracing.
102+ */
103+ strcpy(mnt, known_mnts[1]);
104+ if (mount_tracefs(mnt))
92105 return false;
93106
94107 exit_found:
@@ -115,17 +128,13 @@ int do_tracelog(int argc, char **argv) · 20 unmodified lines
115128 .sa_handler = exit_tracelog
116129 };
117130 char trace_pipe[PATH_MAX];
118− bool found_trace_pipe;
119131 size_t buff_len = 0;
120132
121133 if (json_output)
122134 jsonw_start_array(json_wtr);
123135
124− found_trace_pipe = find_tracefs_pipe(trace_pipe);
125− if (!found_trace_pipe) {
126− p_err("could not find trace pipe, tracefs not mounted?");
136+ if (!get_tracefs_pipe(trace_pipe))
127137 return -1;
128− }
129138
130139 trace_pipe_fd = fopen(trace_pipe, "r");
131140 if (!trace_pipe_fd) {
tools/bpf/bpftool/xlated_dumper.c+5−38
@@ -1,39 +1,5 @@
11 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2−/*
3− * Copyright (C) 2018 Netronome Systems, Inc.
4− *
5− * This software is dual licensed under the GNU General License Version 2,
6− * June 1991 as shown in the file COPYING in the top-level directory of this
7− * source tree or the BSD 2-Clause License provided below. You have the
8− * option to license this software under the complete terms of either license.
9− *
10− * The BSD 2-Clause License:
11− *
12− * Redistribution and use in source and binary forms, with or
13− * without modification, are permitted provided that the following
14− * conditions are met:
15− *
16− * 1. Redistributions of source code must retain the above
17− * copyright notice, this list of conditions and the following
18− * disclaimer.
19− *
20− * 2. Redistributions in binary form must reproduce the above
21− * copyright notice, this list of conditions and the following
22− * disclaimer in the documentation and/or other materials
23− * provided with the distribution.
24− *
25− * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26− * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27− * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28− * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29− * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30− * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31− * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32− * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33− * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34− * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35− * POSSIBILITY OF SUCH DAMAGE.
36− */
2+/* Copyright (C) 2018 Netronome Systems, Inc. */
373
384 #define _GNU_SOURCE
395 #include <stdarg.h>
@@ -115,7 +81,7 @@ struct kernel_sym *kernel_syms_search(struct dump_data *dd, · 75 unmodified lines
11581 sizeof(*dd->sym_mapping), kernel_syms_cmp) : NULL;
11682 }
11783
118−static void print_insn(void *private_data, const char *fmt, ...)
84+static void __printf(2, 3) print_insn(void *private_data, const char *fmt, ...)
11985 {
12086 va_list args;
12187
@@ -124,7 +90,7 @@ static void print_insn(void *private_data, const char *fmt, ...) · 2 unmodified lines
12490 va_end(args);
12591 }
12692
127−static void
93+static void __printf(2, 3)
12894 print_insn_for_graph(void *private_data, const char *fmt, ...)
12995 {
13096 char buf[64], *p;
@@ -155,7 +121,8 @@ print_insn_for_graph(void *private_data, const char *fmt, ...) · 24 unmodified lines
155121 printf("%s", buf);
156122 }
157123
158−static void print_insn_json(void *private_data, const char *fmt, ...)
124+static void __printf(2, 3)
125+print_insn_json(void *private_data, const char *fmt, ...)
159126 {
160127 unsigned int l = strlen(fmt);
161128 char chomped_fmt[l];
tools/bpf/bpftool/xlated_dumper.h+2−36
@@ -1,39 +1,5 @@
1−// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2−/*
3− * Copyright (C) 2018 Netronome Systems, Inc.
4− *
5− * This software is dual licensed under the GNU General License Version 2,
6− * June 1991 as shown in the file COPYING in the top-level directory of this
7− * source tree or the BSD 2-Clause License provided below. You have the
8− * option to license this software under the complete terms of either license.
9− *
10− * The BSD 2-Clause License:
11− *
12− * Redistribution and use in source and binary forms, with or
13− * without modification, are permitted provided that the following
14− * conditions are met:
15− *
16− * 1. Redistributions of source code must retain the above
17− * copyright notice, this list of conditions and the following
18− * disclaimer.
19− *
20− * 2. Redistributions in binary form must reproduce the above
21− * copyright notice, this list of conditions and the following
22− * disclaimer in the documentation and/or other materials
23− * provided with the distribution.
24− *
25− * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26− * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27− * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28− * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29− * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30− * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31− * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32− * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33− * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34− * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35− * POSSIBILITY OF SUCH DAMAGE.
36− */
1+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
2+/* Copyright (C) 2018 Netronome Systems, Inc. */
373
384 #ifndef __BPF_TOOL_XLATED_DUMPER_H
395 #define __BPF_TOOL_XLATED_DUMPER_H
tools/include/uapi/linux/bpf.h+12−1
@@ -133,6 +133,14 @@ enum bpf_map_type { · 132 unmodified lines
133133 BPF_MAP_TYPE_STACK,
134134 };
135135
136+/* Note that tracing related programs such as
137+ * BPF_PROG_TYPE_{KPROBE,TRACEPOINT,PERF_EVENT,RAW_TRACEPOINT}
138+ * are not subject to a stable API since kernel internal data
139+ * structures can change from release to release and may
140+ * therefore break existing tracing BPF programs. Tracing BPF
141+ * programs correspond to /a/ specific kernel which is to be
142+ * analyzed, and not /a/ specific kernel /and/ all future ones.
143+ */
136144 enum bpf_prog_type {
137145 BPF_PROG_TYPE_UNSPEC,
138146 BPF_PROG_TYPE_SOCKET_FILTER,
@@ -343,7 +351,7 @@ union bpf_attr { · 204 unmodified lines
343351 __u32 log_level; /* verbosity level of verifier */
344352 __u32 log_size; /* size of user buffer */
345353 __aligned_u64 log_buf; /* user supplied buffer */
346− __u32 kern_version; /* checked when prog_type=kprobe */
354+ __u32 kern_version; /* not used */
347355 __u32 prog_flags;
348356 char prog_name[BPF_OBJ_NAME_LEN];
349357 __u32 prog_ifindex; /* ifindex of netdev to prep for */
@@ -2657,6 +2665,7 @@ struct sk_msg_md { · 2307 unmodified lines
26572665 __u32 local_ip6[4]; /* Stored in network byte order */
26582666 __u32 remote_port; /* Stored in network byte order */
26592667 __u32 local_port; /* stored in host byte order */
2668+ __u32 size; /* Total size of sk_msg */
26602669 };
26612670
26622671 struct sk_reuseport_md {
@@ -2717,6 +2726,8 @@ struct bpf_prog_info { · 54 unmodified lines
27172726 __u32 nr_jited_line_info;
27182727 __u32 line_info_rec_size;
27192728 __u32 jited_line_info_rec_size;
2729+ __u32 nr_prog_tags;
2730+ __aligned_u64 prog_tags;
27202731 } __attribute__((aligned(8)));
27212732
27222733 struct bpf_map_info {
tools/include/uapi/linux/btf.h+18−2
@@ -34,7 +34,9 @@ struct btf_type { · 33 unmodified lines
3434 * bits 0-15: vlen (e.g. # of struct's members)
3535 * bits 16-23: unused
3636 * bits 24-27: kind (e.g. int, ptr, array...etc)
37− * bits 28-31: unused
37+ * bits 28-30: unused
38+ * bit 31: kind_flag, currently used by
39+ * struct, union and fwd
3840 */
3941 __u32 info;
4042 /* "size" is used by INT, ENUM, STRUCT and UNION.
@@ -52,6 +54,7 @@ struct btf_type { · 11 unmodified lines
5254
5355 #define BTF_INFO_KIND(info) (((info) >> 24) & 0x0f)
5456 #define BTF_INFO_VLEN(info) ((info) & 0xffff)
57+#define BTF_INFO_KFLAG(info) ((info) >> 31)
5558
5659 #define BTF_KIND_UNKN 0 /* Unknown */
5760 #define BTF_KIND_INT 1 /* Integer */
@@ -110,9 +113,22 @@ struct btf_array { · 52 unmodified lines
110113 struct btf_member {
111114 __u32 name_off;
112115 __u32 type;
113− __u32 offset; /* offset in bits */
116+ /* If the type info kind_flag is set, the btf_member offset
117+ * contains both member bitfield size and bit offset. The
118+ * bitfield size is set for bitfield members. If the type
119+ * info kind_flag is not set, the offset contains only bit
120+ * offset.
121+ */
122+ __u32 offset;
114123 };
115124
125+/* If the struct/union type info kind_flag is set, the
126+ * following two macros are used to access bitfield_size
127+ * and bit_offset from btf_member.offset.
128+ */
129+#define BTF_MEMBER_BITFIELD_SIZE(val) ((val) >> 24)
130+#define BTF_MEMBER_BIT_OFFSET(val) ((val) & 0xffffff)
131+
116132 /* BTF_KIND_FUNC_PROTO is followed by multiple "struct btf_param".
117133 * The exact number of btf_param is stored in the vlen (of the
118134 * info in "struct btf_type").
tools/lib/bpf/bpf_prog_linfo.c+1−5
@@ -107,11 +107,7 @@ struct bpf_prog_linfo *bpf_prog_linfo__new(const struct bpf_prog_info *info) · 106 unmodified lines
107107
108108 nr_linfo = info->nr_line_info;
109109
110− /*
111− * Test !info->line_info because the kernel may NULL
112− * the ptr if kernel.kptr_restrict is set.
113− */
114− if (!nr_linfo || !info->line_info)
110+ if (!nr_linfo)
115111 return NULL;
116112
117113 /*
tools/lib/bpf/libbpf.c+1−0
@@ -266,6 +266,7 @@ void bpf_program__unload(struct bpf_program *prog) · 265 unmodified lines
266266
267267 zclose(prog->btf_fd);
268268 zfree(&prog->func_info);
269+ zfree(&prog->line_info);
269270 }
270271
271272 static void bpf_program__exit(struct bpf_program *prog)
tools/testing/selftests/bpf/.gitignore+1−0
@@ -27,3 +27,4 @@ test_flow_dissector · 26 unmodified lines
2727 flow_dissector_load
2828 test_netcnt
2929 test_section_names
30+test_tcpnotify_user
tools/testing/selftests/bpf/connect4_prog.c+4−2
@@ -35,9 +35,11 @@ int connect_v4_prog(struct bpf_sock_addr *ctx) · 34 unmodified lines
3535 if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM)
3636 return 0;
3737 else if (ctx->type == SOCK_STREAM)
38− sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv4), 0, 0);
38+ sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv4),
39+ BPF_F_CURRENT_NETNS, 0);
3940 else
40− sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv4), 0, 0);
41+ sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv4),
42+ BPF_F_CURRENT_NETNS, 0);
4143
4244 if (!sk)
4345 return 0;
tools/testing/selftests/bpf/connect6_prog.c+4−2
@@ -47,9 +47,11 @@ int connect_v6_prog(struct bpf_sock_addr *ctx) · 46 unmodified lines
4747 if (ctx->type != SOCK_STREAM && ctx->type != SOCK_DGRAM)
4848 return 0;
4949 else if (ctx->type == SOCK_STREAM)
50− sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv6), 0, 0);
50+ sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof(tuple.ipv6),
51+ BPF_F_CURRENT_NETNS, 0);
5152 else
52− sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv6), 0, 0);
53+ sk = bpf_sk_lookup_udp(ctx, &tuple, sizeof(tuple.ipv6),
54+ BPF_F_CURRENT_NETNS, 0);
5355
5456 if (!sk)
5557 return 0;
tools/testing/selftests/bpf/netcnt_prog.c+6−0
@@ -16,12 +16,18 @@ struct bpf_map_def SEC("maps") percpu_netcnt = { · 15 unmodified lines
1616 .value_size = sizeof(struct percpu_net_cnt),
1717 };
1818
19+BPF_ANNOTATE_KV_PAIR(percpu_netcnt, struct bpf_cgroup_storage_key,
20+ struct percpu_net_cnt);
21+
1922 struct bpf_map_def SEC("maps") netcnt = {
2023 .type = BPF_MAP_TYPE_CGROUP_STORAGE,
2124 .key_size = sizeof(struct bpf_cgroup_storage_key),
2225 .value_size = sizeof(struct net_cnt),
2326 };
2427
28+BPF_ANNOTATE_KV_PAIR(netcnt, struct bpf_cgroup_storage_key,
29+ struct net_cnt);
30+
2531 SEC("cgroup/skb")
2632 int bpf_nextcnt(struct __sk_buff *skb)
2733 {
tools/testing/selftests/bpf/test_btf.c+680−28
@@ -65,8 +65,8 @@ static int __base_pr(const char *format, ...) · 64 unmodified lines
6565 return err;
6666 }
6767
68−#define BTF_INFO_ENC(kind, root, vlen) \
69− ((!!(root) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
68+#define BTF_INFO_ENC(kind, kind_flag, vlen) \
69+ ((!!(kind_flag) << 31) | ((kind) << 24) | ((vlen) & BTF_MAX_VLEN))
7070
7171 #define BTF_TYPE_ENC(name, info, size_or_type) \
7272 (name), (info), (size_or_type)
@@ -86,6 +86,8 @@ static int __base_pr(const char *format, ...) · 13 unmodified lines
8686 #define BTF_MEMBER_ENC(name, type, bits_offset) \
8787 (name), (type), (bits_offset)
8888 #define BTF_ENUM_ENC(name, val) (name), (val)
89+#define BTF_MEMBER_OFFSET(bitfield_size, bits_offset) \
90+ ((bitfield_size) << 24 | (bits_offset))
8991
9092 #define BTF_TYPEDEF_ENC(name, type) \
9193 BTF_TYPE_ENC(name, BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0), type)
@@ -2215,6 +2217,496 @@ static struct btf_raw_test raw_tests[] = { · 2123 unmodified lines
22152217 .err_str = "Invalid type_id",
22162218 },
22172219
2220+{
2221+ .descr = "invalid int kind_flag",
2222+ .raw_types = {
2223+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2224+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_INT, 1, 0), 4), /* [2] */
2225+ BTF_INT_ENC(0, 0, 32),
2226+ BTF_END_RAW,
2227+ },
2228+ BTF_STR_SEC(""),
2229+ .map_type = BPF_MAP_TYPE_ARRAY,
2230+ .map_name = "int_type_check_btf",
2231+ .key_size = sizeof(int),
2232+ .value_size = sizeof(int),
2233+ .key_type_id = 1,
2234+ .value_type_id = 1,
2235+ .max_entries = 4,
2236+ .btf_load_err = true,
2237+ .err_str = "Invalid btf_info kind_flag",
2238+},
2239+
2240+{
2241+ .descr = "invalid ptr kind_flag",
2242+ .raw_types = {
2243+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2244+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 1, 0), 1), /* [2] */
2245+ BTF_END_RAW,
2246+ },
2247+ BTF_STR_SEC(""),
2248+ .map_type = BPF_MAP_TYPE_ARRAY,
2249+ .map_name = "ptr_type_check_btf",
2250+ .key_size = sizeof(int),
2251+ .value_size = sizeof(int),
2252+ .key_type_id = 1,
2253+ .value_type_id = 1,
2254+ .max_entries = 4,
2255+ .btf_load_err = true,
2256+ .err_str = "Invalid btf_info kind_flag",
2257+},
2258+
2259+{
2260+ .descr = "invalid array kind_flag",
2261+ .raw_types = {
2262+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2263+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ARRAY, 1, 0), 0), /* [2] */
2264+ BTF_ARRAY_ENC(1, 1, 1),
2265+ BTF_END_RAW,
2266+ },
2267+ BTF_STR_SEC(""),
2268+ .map_type = BPF_MAP_TYPE_ARRAY,
2269+ .map_name = "array_type_check_btf",
2270+ .key_size = sizeof(int),
2271+ .value_size = sizeof(int),
2272+ .key_type_id = 1,
2273+ .value_type_id = 1,
2274+ .max_entries = 4,
2275+ .btf_load_err = true,
2276+ .err_str = "Invalid btf_info kind_flag",
2277+},
2278+
2279+{
2280+ .descr = "invalid enum kind_flag",
2281+ .raw_types = {
2282+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2283+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 1, 1), 4), /* [2] */
2284+ BTF_ENUM_ENC(NAME_TBD, 0),
2285+ BTF_END_RAW,
2286+ },
2287+ BTF_STR_SEC("\0A"),
2288+ .map_type = BPF_MAP_TYPE_ARRAY,
2289+ .map_name = "enum_type_check_btf",
2290+ .key_size = sizeof(int),
2291+ .value_size = sizeof(int),
2292+ .key_type_id = 1,
2293+ .value_type_id = 1,
2294+ .max_entries = 4,
2295+ .btf_load_err = true,
2296+ .err_str = "Invalid btf_info kind_flag",
2297+},
2298+
2299+{
2300+ .descr = "valid fwd kind_flag",
2301+ .raw_types = {
2302+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2303+ BTF_TYPE_ENC(NAME_TBD,
2304+ BTF_INFO_ENC(BTF_KIND_FWD, 1, 0), 0), /* [2] */
2305+ BTF_END_RAW,
2306+ },
2307+ BTF_STR_SEC("\0A"),
2308+ .map_type = BPF_MAP_TYPE_ARRAY,
2309+ .map_name = "fwd_type_check_btf",
2310+ .key_size = sizeof(int),
2311+ .value_size = sizeof(int),
2312+ .key_type_id = 1,
2313+ .value_type_id = 1,
2314+ .max_entries = 4,
2315+},
2316+
2317+{
2318+ .descr = "invalid typedef kind_flag",
2319+ .raw_types = {
2320+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2321+ BTF_TYPE_ENC(NAME_TBD,
2322+ BTF_INFO_ENC(BTF_KIND_TYPEDEF, 1, 0), 1), /* [2] */
2323+ BTF_END_RAW,
2324+ },
2325+ BTF_STR_SEC("\0A"),
2326+ .map_type = BPF_MAP_TYPE_ARRAY,
2327+ .map_name = "typedef_type_check_btf",
2328+ .key_size = sizeof(int),
2329+ .value_size = sizeof(int),
2330+ .key_type_id = 1,
2331+ .value_type_id = 1,
2332+ .max_entries = 4,
2333+ .btf_load_err = true,
2334+ .err_str = "Invalid btf_info kind_flag",
2335+},
2336+
2337+{
2338+ .descr = "invalid volatile kind_flag",
2339+ .raw_types = {
2340+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2341+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 1, 0), 1), /* [2] */
2342+ BTF_END_RAW,
2343+ },
2344+ BTF_STR_SEC(""),
2345+ .map_type = BPF_MAP_TYPE_ARRAY,
2346+ .map_name = "volatile_type_check_btf",
2347+ .key_size = sizeof(int),
2348+ .value_size = sizeof(int),
2349+ .key_type_id = 1,
2350+ .value_type_id = 1,
2351+ .max_entries = 4,
2352+ .btf_load_err = true,
2353+ .err_str = "Invalid btf_info kind_flag",
2354+},
2355+
2356+{
2357+ .descr = "invalid const kind_flag",
2358+ .raw_types = {
2359+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2360+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 1, 0), 1), /* [2] */
2361+ BTF_END_RAW,
2362+ },
2363+ BTF_STR_SEC(""),
2364+ .map_type = BPF_MAP_TYPE_ARRAY,
2365+ .map_name = "const_type_check_btf",
2366+ .key_size = sizeof(int),
2367+ .value_size = sizeof(int),
2368+ .key_type_id = 1,
2369+ .value_type_id = 1,
2370+ .max_entries = 4,
2371+ .btf_load_err = true,
2372+ .err_str = "Invalid btf_info kind_flag",
2373+},
2374+
2375+{
2376+ .descr = "invalid restrict kind_flag",
2377+ .raw_types = {
2378+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2379+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_RESTRICT, 1, 0), 1), /* [2] */
2380+ BTF_END_RAW,
2381+ },
2382+ BTF_STR_SEC(""),
2383+ .map_type = BPF_MAP_TYPE_ARRAY,
2384+ .map_name = "restrict_type_check_btf",
2385+ .key_size = sizeof(int),
2386+ .value_size = sizeof(int),
2387+ .key_type_id = 1,
2388+ .value_type_id = 1,
2389+ .max_entries = 4,
2390+ .btf_load_err = true,
2391+ .err_str = "Invalid btf_info kind_flag",
2392+},
2393+
2394+{
2395+ .descr = "invalid func kind_flag",
2396+ .raw_types = {
2397+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2398+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0), /* [2] */
2399+ BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_FUNC, 1, 0), 2), /* [3] */
2400+ BTF_END_RAW,
2401+ },
2402+ BTF_STR_SEC("\0A"),
2403+ .map_type = BPF_MAP_TYPE_ARRAY,
2404+ .map_name = "func_type_check_btf",
2405+ .key_size = sizeof(int),
2406+ .value_size = sizeof(int),
2407+ .key_type_id = 1,
2408+ .value_type_id = 1,
2409+ .max_entries = 4,
2410+ .btf_load_err = true,
2411+ .err_str = "Invalid btf_info kind_flag",
2412+},
2413+
2414+{
2415+ .descr = "invalid func_proto kind_flag",
2416+ .raw_types = {
2417+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2418+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 1, 0), 0), /* [2] */
2419+ BTF_END_RAW,
2420+ },
2421+ BTF_STR_SEC(""),
2422+ .map_type = BPF_MAP_TYPE_ARRAY,
2423+ .map_name = "func_proto_type_check_btf",
2424+ .key_size = sizeof(int),
2425+ .value_size = sizeof(int),
2426+ .key_type_id = 1,
2427+ .value_type_id = 1,
2428+ .max_entries = 4,
2429+ .btf_load_err = true,
2430+ .err_str = "Invalid btf_info kind_flag",
2431+},
2432+
2433+{
2434+ .descr = "valid struct, kind_flag, bitfield_size = 0",
2435+ .raw_types = {
2436+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2437+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 8), /* [2] */
2438+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 0)),
2439+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(0, 32)),
2440+ BTF_END_RAW,
2441+ },
2442+ BTF_STR_SEC("\0A\0B"),
2443+ .map_type = BPF_MAP_TYPE_ARRAY,
2444+ .map_name = "struct_type_check_btf",
2445+ .key_size = sizeof(int),
2446+ .value_size = sizeof(int),
2447+ .key_type_id = 1,
2448+ .value_type_id = 1,
2449+ .max_entries = 4,
2450+},
2451+
2452+{
2453+ .descr = "valid struct, kind_flag, int member, bitfield_size != 0",
2454+ .raw_types = {
2455+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2456+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */
2457+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2458+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 4)),
2459+ BTF_END_RAW,
2460+ },
2461+ BTF_STR_SEC("\0A\0B"),
2462+ .map_type = BPF_MAP_TYPE_ARRAY,
2463+ .map_name = "struct_type_check_btf",
2464+ .key_size = sizeof(int),
2465+ .value_size = sizeof(int),
2466+ .key_type_id = 1,
2467+ .value_type_id = 1,
2468+ .max_entries = 4,
2469+},
2470+
2471+{
2472+ .descr = "valid union, kind_flag, int member, bitfield_size != 0",
2473+ .raw_types = {
2474+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2475+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [2] */
2476+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2477+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(4, 0)),
2478+ BTF_END_RAW,
2479+ },
2480+ BTF_STR_SEC("\0A\0B"),
2481+ .map_type = BPF_MAP_TYPE_ARRAY,
2482+ .map_name = "union_type_check_btf",
2483+ .key_size = sizeof(int),
2484+ .value_size = sizeof(int),
2485+ .key_type_id = 1,
2486+ .value_type_id = 1,
2487+ .max_entries = 4,
2488+},
2489+
2490+{
2491+ .descr = "valid struct, kind_flag, enum member, bitfield_size != 0",
2492+ .raw_types = {
2493+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2494+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2495+ BTF_ENUM_ENC(NAME_TBD, 0),
2496+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
2497+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2498+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 4)),
2499+ BTF_END_RAW,
2500+ },
2501+ BTF_STR_SEC("\0A\0B\0C"),
2502+ .map_type = BPF_MAP_TYPE_ARRAY,
2503+ .map_name = "struct_type_check_btf",
2504+ .key_size = sizeof(int),
2505+ .value_size = sizeof(int),
2506+ .key_type_id = 1,
2507+ .value_type_id = 1,
2508+ .max_entries = 4,
2509+},
2510+
2511+{
2512+ .descr = "valid union, kind_flag, enum member, bitfield_size != 0",
2513+ .raw_types = {
2514+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2515+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2516+ BTF_ENUM_ENC(NAME_TBD, 0),
2517+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
2518+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2519+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(4, 0)),
2520+ BTF_END_RAW,
2521+ },
2522+ BTF_STR_SEC("\0A\0B\0C"),
2523+ .map_type = BPF_MAP_TYPE_ARRAY,
2524+ .map_name = "union_type_check_btf",
2525+ .key_size = sizeof(int),
2526+ .value_size = sizeof(int),
2527+ .key_type_id = 1,
2528+ .value_type_id = 1,
2529+ .max_entries = 4,
2530+},
2531+
2532+{
2533+ .descr = "valid struct, kind_flag, typedef member, bitfield_size != 0",
2534+ .raw_types = {
2535+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2536+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2537+ BTF_ENUM_ENC(NAME_TBD, 0),
2538+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4),/* [3] */
2539+ BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2540+ BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 4)),
2541+ BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */
2542+ BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */
2543+ BTF_END_RAW,
2544+ },
2545+ BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2546+ .map_type = BPF_MAP_TYPE_ARRAY,
2547+ .map_name = "struct_type_check_btf",
2548+ .key_size = sizeof(int),
2549+ .value_size = sizeof(int),
2550+ .key_type_id = 1,
2551+ .value_type_id = 1,
2552+ .max_entries = 4,
2553+},
2554+
2555+{
2556+ .descr = "valid union, kind_flag, typedef member, bitfield_size != 0",
2557+ .raw_types = {
2558+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2559+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2560+ BTF_ENUM_ENC(NAME_TBD, 0),
2561+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 4), /* [3] */
2562+ BTF_MEMBER_ENC(NAME_TBD, 4, BTF_MEMBER_OFFSET(4, 0)),
2563+ BTF_MEMBER_ENC(NAME_TBD, 5, BTF_MEMBER_OFFSET(4, 0)),
2564+ BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [4] */
2565+ BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [5] */
2566+ BTF_END_RAW,
2567+ },
2568+ BTF_STR_SEC("\0A\0B\0C\0D\0E"),
2569+ .map_type = BPF_MAP_TYPE_ARRAY,
2570+ .map_name = "union_type_check_btf",
2571+ .key_size = sizeof(int),
2572+ .value_size = sizeof(int),
2573+ .key_type_id = 1,
2574+ .value_type_id = 1,
2575+ .max_entries = 4,
2576+},
2577+
2578+{
2579+ .descr = "invalid struct, kind_flag, bitfield_size greater than struct size",
2580+ .raw_types = {
2581+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2582+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [2] */
2583+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2584+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 20)),
2585+ BTF_END_RAW,
2586+ },
2587+ BTF_STR_SEC("\0A\0B"),
2588+ .map_type = BPF_MAP_TYPE_ARRAY,
2589+ .map_name = "struct_type_check_btf",
2590+ .key_size = sizeof(int),
2591+ .value_size = sizeof(int),
2592+ .key_type_id = 1,
2593+ .value_type_id = 1,
2594+ .max_entries = 4,
2595+ .btf_load_err = true,
2596+ .err_str = "Member exceeds struct_size",
2597+},
2598+
2599+{
2600+ .descr = "invalid struct, kind_flag, bitfield base_type int not regular",
2601+ .raw_types = {
2602+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2603+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 20, 4), /* [2] */
2604+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */
2605+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 0)),
2606+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(20, 20)),
2607+ BTF_END_RAW,
2608+ },
2609+ BTF_STR_SEC("\0A\0B"),
2610+ .map_type = BPF_MAP_TYPE_ARRAY,
2611+ .map_name = "struct_type_check_btf",
2612+ .key_size = sizeof(int),
2613+ .value_size = sizeof(int),
2614+ .key_type_id = 1,
2615+ .value_type_id = 1,
2616+ .max_entries = 4,
2617+ .btf_load_err = true,
2618+ .err_str = "Invalid member base type",
2619+},
2620+
2621+{
2622+ .descr = "invalid struct, kind_flag, base_type int not regular",
2623+ .raw_types = {
2624+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2625+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 12, 4), /* [2] */
2626+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 4), /* [3] */
2627+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 0)),
2628+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(8, 8)),
2629+ BTF_END_RAW,
2630+ },
2631+ BTF_STR_SEC("\0A\0B"),
2632+ .map_type = BPF_MAP_TYPE_ARRAY,
2633+ .map_name = "struct_type_check_btf",
2634+ .key_size = sizeof(int),
2635+ .value_size = sizeof(int),
2636+ .key_type_id = 1,
2637+ .value_type_id = 1,
2638+ .max_entries = 4,
2639+ .btf_load_err = true,
2640+ .err_str = "Invalid member base type",
2641+},
2642+
2643+{
2644+ .descr = "invalid union, kind_flag, bitfield_size greater than struct size",
2645+ .raw_types = {
2646+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2647+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 1, 2), 2), /* [2] */
2648+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(8, 0)),
2649+ BTF_MEMBER_ENC(NAME_TBD, 1, BTF_MEMBER_OFFSET(20, 0)),
2650+ BTF_END_RAW,
2651+ },
2652+ BTF_STR_SEC("\0A\0B"),
2653+ .map_type = BPF_MAP_TYPE_ARRAY,
2654+ .map_name = "union_type_check_btf",
2655+ .key_size = sizeof(int),
2656+ .value_size = sizeof(int),
2657+ .key_type_id = 1,
2658+ .value_type_id = 1,
2659+ .max_entries = 4,
2660+ .btf_load_err = true,
2661+ .err_str = "Member exceeds struct_size",
2662+},
2663+
2664+{
2665+ .descr = "invalid struct, kind_flag, int member, bitfield_size = 0, wrong byte alignment",
2666+ .raw_types = {
2667+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2668+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
2669+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */
2670+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2671+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2672+ BTF_END_RAW,
2673+ },
2674+ BTF_STR_SEC("\0A\0B"),
2675+ .map_type = BPF_MAP_TYPE_ARRAY,
2676+ .map_name = "struct_type_check_btf",
2677+ .key_size = sizeof(int),
2678+ .value_size = sizeof(int),
2679+ .key_type_id = 1,
2680+ .value_type_id = 1,
2681+ .max_entries = 4,
2682+ .btf_load_err = true,
2683+ .err_str = "Invalid member offset",
2684+},
2685+
2686+{
2687+ .descr = "invalid struct, kind_flag, enum member, bitfield_size = 0, wrong byte alignment",
2688+ .raw_types = {
2689+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
2690+ BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [2] */
2691+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 1), 4), /* [2] */
2692+ BTF_ENUM_ENC(NAME_TBD, 0),
2693+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 2), 12), /* [3] */
2694+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 0)),
2695+ BTF_MEMBER_ENC(NAME_TBD, 2, BTF_MEMBER_OFFSET(0, 36)),
2696+ BTF_END_RAW,
2697+ },
2698+ BTF_STR_SEC("\0A\0B\0C"),
2699+ .map_type = BPF_MAP_TYPE_ARRAY,
2700+ .map_name = "struct_type_check_btf",
2701+ .key_size = sizeof(int),
2702+ .value_size = sizeof(int),
2703+ .key_type_id = 1,
2704+ .value_type_id = 1,
2705+ .max_entries = 4,
2706+ .btf_load_err = true,
2707+ .err_str = "Invalid member offset",
2708+},
2709+
22182710 }; /* struct btf_raw_test raw_tests[] */
22192711
22202712 static const char *get_next_str(const char *start, const char *end)
@@ -2916,7 +3408,7 @@ static int do_test_file(unsigned int test_num) · 695 unmodified lines
29163408 goto done;
29173409 }
29183410 rec_size = info.func_info_rec_size;
2919− if (CHECK(rec_size < 4,
3411+ if (CHECK(rec_size != sizeof(struct bpf_func_info),
29203412 "incorrect info.func_info_rec_size (1st) %d\n", rec_size)) {
29213413 err = -1;
29223414 goto done;
@@ -3036,7 +3528,8 @@ struct pprint_mapv { · 113 unmodified lines
30363528 } aenum;
30373529 };
30383530
3039−static struct btf_raw_test pprint_test_template = {
3531+static struct btf_raw_test pprint_test_template[] = {
3532+{
30403533 .raw_types = {
30413534 /* unsighed char */ /* [1] */
30423535 BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
@@ -3086,13 +3579,140 @@ static struct btf_raw_test pprint_test_template = { · 43 unmodified lines
30863579 BTF_MEMBER_ENC(NAME_TBD, 15, 192), /* aenum */
30873580 BTF_END_RAW,
30883581 },
3089− .str_sec = "\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum",
3090− .str_sec_size = sizeof("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"),
3582+ BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"),
3583+ .key_size = sizeof(unsigned int),
3584+ .value_size = sizeof(struct pprint_mapv),
3585+ .key_type_id = 3, /* unsigned int */
3586+ .value_type_id = 16, /* struct pprint_mapv */
3587+ .max_entries = 128 * 1024,
3588+},
3589+
3590+{
3591+ /* this type will have the same type as the
3592+ * first .raw_types definition, but struct type will
3593+ * be encoded with kind_flag set.
3594+ */
3595+ .raw_types = {
3596+ /* unsighed char */ /* [1] */
3597+ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3598+ /* unsigned short */ /* [2] */
3599+ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3600+ /* unsigned int */ /* [3] */
3601+ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3602+ /* int */ /* [4] */
3603+ BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3604+ /* unsigned long long */ /* [5] */
3605+ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3606+ BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */
3607+ BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */
3608+ /* uint8_t[8] */ /* [8] */
3609+ BTF_TYPE_ARRAY_ENC(9, 1, 8),
3610+ /* typedef unsigned char uint8_t */ /* [9] */
3611+ BTF_TYPEDEF_ENC(NAME_TBD, 1),
3612+ /* typedef unsigned short uint16_t */ /* [10] */
3613+ BTF_TYPEDEF_ENC(NAME_TBD, 2),
3614+ /* typedef unsigned int uint32_t */ /* [11] */
3615+ BTF_TYPEDEF_ENC(NAME_TBD, 3),
3616+ /* typedef int int32_t */ /* [12] */
3617+ BTF_TYPEDEF_ENC(NAME_TBD, 4),
3618+ /* typedef unsigned long long uint64_t *//* [13] */
3619+ BTF_TYPEDEF_ENC(NAME_TBD, 5),
3620+ /* union (anon) */ /* [14] */
3621+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3622+ BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3623+ BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3624+ /* enum (anon) */ /* [15] */
3625+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3626+ BTF_ENUM_ENC(NAME_TBD, 0),
3627+ BTF_ENUM_ENC(NAME_TBD, 1),
3628+ BTF_ENUM_ENC(NAME_TBD, 2),
3629+ BTF_ENUM_ENC(NAME_TBD, 3),
3630+ /* struct pprint_mapv */ /* [16] */
3631+ BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 8), 32),
3632+ BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */
3633+ BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
3634+ BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
3635+ BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
3636+ BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
3637+ BTF_MEMBER_ENC(NAME_TBD, 6, BTF_MEMBER_OFFSET(2, 126)), /* unused_bits2b */
3638+ BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */
3639+ BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */
3640+ BTF_END_RAW,
3641+ },
3642+ BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum"),
3643+ .key_size = sizeof(unsigned int),
3644+ .value_size = sizeof(struct pprint_mapv),
3645+ .key_type_id = 3, /* unsigned int */
3646+ .value_type_id = 16, /* struct pprint_mapv */
3647+ .max_entries = 128 * 1024,
3648+},
3649+
3650+{
3651+ /* this type will have the same layout as the
3652+ * first .raw_types definition. The struct type will
3653+ * be encoded with kind_flag set, bitfield members
3654+ * are added typedef/const/volatile, and bitfield members
3655+ * will have both int and enum types.
3656+ */
3657+ .raw_types = {
3658+ /* unsighed char */ /* [1] */
3659+ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 8, 1),
3660+ /* unsigned short */ /* [2] */
3661+ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 16, 2),
3662+ /* unsigned int */ /* [3] */
3663+ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 32, 4),
3664+ /* int */ /* [4] */
3665+ BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4),
3666+ /* unsigned long long */ /* [5] */
3667+ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8),
3668+ BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [6] */
3669+ BTF_TYPE_INT_ENC(0, 0, 0, 32, 4), /* [7] */
3670+ /* uint8_t[8] */ /* [8] */
3671+ BTF_TYPE_ARRAY_ENC(9, 1, 8),
3672+ /* typedef unsigned char uint8_t */ /* [9] */
3673+ BTF_TYPEDEF_ENC(NAME_TBD, 1),
3674+ /* typedef unsigned short uint16_t */ /* [10] */
3675+ BTF_TYPEDEF_ENC(NAME_TBD, 2),
3676+ /* typedef unsigned int uint32_t */ /* [11] */
3677+ BTF_TYPEDEF_ENC(NAME_TBD, 3),
3678+ /* typedef int int32_t */ /* [12] */
3679+ BTF_TYPEDEF_ENC(NAME_TBD, 4),
3680+ /* typedef unsigned long long uint64_t *//* [13] */
3681+ BTF_TYPEDEF_ENC(NAME_TBD, 5),
3682+ /* union (anon) */ /* [14] */
3683+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_UNION, 0, 2), 8),
3684+ BTF_MEMBER_ENC(NAME_TBD, 13, 0),/* uint64_t ui64; */
3685+ BTF_MEMBER_ENC(NAME_TBD, 8, 0), /* uint8_t ui8a[8]; */
3686+ /* enum (anon) */ /* [15] */
3687+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_ENUM, 0, 4), 4),
3688+ BTF_ENUM_ENC(NAME_TBD, 0),
3689+ BTF_ENUM_ENC(NAME_TBD, 1),
3690+ BTF_ENUM_ENC(NAME_TBD, 2),
3691+ BTF_ENUM_ENC(NAME_TBD, 3),
3692+ /* struct pprint_mapv */ /* [16] */
3693+ BTF_TYPE_ENC(NAME_TBD, BTF_INFO_ENC(BTF_KIND_STRUCT, 1, 8), 32),
3694+ BTF_MEMBER_ENC(NAME_TBD, 11, BTF_MEMBER_OFFSET(0, 0)), /* uint32_t ui32 */
3695+ BTF_MEMBER_ENC(NAME_TBD, 10, BTF_MEMBER_OFFSET(0, 32)), /* uint16_t ui16 */
3696+ BTF_MEMBER_ENC(NAME_TBD, 12, BTF_MEMBER_OFFSET(0, 64)), /* int32_t si32 */
3697+ BTF_MEMBER_ENC(NAME_TBD, 17, BTF_MEMBER_OFFSET(2, 96)), /* unused_bits2a */
3698+ BTF_MEMBER_ENC(NAME_TBD, 7, BTF_MEMBER_OFFSET(28, 98)), /* bits28 */
3699+ BTF_MEMBER_ENC(NAME_TBD, 19, BTF_MEMBER_OFFSET(2, 126)),/* unused_bits2b */
3700+ BTF_MEMBER_ENC(0, 14, BTF_MEMBER_OFFSET(0, 128)), /* union (anon) */
3701+ BTF_MEMBER_ENC(NAME_TBD, 15, BTF_MEMBER_OFFSET(0, 192)), /* aenum */
3702+ /* typedef unsigned int ___int */ /* [17] */
3703+ BTF_TYPEDEF_ENC(NAME_TBD, 18),
3704+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_VOLATILE, 0, 0), 6), /* [18] */
3705+ BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_CONST, 0, 0), 15), /* [19] */
3706+ BTF_END_RAW,
3707+ },
3708+ BTF_STR_SEC("\0unsigned char\0unsigned short\0unsigned int\0int\0unsigned long long\0uint8_t\0uint16_t\0uint32_t\0int32_t\0uint64_t\0ui64\0ui8a\0ENUM_ZERO\0ENUM_ONE\0ENUM_TWO\0ENUM_THREE\0pprint_mapv\0ui32\0ui16\0si32\0unused_bits2a\0bits28\0unused_bits2b\0aenum\0___int"),
30913709 .key_size = sizeof(unsigned int),
30923710 .value_size = sizeof(struct pprint_mapv),
30933711 .key_type_id = 3, /* unsigned int */
30943712 .value_type_id = 16, /* struct pprint_mapv */
30953713 .max_entries = 128 * 1024,
3714+},
3715+
30963716 };
30973717
30983718 static struct btf_pprint_test_meta {
@@ -3195,9 +3815,9 @@ static int check_line(const char *expected_line, int nexpected_line, · 96 unmodified lines
31953815 }
31963816
31973817
3198−static int do_test_pprint(void)
3818+static int do_test_pprint(int test_num)
31993819 {
3200− const struct btf_raw_test *test = &pprint_test_template;
3820+ const struct btf_raw_test *test = &pprint_test_template[test_num];
32013821 struct bpf_create_map_attr create_attr = {};
32023822 bool ordered_map, lossless_map, percpu_map;
32033823 int err, ret, num_cpus, rounded_value_size;
@@ -3213,7 +3833,7 @@ static int do_test_pprint(void) · 9 unmodified lines
32133833 uint8_t *raw_btf;
32143834 ssize_t nread;
32153835
3216− fprintf(stderr, "%s......", test->descr);
3836+ fprintf(stderr, "%s(#%d)......", test->descr, test_num);
32173837 raw_btf = btf_raw_create(&hdr_tmpl, test->raw_types,
32183838 test->str_sec, test->str_sec_size,
32193839 &raw_btf_size, NULL);
@@ -3406,15 +4026,27 @@ static int test_pprint(void) · 186 unmodified lines
34064026 unsigned int i;
34074027 int err = 0;
34084028
4029+ /* test various maps with the first test template */
34094030 for (i = 0; i < ARRAY_SIZE(pprint_tests_meta); i++) {
3410− pprint_test_template.descr = pprint_tests_meta[i].descr;
3411− pprint_test_template.map_type = pprint_tests_meta[i].map_type;
3412− pprint_test_template.map_name = pprint_tests_meta[i].map_name;
3413− pprint_test_template.ordered_map = pprint_tests_meta[i].ordered_map;
3414− pprint_test_template.lossless_map = pprint_tests_meta[i].lossless_map;
3415− pprint_test_template.percpu_map = pprint_tests_meta[i].percpu_map;
3416−
3417− err |= count_result(do_test_pprint());
4031+ pprint_test_template[0].descr = pprint_tests_meta[i].descr;
4032+ pprint_test_template[0].map_type = pprint_tests_meta[i].map_type;
4033+ pprint_test_template[0].map_name = pprint_tests_meta[i].map_name;
4034+ pprint_test_template[0].ordered_map = pprint_tests_meta[i].ordered_map;
4035+ pprint_test_template[0].lossless_map = pprint_tests_meta[i].lossless_map;
4036+ pprint_test_template[0].percpu_map = pprint_tests_meta[i].percpu_map;
4037+
4038+ err |= count_result(do_test_pprint(0));
4039+ }
4040+
4041+ /* test rest test templates with the first map */
4042+ for (i = 1; i < ARRAY_SIZE(pprint_test_template); i++) {
4043+ pprint_test_template[i].descr = pprint_tests_meta[0].descr;
4044+ pprint_test_template[i].map_type = pprint_tests_meta[0].map_type;
4045+ pprint_test_template[i].map_name = pprint_tests_meta[0].map_name;
4046+ pprint_test_template[i].ordered_map = pprint_tests_meta[0].ordered_map;
4047+ pprint_test_template[i].lossless_map = pprint_tests_meta[0].lossless_map;
4048+ pprint_test_template[i].percpu_map = pprint_tests_meta[0].percpu_map;
4049+ err |= count_result(do_test_pprint(i));
34184050 }
34194051
34204052 return err;
@@ -3621,6 +4253,33 @@ static struct prog_info_raw_test { · 200 unmodified lines
36214253 .expected_prog_load_failure = true,
36224254 },
36234255
4256+{
4257+ .descr = "line_info (Zero bpf insn code)",
4258+ .raw_types = {
4259+ BTF_TYPE_INT_ENC(NAME_TBD, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
4260+ BTF_TYPE_INT_ENC(NAME_TBD, 0, 0, 64, 8), /* [2] */
4261+ BTF_TYPEDEF_ENC(NAME_TBD, 2), /* [3] */
4262+ BTF_END_RAW,
4263+ },
4264+ BTF_STR_SEC("\0int\0unsigned long\0u64\0u64 a=1;\0return a;"),
4265+ .insns = {
4266+ BPF_LD_IMM64(BPF_REG_0, 1),
4267+ BPF_EXIT_INSN(),
4268+ },
4269+ .prog_type = BPF_PROG_TYPE_TRACEPOINT,
4270+ .func_info_cnt = 0,
4271+ .line_info = {
4272+ BPF_LINE_INFO_ENC(0, 0, NAME_TBD, 1, 10),
4273+ BPF_LINE_INFO_ENC(1, 0, 0, 2, 9),
4274+ BPF_LINE_INFO_ENC(2, 0, NAME_TBD, 3, 8),
4275+ BTF_END_RAW,
4276+ },
4277+ .line_info_rec_size = sizeof(struct bpf_line_info),
4278+ .nr_jited_ksyms = 1,
4279+ .err_str = "Invalid insn code at line_info[1]",
4280+ .expected_prog_load_failure = true,
4281+},
4282+
36244283 {
36254284 .descr = "line_info (No subprog. zero tailing line_info",
36264285 .raw_types = {
@@ -3912,7 +4571,7 @@ static int test_get_finfo(const struct prog_info_raw_test *test, · 285 unmodified lines
39124571 }
39134572
39144573 rec_size = info.func_info_rec_size;
3915− if (CHECK(rec_size < 8,
4574+ if (CHECK(rec_size != sizeof(struct bpf_func_info),
39164575 "incorrect info.func_info_rec_size (1st) %d", rec_size)) {
39174576 return -1;
39184577 }
@@ -3941,19 +4600,13 @@ static int test_get_finfo(const struct prog_info_raw_test *test, · 22 unmodified lines
39414600 err = -1;
39424601 goto done;
39434602 }
3944− if (CHECK(info.func_info_rec_size < 8,
4603+ if (CHECK(info.func_info_rec_size != rec_size,
39454604 "incorrect info.func_info_rec_size (2nd) %d",
39464605 info.func_info_rec_size)) {
39474606 err = -1;
39484607 goto done;
39494608 }
39504609
3951− if (CHECK(!info.func_info,
3952− "info.func_info == 0. kernel.kptr_restrict is set?")) {
3953− err = -1;
3954− goto done;
3955− }
3956−
39574610 finfo = func_info;
39584611 for (i = 0; i < test->func_info_cnt; i++) {
39594612 if (CHECK(finfo->type_id != test->func_info[i][1],
@@ -4023,8 +4676,8 @@ static int test_get_linfo(const struct prog_info_raw_test *test, · 63 unmodified lines
40234676 goto done;
40244677 }
40254678
4026− if (CHECK(info.line_info_rec_size < 16 ||
4027− info.jited_line_info_rec_size < 8,
4679+ if (CHECK(info.line_info_rec_size != sizeof(struct bpf_line_info) ||
4680+ info.jited_line_info_rec_size != sizeof(__u64),
40284681 "info: line_info_rec_size:%u(userspace expected:%u) jited_line_info_rec_size:%u(userspace expected:%u)",
40294682 info.line_info_rec_size, rec_size,
40304683 info.jited_line_info_rec_size, jited_rec_size)) {
@@ -4077,7 +4730,6 @@ static int test_get_linfo(const struct prog_info_raw_test *test, · 46 unmodified lines
40774730 * Other fields are not the concern of this test.
40784731 */
40794732 if (CHECK(err == -1 ||
4080− !info.line_info ||
40814733 info.nr_line_info != cnt ||
40824734 (jited_cnt && !info.jited_line_info) ||
40834735 info.nr_jited_line_info != jited_cnt ||
tools/testing/selftests/bpf/test_progs.c+4−4
@@ -51,10 +51,10 @@ static struct { · 50 unmodified lines
5151 struct iphdr iph;
5252 struct tcphdr tcp;
5353 } __packed pkt_v4 = {
54− .eth.h_proto = bpf_htons(ETH_P_IP),
54+ .eth.h_proto = __bpf_constant_htons(ETH_P_IP),
5555 .iph.ihl = 5,
5656 .iph.protocol = 6,
57− .iph.tot_len = bpf_htons(MAGIC_BYTES),
57+ .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
5858 .tcp.urg_ptr = 123,
5959 };
6060
@@ -64,9 +64,9 @@ static struct { · 3 unmodified lines
6464 struct ipv6hdr iph;
6565 struct tcphdr tcp;
6666 } __packed pkt_v6 = {
67− .eth.h_proto = bpf_htons(ETH_P_IPV6),
67+ .eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
6868 .iph.nexthdr = 6,
69− .iph.payload_len = bpf_htons(MAGIC_BYTES),
69+ .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
7070 .tcp.urg_ptr = 123,
7171 };
7272
tools/testing/selftests/bpf/test_verifier.c+354−37
@@ -49,6 +49,7 @@ · 48 unmodified lines
4949 #define MAX_INSNS BPF_MAXINSNS
5050 #define MAX_FIXUPS 8
5151 #define MAX_NR_MAPS 13
52+#define MAX_TEST_RUNS 8
5253 #define POINTER_VALUE 0xcafe4all
5354 #define TEST_DATA_LEN 64
5455
@@ -76,7 +77,7 @@ struct bpf_test { · 21 unmodified lines
7677 int fixup_percpu_cgroup_storage[MAX_FIXUPS];
7778 const char *errstr;
7879 const char *errstr_unpriv;
79− uint32_t retval, retval_unpriv;
80+ uint32_t retval, retval_unpriv, insn_processed;
8081 enum {
8182 UNDEF,
8283 ACCEPT,
@@ -86,6 +87,14 @@ struct bpf_test { · 3 unmodified lines
8687 uint8_t flags;
8788 __u8 data[TEST_DATA_LEN];
8889 void (*fill_helper)(struct bpf_test *self);
90+ uint8_t runs;
91+ struct {
92+ uint32_t retval, retval_unpriv;
93+ union {
94+ __u8 data[TEST_DATA_LEN];
95+ __u64 data64[TEST_DATA_LEN / 8];
96+ };
97+ } retvals[MAX_TEST_RUNS];
8998 };
9099
91100 /* Note we want this to be 64 bit aligned so that the end of our array is
@@ -1001,14 +1010,44 @@ static struct bpf_test tests[] = { · 909 unmodified lines
10011010 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
10021011 /* mess up with R1 pointer on stack */
10031012 BPF_ST_MEM(BPF_B, BPF_REG_10, -7, 0x23),
1004− /* fill back into R0 should fail */
1013+ /* fill back into R0 is fine for priv.
1014+ * R0 now becomes SCALAR_VALUE.
1015+ */
10051016 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
1017+ /* Load from R0 should fail. */
1018+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
10061019 BPF_EXIT_INSN(),
10071020 },
10081021 .errstr_unpriv = "attempt to corrupt spilled",
1009− .errstr = "corrupted spill",
1022+ .errstr = "R0 invalid mem access 'inv",
10101023 .result = REJECT,
10111024 },
1025+ {
1026+ "check corrupted spill/fill, LSB",
1027+ .insns = {
1028+ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
1029+ BPF_ST_MEM(BPF_H, BPF_REG_10, -8, 0xcafe),
1030+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
1031+ BPF_EXIT_INSN(),
1032+ },
1033+ .errstr_unpriv = "attempt to corrupt spilled",
1034+ .result_unpriv = REJECT,
1035+ .result = ACCEPT,
1036+ .retval = POINTER_VALUE,
1037+ },
1038+ {
1039+ "check corrupted spill/fill, MSB",
1040+ .insns = {
1041+ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -8),
1042+ BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0x12345678),
1043+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_10, -8),
1044+ BPF_EXIT_INSN(),
1045+ },
1046+ .errstr_unpriv = "attempt to corrupt spilled",
1047+ .result_unpriv = REJECT,
1048+ .result = ACCEPT,
1049+ .retval = POINTER_VALUE,
1050+ },
10121051 {
10131052 "invalid src register in STX",
10141053 .insns = {
@@ -1813,10 +1852,20 @@ static struct bpf_test tests[] = { · 798 unmodified lines
18131852 .prog_type = BPF_PROG_TYPE_SK_SKB,
18141853 },
18151854 {
1816− "invalid 64B read of family in SK_MSG",
1855+ "valid access size in SK_MSG",
1856+ .insns = {
1857+ BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1858+ offsetof(struct sk_msg_md, size)),
1859+ BPF_EXIT_INSN(),
1860+ },
1861+ .result = ACCEPT,
1862+ .prog_type = BPF_PROG_TYPE_SK_MSG,
1863+ },
1864+ {
1865+ "invalid 64B read of size in SK_MSG",
18171866 .insns = {
18181867 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1819− offsetof(struct sk_msg_md, family)),
1868+ offsetof(struct sk_msg_md, size)),
18201869 BPF_EXIT_INSN(),
18211870 },
18221871 .errstr = "invalid bpf_context access",
@@ -1827,10 +1876,10 @@ static struct bpf_test tests[] = { · 4 unmodified lines
18271876 "invalid read past end of SK_MSG",
18281877 .insns = {
18291878 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1830− offsetof(struct sk_msg_md, local_port) + 4),
1879+ offsetof(struct sk_msg_md, size) + 4),
18311880 BPF_EXIT_INSN(),
18321881 },
1833− .errstr = "R0 !read_ok",
1882+ .errstr = "invalid bpf_context access",
18341883 .result = REJECT,
18351884 .prog_type = BPF_PROG_TYPE_SK_MSG,
18361885 },
@@ -13647,6 +13696,28 @@ static struct bpf_test tests[] = { · 11810 unmodified lines
1364713696 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
1364813697 .result = ACCEPT,
1364913698 },
13699+ {
13700+ "allocated_stack",
13701+ .insns = {
13702+ BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
13703+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
13704+ BPF_ALU64_REG(BPF_MOV, BPF_REG_7, BPF_REG_0),
13705+ BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
13706+ BPF_MOV64_IMM(BPF_REG_0, 0),
13707+ BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
13708+ BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, -8),
13709+ BPF_STX_MEM(BPF_B, BPF_REG_10, BPF_REG_7, -9),
13710+ BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_10, -9),
13711+ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
13712+ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
13713+ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
13714+ BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
13715+ BPF_EXIT_INSN(),
13716+ },
13717+ .result = ACCEPT,
13718+ .result_unpriv = ACCEPT,
13719+ .insn_processed = 15,
13720+ },
1365013721 {
1365113722 "reference tracking in call: free reference in subprog and outside",
1365213723 .insns = {
@@ -14099,6 +14170,7 @@ static struct bpf_test tests[] = { · 446 unmodified lines
1409914170 .errstr_unpriv = "R1 leaks addr",
1410014171 .result = REJECT,
1410114172 },
14173+ {
1410214174 "calls: cross frame pruning",
1410314175 .insns = {
1410414176 /* r8 = !!random();
@@ -14122,10 +14194,199 @@ static struct bpf_test tests[] = { · 17 unmodified lines
1412214194 },
1412314195 .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
1412414196 .errstr_unpriv = "function calls to other bpf functions are allowed for root only",
14197+ .result = REJECT,
14198+ },
14199+ {
14200+ "jset: functional",
14201+ .insns = {
14202+ /* r0 = 0 */
14203+ BPF_MOV64_IMM(BPF_REG_0, 0),
14204+ /* prep for direct packet access via r2 */
14205+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
14206+ offsetof(struct __sk_buff, data)),
14207+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
14208+ offsetof(struct __sk_buff, data_end)),
14209+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
14210+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
14211+ BPF_JMP_REG(BPF_JLE, BPF_REG_4, BPF_REG_3, 1),
14212+ BPF_EXIT_INSN(),
14213+
14214+ BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_2, 0),
14215+
14216+ /* reg, bit 63 or bit 0 set, taken */
14217+ BPF_LD_IMM64(BPF_REG_8, 0x8000000000000001),
14218+ BPF_JMP_REG(BPF_JSET, BPF_REG_7, BPF_REG_8, 1),
14219+ BPF_EXIT_INSN(),
14220+
14221+ /* reg, bit 62, not taken */
14222+ BPF_LD_IMM64(BPF_REG_8, 0x4000000000000000),
14223+ BPF_JMP_REG(BPF_JSET, BPF_REG_7, BPF_REG_8, 1),
14224+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
14225+ BPF_EXIT_INSN(),
14226+
14227+ /* imm, any bit set, taken */
14228+ BPF_JMP_IMM(BPF_JSET, BPF_REG_7, -1, 1),
14229+ BPF_EXIT_INSN(),
14230+
14231+ /* imm, bit 31 set, taken */
14232+ BPF_JMP_IMM(BPF_JSET, BPF_REG_7, 0x80000000, 1),
14233+ BPF_EXIT_INSN(),
14234+
14235+ /* all good - return r0 == 2 */
14236+ BPF_MOV64_IMM(BPF_REG_0, 2),
14237+ BPF_EXIT_INSN(),
14238+ },
14239+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
14240+ .result = ACCEPT,
14241+ .runs = 7,
14242+ .retvals = {
14243+ { .retval = 2,
14244+ .data64 = { (1ULL << 63) | (1U << 31) | (1U << 0), }
14245+ },
14246+ { .retval = 2,
14247+ .data64 = { (1ULL << 63) | (1U << 31), }
14248+ },
14249+ { .retval = 2,
14250+ .data64 = { (1ULL << 31) | (1U << 0), }
14251+ },
14252+ { .retval = 2,
14253+ .data64 = { (__u32)-1, }
14254+ },
14255+ { .retval = 2,
14256+ .data64 = { ~0x4000000000000000ULL, }
14257+ },
14258+ { .retval = 0,
14259+ .data64 = { 0, }
14260+ },
14261+ { .retval = 0,
14262+ .data64 = { ~0ULL, }
14263+ },
14264+ },
14265+ },
14266+ {
14267+ "jset: sign-extend",
14268+ .insns = {
14269+ /* r0 = 0 */
14270+ BPF_MOV64_IMM(BPF_REG_0, 0),
14271+ /* prep for direct packet access via r2 */
14272+ BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
14273+ offsetof(struct __sk_buff, data)),
14274+ BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
14275+ offsetof(struct __sk_buff, data_end)),
14276+ BPF_MOV64_REG(BPF_REG_4, BPF_REG_2),
14277+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_4, 8),
14278+ BPF_JMP_REG(BPF_JLE, BPF_REG_4, BPF_REG_3, 1),
14279+ BPF_EXIT_INSN(),
14280+
14281+ BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_2, 0),
14282+
14283+ BPF_JMP_IMM(BPF_JSET, BPF_REG_7, 0x80000000, 1),
14284+ BPF_EXIT_INSN(),
14285+
14286+ BPF_MOV64_IMM(BPF_REG_0, 2),
14287+ BPF_EXIT_INSN(),
14288+ },
14289+ .prog_type = BPF_PROG_TYPE_SCHED_CLS,
14290+ .result = ACCEPT,
14291+ .retval = 2,
14292+ .data = { 1, 0, 0, 0, 0, 0, 0, 1, },
14293+ },
14294+ {
14295+ "jset: known const compare",
14296+ .insns = {
14297+ BPF_MOV64_IMM(BPF_REG_0, 1),
14298+ BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1),
14299+ BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14300+ BPF_EXIT_INSN(),
14301+ },
14302+ .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14303+ .retval_unpriv = 1,
14304+ .result_unpriv = ACCEPT,
14305+ .retval = 1,
14306+ .result = ACCEPT,
14307+ },
14308+ {
14309+ "jset: known const compare bad",
14310+ .insns = {
14311+ BPF_MOV64_IMM(BPF_REG_0, 0),
14312+ BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1),
14313+ BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14314+ BPF_EXIT_INSN(),
14315+ },
14316+ .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14317+ .errstr_unpriv = "!read_ok",
1412514318 .result_unpriv = REJECT,
1412614319 .errstr = "!read_ok",
1412714320 .result = REJECT,
1412814321 },
14322+ {
14323+ "jset: unknown const compare taken",
14324+ .insns = {
14325+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
14326+ BPF_FUNC_get_prandom_u32),
14327+ BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1),
14328+ BPF_JMP_IMM(BPF_JA, 0, 0, 1),
14329+ BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14330+ BPF_EXIT_INSN(),
14331+ },
14332+ .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14333+ .errstr_unpriv = "!read_ok",
14334+ .result_unpriv = REJECT,
14335+ .errstr = "!read_ok",
14336+ .result = REJECT,
14337+ },
14338+ {
14339+ "jset: unknown const compare not taken",
14340+ .insns = {
14341+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
14342+ BPF_FUNC_get_prandom_u32),
14343+ BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 1, 1),
14344+ BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14345+ BPF_EXIT_INSN(),
14346+ },
14347+ .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14348+ .errstr_unpriv = "!read_ok",
14349+ .result_unpriv = REJECT,
14350+ .errstr = "!read_ok",
14351+ .result = REJECT,
14352+ },
14353+ {
14354+ "jset: half-known const compare",
14355+ .insns = {
14356+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
14357+ BPF_FUNC_get_prandom_u32),
14358+ BPF_ALU64_IMM(BPF_OR, BPF_REG_0, 2),
14359+ BPF_JMP_IMM(BPF_JSET, BPF_REG_0, 3, 1),
14360+ BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14361+ BPF_MOV64_IMM(BPF_REG_0, 0),
14362+ BPF_EXIT_INSN(),
14363+ },
14364+ .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14365+ .result_unpriv = ACCEPT,
14366+ .result = ACCEPT,
14367+ },
14368+ {
14369+ "jset: range",
14370+ .insns = {
14371+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
14372+ BPF_FUNC_get_prandom_u32),
14373+ BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
14374+ BPF_MOV64_IMM(BPF_REG_0, 0),
14375+ BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xff),
14376+ BPF_JMP_IMM(BPF_JSET, BPF_REG_1, 0xf0, 3),
14377+ BPF_JMP_IMM(BPF_JLT, BPF_REG_1, 0x10, 1),
14378+ BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14379+ BPF_EXIT_INSN(),
14380+ BPF_JMP_IMM(BPF_JSET, BPF_REG_1, 0x10, 1),
14381+ BPF_EXIT_INSN(),
14382+ BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0x10, 1),
14383+ BPF_LDX_MEM(BPF_B, BPF_REG_8, BPF_REG_9, 0),
14384+ BPF_EXIT_INSN(),
14385+ },
14386+ .prog_type = BPF_PROG_TYPE_SOCKET_FILTER,
14387+ .result_unpriv = ACCEPT,
14388+ .result = ACCEPT,
14389+ },
1412914390 };
1413014391
1413114392 static int probe_filter_length(const struct bpf_insn *fp)
@@ -14408,16 +14669,42 @@ out: · 276 unmodified lines
1440814669 return ret;
1440914670 }
1441014671
14672+static int do_prog_test_run(int fd_prog, bool unpriv, uint32_t expected_val,
14673+ void *data, size_t size_data)
14674+{
14675+ __u8 tmp[TEST_DATA_LEN << 2];
14676+ __u32 size_tmp = sizeof(tmp);
14677+ uint32_t retval;
14678+ int err;
14679+
14680+ if (unpriv)
14681+ set_admin(true);
14682+ err = bpf_prog_test_run(fd_prog, 1, data, size_data,
14683+ tmp, &size_tmp, &retval, NULL);
14684+ if (unpriv)
14685+ set_admin(false);
14686+ if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
14687+ printf("Unexpected bpf_prog_test_run error ");
14688+ return err;
14689+ }
14690+ if (!err && retval != expected_val &&
14691+ expected_val != POINTER_VALUE) {
14692+ printf("FAIL retval %d != %d ", retval, expected_val);
14693+ return 1;
14694+ }
14695+
14696+ return 0;
14697+}
14698+
1441114699 static void do_test_single(struct bpf_test *test, bool unpriv,
1441214700 int *passes, int *errors)
1441314701 {
1441414702 int fd_prog, expected_ret, alignment_prevented_execution;
1441514703 int prog_len, prog_type = test->prog_type;
1441614704 struct bpf_insn *prog = test->insns;
14705+ int run_errs, run_successes;
1441714706 int map_fds[MAX_NR_MAPS];
1441814707 const char *expected_err;
14419− uint32_t expected_val;
14420− uint32_t retval;
1442114708 __u32 pflags;
1442214709 int i, err;
1442314710
@@ -14441,8 +14728,6 @@ static void do_test_single(struct bpf_test *test, bool unpriv, · 17 unmodified lines
1444114728 test->result_unpriv : test->result;
1444214729 expected_err = unpriv && test->errstr_unpriv ?
1444314730 test->errstr_unpriv : test->errstr;
14444− expected_val = unpriv && test->retval_unpriv ?
14445− test->retval_unpriv : test->retval;
1444614731
1444714732 alignment_prevented_execution = 0;
1444814733
@@ -14454,10 +14739,8 @@ static void do_test_single(struct bpf_test *test, bool unpriv, · 5 unmodified lines
1445414739 }
1445514740 #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
1445614741 if (fd_prog >= 0 &&
14457− (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS)) {
14742+ (test->flags & F_NEEDS_EFFICIENT_UNALIGNED_ACCESS))
1445814743 alignment_prevented_execution = 1;
14459− goto test_ok;
14460− }
1446114744 #endif
1446214745 } else {
1446314746 if (fd_prog >= 0) {
@@ -14471,33 +14754,67 @@ static void do_test_single(struct bpf_test *test, bool unpriv, · 7 unmodified lines
1447114754 }
1447214755 }
1447314756
14474− if (fd_prog >= 0) {
14475− __u8 tmp[TEST_DATA_LEN << 2];
14476− __u32 size_tmp = sizeof(tmp);
14477−
14478− if (unpriv)
14479− set_admin(true);
14480− err = bpf_prog_test_run(fd_prog, 1, test->data,
14481− sizeof(test->data), tmp, &size_tmp,
14482− &retval, NULL);
14483− if (unpriv)
14484− set_admin(false);
14485− if (err && errno != 524/*ENOTSUPP*/ && errno != EPERM) {
14486− printf("Unexpected bpf_prog_test_run error\n");
14757+ if (test->insn_processed) {
14758+ uint32_t insn_processed;
14759+ char *proc;
14760+
14761+ proc = strstr(bpf_vlog, "processed ");
14762+ insn_processed = atoi(proc + 10);
14763+ if (test->insn_processed != insn_processed) {
14764+ printf("FAIL\nUnexpected insn_processed %u vs %u\n",
14765+ insn_processed, test->insn_processed);
1448714766 goto fail_log;
1448814767 }
14489− if (!err && retval != expected_val &&
14490− expected_val != POINTER_VALUE) {
14491− printf("FAIL retval %d != %d\n", retval, expected_val);
14492− goto fail_log;
14768+ }
14769+
14770+ run_errs = 0;
14771+ run_successes = 0;
14772+ if (!alignment_prevented_execution && fd_prog >= 0) {
14773+ uint32_t expected_val;
14774+ int i;
14775+
14776+ if (!test->runs) {
14777+ expected_val = unpriv && test->retval_unpriv ?
14778+ test->retval_unpriv : test->retval;
14779+
14780+ err = do_prog_test_run(fd_prog, unpriv, expected_val,
14781+ test->data, sizeof(test->data));
14782+ if (err)
14783+ run_errs++;
14784+ else
14785+ run_successes++;
14786+ }
14787+
14788+ for (i = 0; i < test->runs; i++) {
14789+ if (unpriv && test->retvals[i].retval_unpriv)
14790+ expected_val = test->retvals[i].retval_unpriv;
14791+ else
14792+ expected_val = test->retvals[i].retval;
14793+
14794+ err = do_prog_test_run(fd_prog, unpriv, expected_val,
14795+ test->retvals[i].data,
14796+ sizeof(test->retvals[i].data));
14797+ if (err) {
14798+ printf("(run %d/%d) ", i + 1, test->runs);
14799+ run_errs++;
14800+ } else {
14801+ run_successes++;
14802+ }
1449314803 }
1449414804 }
14495−#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
14496−test_ok:
14497−#endif
14498− (*passes)++;
14499− printf("OK%s\n", alignment_prevented_execution ?
14500− " (NOTE: not executed due to unknown alignment)" : "");
14805+
14806+ if (!run_errs) {
14807+ (*passes)++;
14808+ if (run_successes > 1)
14809+ printf("%d cases ", run_successes);
14810+ printf("OK");
14811+ if (alignment_prevented_execution)
14812+ printf(" (NOTE: not executed due to unknown alignment)");
14813+ printf("\n");
14814+ } else {
14815+ printf("\n");
14816+ goto fail_log;
14817+ }
1450114818 close_fds:
1450214819 close(fd_prog);
1450314820 for (i = 0; i < MAX_NR_MAPS; i++)