From 32e3e58e4c5910bb0d6024d151c2f559bb7e973c Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Mon, 7 Oct 2019 15:56:04 -0700 Subject: bpftool: Fix bpftool build by switching to bpf_object__open_file() As part of libbpf in 5e61f2707029 ("libbpf: stop enforcing kern_version, populate it for users") non-LIBBPF_API __bpf_object__open_xattr() API was removed from libbpf.h header. This broke bpftool, which relied on that function. This patch fixes the build by switching to newly added bpf_object__open_file() which provides the same capabilities, but is official and future-proof API. v1->v2: - fix prog_type shadowing (Stanislav). Fixes: 5e61f2707029 ("libbpf: stop enforcing kern_version, populate it for users") Reported-by: Stanislav Fomichev Signed-off-by: Andrii Nakryiko Signed-off-by: Alexei Starovoitov Reviewed-by: Stanislav Fomichev Link: https://lore.kernel.org/bpf/20191007225604.2006146-1-andriin@fb.com --- tools/bpf/bpftool/prog.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'tools/bpf/bpftool/prog.c') diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 43fdbbfe41bb..27da96a797ab 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -1092,9 +1092,7 @@ free_data_in: static int load_with_options(int argc, char **argv, bool first_prog_only) { struct bpf_object_load_attr load_attr = { 0 }; - struct bpf_object_open_attr open_attr = { - .prog_type = BPF_PROG_TYPE_UNSPEC, - }; + enum bpf_prog_type common_prog_type = BPF_PROG_TYPE_UNSPEC; enum bpf_attach_type expected_attach_type; struct map_replace *map_replace = NULL; struct bpf_program *prog = NULL, *pos; @@ -1105,11 +1103,16 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) const char *pinfile; unsigned int i, j; __u32 ifindex = 0; + const char *file; int idx, err; + LIBBPF_OPTS(bpf_object_open_opts, open_opts, + .relaxed_maps = relaxed_maps, + ); + if (!REQ_ARGS(2)) return -1; - open_attr.file = GET_ARG(); + file = GET_ARG(); pinfile = GET_ARG(); while (argc) { @@ -1118,7 +1121,7 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) NEXT_ARG(); - if (open_attr.prog_type != BPF_PROG_TYPE_UNSPEC) { + if (common_prog_type != BPF_PROG_TYPE_UNSPEC) { p_err("program type already specified"); goto err_free_reuse_maps; } @@ -1135,8 +1138,7 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) strcat(type, *argv); strcat(type, "/"); - err = libbpf_prog_type_by_name(type, - &open_attr.prog_type, + err = libbpf_prog_type_by_name(type, &common_prog_type, &expected_attach_type); free(type); if (err < 0) @@ -1224,16 +1226,16 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) set_max_rlimit(); - obj = __bpf_object__open_xattr(&open_attr, bpf_flags); + obj = bpf_object__open_file(file, &open_opts); if (IS_ERR_OR_NULL(obj)) { p_err("failed to open object file"); goto err_free_reuse_maps; } bpf_object__for_each_program(pos, obj) { - enum bpf_prog_type prog_type = open_attr.prog_type; + enum bpf_prog_type prog_type = common_prog_type; - if (open_attr.prog_type == BPF_PROG_TYPE_UNSPEC) { + if (prog_type == BPF_PROG_TYPE_UNSPEC) { const char *sec_name = bpf_program__title(pos, false); err = libbpf_prog_type_by_name(sec_name, &prog_type, -- cgit v1.2.3 From e00aca65e646da08f8dce31c9b89f11dab76198c Mon Sep 17 00:00:00 2001 From: Andrii Nakryiko Date: Tue, 22 Oct 2019 10:21:00 -0700 Subject: libbpf: Make DECLARE_LIBBPF_OPTS macro strictly a variable declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LIBBPF_OPTS is implemented as a mix of field declaration and memset + assignment. This makes it neither variable declaration nor purely statements, which is a problem, because you can't mix it with either other variable declarations nor other function statements, because C90 compiler mode emits warning on mixing all that together. This patch changes LIBBPF_OPTS into a strictly declaration of variable and solves this problem, as can be seen in case of bpftool, which previously would emit compiler warning, if done this way (LIBBPF_OPTS as part of function variables declaration block). This patch also renames LIBBPF_OPTS into DECLARE_LIBBPF_OPTS to follow kernel convention for similar macros more closely. v1->v2: - rename LIBBPF_OPTS into DECLARE_LIBBPF_OPTS (Jakub Sitnicki). Signed-off-by: Andrii Nakryiko Signed-off-by: Daniel Borkmann Acked-by: Toke Høiland-Jørgensen Link: https://lore.kernel.org/bpf/20191022172100.3281465-1-andriin@fb.com --- tools/bpf/bpftool/prog.c | 8 ++++---- tools/lib/bpf/libbpf.c | 4 ++-- tools/lib/bpf/libbpf.h | 19 ++++++++++++------- tools/testing/selftests/bpf/prog_tests/attach_probe.c | 2 +- tools/testing/selftests/bpf/prog_tests/core_reloc.c | 2 +- .../selftests/bpf/prog_tests/reference_tracking.c | 2 +- 6 files changed, 21 insertions(+), 16 deletions(-) (limited to 'tools/bpf/bpftool/prog.c') diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 27da96a797ab..4535c863d2cd 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -1091,8 +1091,11 @@ free_data_in: static int load_with_options(int argc, char **argv, bool first_prog_only) { - struct bpf_object_load_attr load_attr = { 0 }; enum bpf_prog_type common_prog_type = BPF_PROG_TYPE_UNSPEC; + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts, + .relaxed_maps = relaxed_maps, + ); + struct bpf_object_load_attr load_attr = { 0 }; enum bpf_attach_type expected_attach_type; struct map_replace *map_replace = NULL; struct bpf_program *prog = NULL, *pos; @@ -1106,9 +1109,6 @@ static int load_with_options(int argc, char **argv, bool first_prog_only) const char *file; int idx, err; - LIBBPF_OPTS(bpf_object_open_opts, open_opts, - .relaxed_maps = relaxed_maps, - ); if (!REQ_ARGS(2)) return -1; diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 803219d6898c..8b4d765c422b 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -3678,7 +3678,7 @@ out: static struct bpf_object * __bpf_object__open_xattr(struct bpf_object_open_attr *attr, int flags) { - LIBBPF_OPTS(bpf_object_open_opts, opts, + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, .relaxed_maps = flags & MAPS_RELAX_COMPAT, ); @@ -3730,7 +3730,7 @@ struct bpf_object * bpf_object__open_buffer(const void *obj_buf, size_t obj_buf_sz, const char *name) { - LIBBPF_OPTS(bpf_object_open_opts, opts, + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, .object_name = name, /* wrong default, but backwards-compatible */ .relaxed_maps = true, diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 0fdf086beba7..c63e2ff84abc 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -75,14 +75,19 @@ struct bpf_object_open_attr { * have all the padding bytes initialized to zero. It's not guaranteed though, * when copying literal, that compiler won't copy garbage in literal's padding * bytes, but that's the best way I've found and it seems to work in practice. + * + * Macro declares opts struct of given type and name, zero-initializes, + * including any extra padding, it with memset() and then assigns initial + * values provided by users in struct initializer-syntax as varargs. */ -#define LIBBPF_OPTS(TYPE, NAME, ...) \ - struct TYPE NAME; \ - memset(&NAME, 0, sizeof(struct TYPE)); \ - NAME = (struct TYPE) { \ - .sz = sizeof(struct TYPE), \ - __VA_ARGS__ \ - } +#define DECLARE_LIBBPF_OPTS(TYPE, NAME, ...) \ + struct TYPE NAME = ({ \ + memset(&NAME, 0, sizeof(struct TYPE)); \ + (struct TYPE) { \ + .sz = sizeof(struct TYPE), \ + __VA_ARGS__ \ + }; \ + }) struct bpf_object_open_opts { /* size of this struct, for forward/backward compatiblity */ diff --git a/tools/testing/selftests/bpf/prog_tests/attach_probe.c b/tools/testing/selftests/bpf/prog_tests/attach_probe.c index 0ee1ce100a4a..a83111a32d4a 100644 --- a/tools/testing/selftests/bpf/prog_tests/attach_probe.c +++ b/tools/testing/selftests/bpf/prog_tests/attach_probe.c @@ -50,7 +50,7 @@ void test_attach_probe(void) const int kprobe_idx = 0, kretprobe_idx = 1; const int uprobe_idx = 2, uretprobe_idx = 3; const char *obj_name = "attach_probe"; - LIBBPF_OPTS(bpf_object_open_opts, open_opts, + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts, .object_name = obj_name, .relaxed_maps = true, ); diff --git a/tools/testing/selftests/bpf/prog_tests/core_reloc.c b/tools/testing/selftests/bpf/prog_tests/core_reloc.c index 523dca82dc82..09dfa75fe948 100644 --- a/tools/testing/selftests/bpf/prog_tests/core_reloc.c +++ b/tools/testing/selftests/bpf/prog_tests/core_reloc.c @@ -377,7 +377,7 @@ void test_core_reloc(void) if (!test__start_subtest(test_case->case_name)) continue; - LIBBPF_OPTS(bpf_object_open_opts, opts, + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, .relaxed_core_relocs = test_case->relaxed_core_relocs, ); diff --git a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c index 4493ba277bd7..fc0d7f4f02cf 100644 --- a/tools/testing/selftests/bpf/prog_tests/reference_tracking.c +++ b/tools/testing/selftests/bpf/prog_tests/reference_tracking.c @@ -5,7 +5,7 @@ void test_reference_tracking(void) { const char *file = "test_sk_lookup_kern.o"; const char *obj_name = "ref_track"; - LIBBPF_OPTS(bpf_object_open_opts, open_opts, + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, open_opts, .object_name = obj_name, .relaxed_maps = true, ); -- cgit v1.2.3 From 5b79bcdf03628a3a9ee04d9cd5fabcf61a8e20be Mon Sep 17 00:00:00 2001 From: Toke Høiland-Jørgensen Date: Tue, 10 Dec 2019 19:14:12 +0100 Subject: bpftool: Don't crash on missing jited insns or ksyms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the kptr_restrict sysctl is set, the kernel can fail to return jited_ksyms or jited_prog_insns, but still have positive values in nr_jited_ksyms and jited_prog_len. This causes bpftool to crash when trying to dump the program because it only checks the len fields not the actual pointers to the instructions and ksyms. Fix this by adding the missing checks. Fixes: 71bb428fe2c1 ("tools: bpf: add bpftool") Fixes: f84192ee00b7 ("tools: bpftool: resolve calls without using imm field") Signed-off-by: Toke Høiland-Jørgensen Signed-off-by: Daniel Borkmann Acked-by: Martin KaFai Lau Link: https://lore.kernel.org/bpf/20191210181412.151226-1-toke@redhat.com --- tools/bpf/bpftool/prog.c | 2 +- tools/bpf/bpftool/xlated_dumper.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/bpf/bpftool/prog.c') diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index 4535c863d2cd..2ce9c5ba1934 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -493,7 +493,7 @@ static int do_dump(int argc, char **argv) info = &info_linear->info; if (mode == DUMP_JITED) { - if (info->jited_prog_len == 0) { + if (info->jited_prog_len == 0 || !info->jited_prog_insns) { p_info("no instructions returned"); goto err_free; } diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c index 494d7ae3614d..5b91ee65a080 100644 --- a/tools/bpf/bpftool/xlated_dumper.c +++ b/tools/bpf/bpftool/xlated_dumper.c @@ -174,7 +174,7 @@ static const char *print_call(void *private_data, struct kernel_sym *sym; if (insn->src_reg == BPF_PSEUDO_CALL && - (__u32) insn->imm < dd->nr_jited_ksyms) + (__u32) insn->imm < dd->nr_jited_ksyms && dd->jited_ksyms) address = dd->jited_ksyms[insn->imm]; sym = kernel_syms_search(dd, address); -- cgit v1.2.3