Skip to content

Commit 10a3b7c

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2020-08-15 The following pull-request contains BPF updates for your *net* tree. We've added 23 non-merge commits during the last 4 day(s) which contain a total of 32 files changed, 421 insertions(+), 141 deletions(-). The main changes are: 1) Fix sock_ops ctx access splat due to register override, from John Fastabend. 2) Batch of various fixes to libbpf, bpftool, and selftests when testing build in 32-bit mode, from Andrii Nakryiko. 3) Fix vmlinux.h generation on ARM by mapping GCC built-in types (__Poly*_t) to equivalent ones clang can work with, from Jean-Philippe Brucker. 4) Fix build_id lookup in bpf_get_stackid() helper by walking all NOTE ELF sections instead of just first, from Jiri Olsa. 5) Avoid use of __builtin_offsetof() in libbpf for CO-RE, from Yonghong Song. 6) Fix segfault in test_mmap due to inconsistent length params, from Jianlin Lv. 7) Don't override errno in libbpf when logging errors, from Toke Høiland-Jørgensen. 8) Fix v4_to_v6 sockaddr conversion in sk_lookup test, from Stanislav Fomichev. 9) Add link to bpf-helpers(7) man page to BPF doc, from Joe Stringer. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents c6165cf + 4fccd2f commit 10a3b7c

32 files changed

+421
-141
lines changed

Documentation/bpf/index.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ Two sets of Questions and Answers (Q&A) are maintained.
3636
bpf_devel_QA
3737

3838

39+
Helper functions
40+
================
41+
42+
* `bpf-helpers(7)`_ maintains a list of helpers available to eBPF programs.
43+
44+
3945
Program types
4046
=============
4147

@@ -79,4 +85,5 @@ Other
7985
.. _networking-filter: ../networking/filter.rst
8086
.. _man-pages: https://www.kernel.org/doc/man-pages/
8187
.. _bpf(2): https://man7.org/linux/man-pages/man2/bpf.2.html
88+
.. _bpf-helpers(7): https://man7.org/linux/man-pages/man7/bpf-helpers.7.html
8289
.. _BPF and XDP Reference Guide: https://docs.cilium.io/en/latest/bpf/

kernel/bpf/stackmap.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -213,11 +213,13 @@ static int stack_map_get_build_id_32(void *page_addr,
213213

214214
phdr = (Elf32_Phdr *)(page_addr + sizeof(Elf32_Ehdr));
215215

216-
for (i = 0; i < ehdr->e_phnum; ++i)
217-
if (phdr[i].p_type == PT_NOTE)
218-
return stack_map_parse_build_id(page_addr, build_id,
219-
page_addr + phdr[i].p_offset,
220-
phdr[i].p_filesz);
216+
for (i = 0; i < ehdr->e_phnum; ++i) {
217+
if (phdr[i].p_type == PT_NOTE &&
218+
!stack_map_parse_build_id(page_addr, build_id,
219+
page_addr + phdr[i].p_offset,
220+
phdr[i].p_filesz))
221+
return 0;
222+
}
221223
return -EINVAL;
222224
}
223225

@@ -236,11 +238,13 @@ static int stack_map_get_build_id_64(void *page_addr,
236238

237239
phdr = (Elf64_Phdr *)(page_addr + sizeof(Elf64_Ehdr));
238240

239-
for (i = 0; i < ehdr->e_phnum; ++i)
240-
if (phdr[i].p_type == PT_NOTE)
241-
return stack_map_parse_build_id(page_addr, build_id,
242-
page_addr + phdr[i].p_offset,
243-
phdr[i].p_filesz);
241+
for (i = 0; i < ehdr->e_phnum; ++i) {
242+
if (phdr[i].p_type == PT_NOTE &&
243+
!stack_map_parse_build_id(page_addr, build_id,
244+
page_addr + phdr[i].p_offset,
245+
phdr[i].p_filesz))
246+
return 0;
247+
}
244248
return -EINVAL;
245249
}
246250

net/core/dev.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8913,10 +8913,6 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
89138913
NL_SET_ERR_MSG(extack, "Active program does not match expected");
89148914
return -EEXIST;
89158915
}
8916-
if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST) && cur_prog) {
8917-
NL_SET_ERR_MSG(extack, "XDP program already attached");
8918-
return -EBUSY;
8919-
}
89208916

89218917
/* put effective new program into new_prog */
89228918
if (link)
@@ -8927,6 +8923,10 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
89278923
enum bpf_xdp_mode other_mode = mode == XDP_MODE_SKB
89288924
? XDP_MODE_DRV : XDP_MODE_SKB;
89298925

8926+
if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST) && cur_prog) {
8927+
NL_SET_ERR_MSG(extack, "XDP program already attached");
8928+
return -EBUSY;
8929+
}
89308930
if (!offload && dev_xdp_prog(dev, other_mode)) {
89318931
NL_SET_ERR_MSG(extack, "Native and generic XDP can't be active at the same time");
89328932
return -EEXIST;

net/core/filter.c

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8317,15 +8317,31 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
83178317
/* Helper macro for adding read access to tcp_sock or sock fields. */
83188318
#define SOCK_OPS_GET_FIELD(BPF_FIELD, OBJ_FIELD, OBJ) \
83198319
do { \
8320+
int fullsock_reg = si->dst_reg, reg = BPF_REG_9, jmp = 2; \
83208321
BUILD_BUG_ON(sizeof_field(OBJ, OBJ_FIELD) > \
83218322
sizeof_field(struct bpf_sock_ops, BPF_FIELD)); \
8323+
if (si->dst_reg == reg || si->src_reg == reg) \
8324+
reg--; \
8325+
if (si->dst_reg == reg || si->src_reg == reg) \
8326+
reg--; \
8327+
if (si->dst_reg == si->src_reg) { \
8328+
*insn++ = BPF_STX_MEM(BPF_DW, si->src_reg, reg, \
8329+
offsetof(struct bpf_sock_ops_kern, \
8330+
temp)); \
8331+
fullsock_reg = reg; \
8332+
jmp += 2; \
8333+
} \
83228334
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \
83238335
struct bpf_sock_ops_kern, \
83248336
is_fullsock), \
8325-
si->dst_reg, si->src_reg, \
8337+
fullsock_reg, si->src_reg, \
83268338
offsetof(struct bpf_sock_ops_kern, \
83278339
is_fullsock)); \
8328-
*insn++ = BPF_JMP_IMM(BPF_JEQ, si->dst_reg, 0, 2); \
8340+
*insn++ = BPF_JMP_IMM(BPF_JEQ, fullsock_reg, 0, jmp); \
8341+
if (si->dst_reg == si->src_reg) \
8342+
*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg, \
8343+
offsetof(struct bpf_sock_ops_kern, \
8344+
temp)); \
83298345
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \
83308346
struct bpf_sock_ops_kern, sk),\
83318347
si->dst_reg, si->src_reg, \
@@ -8334,6 +8350,49 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
83348350
OBJ_FIELD), \
83358351
si->dst_reg, si->dst_reg, \
83368352
offsetof(OBJ, OBJ_FIELD)); \
8353+
if (si->dst_reg == si->src_reg) { \
8354+
*insn++ = BPF_JMP_A(1); \
8355+
*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg, \
8356+
offsetof(struct bpf_sock_ops_kern, \
8357+
temp)); \
8358+
} \
8359+
} while (0)
8360+
8361+
#define SOCK_OPS_GET_SK() \
8362+
do { \
8363+
int fullsock_reg = si->dst_reg, reg = BPF_REG_9, jmp = 1; \
8364+
if (si->dst_reg == reg || si->src_reg == reg) \
8365+
reg--; \
8366+
if (si->dst_reg == reg || si->src_reg == reg) \
8367+
reg--; \
8368+
if (si->dst_reg == si->src_reg) { \
8369+
*insn++ = BPF_STX_MEM(BPF_DW, si->src_reg, reg, \
8370+
offsetof(struct bpf_sock_ops_kern, \
8371+
temp)); \
8372+
fullsock_reg = reg; \
8373+
jmp += 2; \
8374+
} \
8375+
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \
8376+
struct bpf_sock_ops_kern, \
8377+
is_fullsock), \
8378+
fullsock_reg, si->src_reg, \
8379+
offsetof(struct bpf_sock_ops_kern, \
8380+
is_fullsock)); \
8381+
*insn++ = BPF_JMP_IMM(BPF_JEQ, fullsock_reg, 0, jmp); \
8382+
if (si->dst_reg == si->src_reg) \
8383+
*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg, \
8384+
offsetof(struct bpf_sock_ops_kern, \
8385+
temp)); \
8386+
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF( \
8387+
struct bpf_sock_ops_kern, sk),\
8388+
si->dst_reg, si->src_reg, \
8389+
offsetof(struct bpf_sock_ops_kern, sk));\
8390+
if (si->dst_reg == si->src_reg) { \
8391+
*insn++ = BPF_JMP_A(1); \
8392+
*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg, \
8393+
offsetof(struct bpf_sock_ops_kern, \
8394+
temp)); \
8395+
} \
83378396
} while (0)
83388397

83398398
#define SOCK_OPS_GET_TCP_SOCK_FIELD(FIELD) \
@@ -8620,17 +8679,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
86208679
SOCK_OPS_GET_TCP_SOCK_FIELD(bytes_acked);
86218680
break;
86228681
case offsetof(struct bpf_sock_ops, sk):
8623-
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
8624-
struct bpf_sock_ops_kern,
8625-
is_fullsock),
8626-
si->dst_reg, si->src_reg,
8627-
offsetof(struct bpf_sock_ops_kern,
8628-
is_fullsock));
8629-
*insn++ = BPF_JMP_IMM(BPF_JEQ, si->dst_reg, 0, 1);
8630-
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
8631-
struct bpf_sock_ops_kern, sk),
8632-
si->dst_reg, si->src_reg,
8633-
offsetof(struct bpf_sock_ops_kern, sk));
8682+
SOCK_OPS_GET_SK();
86348683
break;
86358684
}
86368685
return insn - insn_buf;

tools/bpf/bpftool/btf_dumper.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d,
6767
if (!info->btf_id || !info->nr_func_info ||
6868
btf__get_from_id(info->btf_id, &prog_btf))
6969
goto print;
70-
finfo = (struct bpf_func_info *)info->func_info;
70+
finfo = u64_to_ptr(info->func_info);
7171
func_type = btf__type_by_id(prog_btf, finfo->type_id);
7272
if (!func_type || !btf_is_func(func_type))
7373
goto print;

tools/bpf/bpftool/gen.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,20 @@ static int codegen_datasec_def(struct bpf_object *obj,
143143
var_name, align);
144144
return -EINVAL;
145145
}
146+
/* Assume 32-bit architectures when generating data section
147+
* struct memory layout. Given bpftool can't know which target
148+
* host architecture it's emitting skeleton for, we need to be
149+
* conservative and assume 32-bit one to ensure enough padding
150+
* bytes are generated for pointer and long types. This will
151+
* still work correctly for 64-bit architectures, because in
152+
* the worst case we'll generate unnecessary padding field,
153+
* which on 64-bit architectures is not strictly necessary and
154+
* would be handled by natural 8-byte alignment. But it still
155+
* will be a correct memory layout, based on recorded offsets
156+
* in BTF.
157+
*/
158+
if (align > 4)
159+
align = 4;
146160

147161
align_off = (off + align - 1) / align * align;
148162
if (align_off != need_off) {
@@ -397,7 +411,7 @@ static int do_skeleton(int argc, char **argv)
397411
{ \n\
398412
struct %1$s *obj; \n\
399413
\n\
400-
obj = (typeof(obj))calloc(1, sizeof(*obj)); \n\
414+
obj = (struct %1$s *)calloc(1, sizeof(*obj)); \n\
401415
if (!obj) \n\
402416
return NULL; \n\
403417
if (%1$s__create_skeleton(obj)) \n\
@@ -461,7 +475,7 @@ static int do_skeleton(int argc, char **argv)
461475
{ \n\
462476
struct bpf_object_skeleton *s; \n\
463477
\n\
464-
s = (typeof(s))calloc(1, sizeof(*s)); \n\
478+
s = (struct bpf_object_skeleton *)calloc(1, sizeof(*s));\n\
465479
if (!s) \n\
466480
return -1; \n\
467481
obj->skeleton = s; \n\
@@ -479,7 +493,7 @@ static int do_skeleton(int argc, char **argv)
479493
/* maps */ \n\
480494
s->map_cnt = %zu; \n\
481495
s->map_skel_sz = sizeof(*s->maps); \n\
482-
s->maps = (typeof(s->maps))calloc(s->map_cnt, s->map_skel_sz);\n\
496+
s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt, s->map_skel_sz);\n\
483497
if (!s->maps) \n\
484498
goto err; \n\
485499
",
@@ -515,7 +529,7 @@ static int do_skeleton(int argc, char **argv)
515529
/* programs */ \n\
516530
s->prog_cnt = %zu; \n\
517531
s->prog_skel_sz = sizeof(*s->progs); \n\
518-
s->progs = (typeof(s->progs))calloc(s->prog_cnt, s->prog_skel_sz);\n\
532+
s->progs = (struct bpf_prog_skeleton *)calloc(s->prog_cnt, s->prog_skel_sz);\n\
519533
if (!s->progs) \n\
520534
goto err; \n\
521535
",

tools/bpf/bpftool/link.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
106106
switch (info->type) {
107107
case BPF_LINK_TYPE_RAW_TRACEPOINT:
108108
jsonw_string_field(json_wtr, "tp_name",
109-
(const char *)info->raw_tracepoint.tp_name);
109+
u64_to_ptr(info->raw_tracepoint.tp_name));
110110
break;
111111
case BPF_LINK_TYPE_TRACING:
112112
err = get_prog_info(info->prog_id, &prog_info);
@@ -185,7 +185,7 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info)
185185
switch (info->type) {
186186
case BPF_LINK_TYPE_RAW_TRACEPOINT:
187187
printf("\n\ttp '%s' ",
188-
(const char *)info->raw_tracepoint.tp_name);
188+
(const char *)u64_to_ptr(info->raw_tracepoint.tp_name));
189189
break;
190190
case BPF_LINK_TYPE_TRACING:
191191
err = get_prog_info(info->prog_id, &prog_info);

tools/bpf/bpftool/main.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,15 @@
2121
/* Make sure we do not use kernel-only integer typedefs */
2222
#pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
2323

24-
#define ptr_to_u64(ptr) ((__u64)(unsigned long)(ptr))
24+
static inline __u64 ptr_to_u64(const void *ptr)
25+
{
26+
return (__u64)(unsigned long)ptr;
27+
}
28+
29+
static inline void *u64_to_ptr(__u64 ptr)
30+
{
31+
return (void *)(unsigned long)ptr;
32+
}
2533

2634
#define NEXT_ARG() ({ argc--; argv++; if (argc < 0) usage(); })
2735
#define NEXT_ARGP() ({ (*argc)--; (*argv)++; if (*argc < 0) usage(); })

tools/bpf/bpftool/prog.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -428,14 +428,14 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
428428
p_info("no instructions returned");
429429
return -1;
430430
}
431-
buf = (unsigned char *)(info->jited_prog_insns);
431+
buf = u64_to_ptr(info->jited_prog_insns);
432432
member_len = info->jited_prog_len;
433433
} else { /* DUMP_XLATED */
434434
if (info->xlated_prog_len == 0 || !info->xlated_prog_insns) {
435435
p_err("error retrieving insn dump: kernel.kptr_restrict set?");
436436
return -1;
437437
}
438-
buf = (unsigned char *)info->xlated_prog_insns;
438+
buf = u64_to_ptr(info->xlated_prog_insns);
439439
member_len = info->xlated_prog_len;
440440
}
441441

@@ -444,7 +444,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
444444
return -1;
445445
}
446446

447-
func_info = (void *)info->func_info;
447+
func_info = u64_to_ptr(info->func_info);
448448

449449
if (info->nr_line_info) {
450450
prog_linfo = bpf_prog_linfo__new(info);
@@ -462,7 +462,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
462462

463463
n = write(fd, buf, member_len);
464464
close(fd);
465-
if (n != member_len) {
465+
if (n != (ssize_t)member_len) {
466466
p_err("error writing output file: %s",
467467
n < 0 ? strerror(errno) : "short write");
468468
return -1;
@@ -492,13 +492,13 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
492492
__u32 i;
493493
if (info->nr_jited_ksyms) {
494494
kernel_syms_load(&dd);
495-
ksyms = (__u64 *) info->jited_ksyms;
495+
ksyms = u64_to_ptr(info->jited_ksyms);
496496
}
497497

498498
if (json_output)
499499
jsonw_start_array(json_wtr);
500500

501-
lens = (__u32 *) info->jited_func_lens;
501+
lens = u64_to_ptr(info->jited_func_lens);
502502
for (i = 0; i < info->nr_jited_func_lens; i++) {
503503
if (ksyms) {
504504
sym = kernel_syms_search(&dd, ksyms[i]);
@@ -559,7 +559,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
559559
} else {
560560
kernel_syms_load(&dd);
561561
dd.nr_jited_ksyms = info->nr_jited_ksyms;
562-
dd.jited_ksyms = (__u64 *) info->jited_ksyms;
562+
dd.jited_ksyms = u64_to_ptr(info->jited_ksyms);
563563
dd.btf = btf;
564564
dd.func_info = func_info;
565565
dd.finfo_rec_size = info->func_info_rec_size;
@@ -1681,7 +1681,7 @@ static char *profile_target_name(int tgt_fd)
16811681
goto out;
16821682
}
16831683

1684-
func_info = (struct bpf_func_info *)(info_linear->info.func_info);
1684+
func_info = u64_to_ptr(info_linear->info.func_info);
16851685
t = btf__type_by_id(btf, func_info[0].type_id);
16861686
if (!t) {
16871687
p_err("btf %d doesn't have type %d",

tools/lib/bpf/bpf_helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
* Helper macro to manipulate data structures
4141
*/
4242
#ifndef offsetof
43-
#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
43+
#define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER)
4444
#endif
4545
#ifndef container_of
4646
#define container_of(ptr, type, member) \

0 commit comments

Comments
 (0)