Re: [PATCH 3/9] bpf: Add bpfwl tool to construct bpf whitelists
From: Andrii Nakryiko <hidden>
Date: 2020-05-14 22:20:33
Also in:
bpf
On Wed, May 6, 2020 at 6:30 AM Jiri Olsa [off-list ref] wrote:
This tool takes vmlinux object and whitelist directory on input
and produces C source object with BPF whitelist data.
The vmlinux object needs to have a BTF information compiled in.
The whitelist directory is expected to contain files with helper
names, where each file contains list of functions/probes that
helper is allowed to be called from - whitelist.
The bpfwl tool has following output:
$ bpfwl vmlinux dir
unsigned long d_path[] __attribute__((section(".BTF_whitelist_d_path"))) = \
{ 24507, 24511, 24537, 24539, 24545, 24588, 24602, 24920 };why long instead of int? btf_id is 4-byte one.
Each array are sorted BTF ids of the functions provided in the helper file. Each array will be compiled into kernel and used during the helper check in verifier. Signed-off-by: Jiri Olsa <jolsa@kernel.org> --- tools/bpf/bpfwl/Build | 11 ++ tools/bpf/bpfwl/Makefile | 60 +++++++++ tools/bpf/bpfwl/bpfwl.c | 285 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 356 insertions(+) create mode 100644 tools/bpf/bpfwl/Build create mode 100644 tools/bpf/bpfwl/Makefile create mode 100644 tools/bpf/bpfwl/bpfwl.c
Sorry, I didn't want to nitpick on naming, honestly, but I think this is actually harmful in the long run. bpfwl is incomprehensible name, anyone reading link script would be like "what the hell is bpfwl?" Why not bpf_build_whitelist or something with "whitelist" spelled out in full?
quoted hunk ↗ jump to hunk
diff --git a/tools/bpf/bpfwl/Build b/tools/bpf/bpfwl/Build new file mode 100644 index 000000000000..667e30d6ce79 --- /dev/null +++ b/tools/bpf/bpfwl/Build@@ -0,0 +1,11 @@ +bpfwl-y += bpfwl.o +bpfwl-y += rbtree.o +bpfwl-y += zalloc.o +
[...]
+
+struct func {
+ char *name;
+ unsigned long id;as mentioned above, btf_id is 4 byte
+ struct rb_node rb_node; + struct list_head list[]; +}; +
[...]
+ btf = btf__parse_elf(vmlinux, NULL);
+ err = libbpf_get_error(btf);
+ if (err) {
+ fprintf(stderr, "FAILED: load BTF from %s: %s",
+ vmlinux, strerror(err));
+ return -1;
+ }
+
+ nr = btf__get_nr_types(btf);
+
+ /* Iterate all the BTF types and resolve all the function IDs. */
+ for (id = 0; id < nr; id++) {It has to be `for (id = 1; id <= nr; id++)`. 0 is VOID type and not included into nr_types. I know it's confusing, but.. life :)
+ const struct btf_type *type; + struct func *func; + const char *str; + + type = btf__type_by_id(btf, id); + if (!type) + continue; +
[...]