Skip to content

Commit

Permalink
libbpf: Sanitize global functions
Browse files Browse the repository at this point in the history
In case the kernel doesn't support BTF_FUNC_GLOBAL sanitize BTF produced by the
compiler for global functions.

Signed-off-by: Alexei Starovoitov <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
Acked-by: Song Liu <[email protected]>
Link: https://lore.kernel.org/bpf/[email protected]
  • Loading branch information
Alexei Starovoitov authored and borkmann committed Jan 10, 2020
1 parent f41aa38 commit 2d3eb67
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
6 changes: 6 additions & 0 deletions tools/include/uapi/linux/btf.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ enum {
BTF_VAR_GLOBAL_EXTERN = 2,
};

enum btf_func_linkage {
BTF_FUNC_STATIC = 0,
BTF_FUNC_GLOBAL = 1,
BTF_FUNC_EXTERN = 2,
};

/* BTF_KIND_VAR is followed by a single "struct btf_var" to describe
* additional information related to the variable such as its linkage.
*/
Expand Down
35 changes: 34 additions & 1 deletion tools/lib/bpf/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ struct bpf_capabilities {
__u32 btf_datasec:1;
/* BPF_F_MMAPABLE is supported for arrays */
__u32 array_mmap:1;
/* BTF_FUNC_GLOBAL is supported */
__u32 btf_func_global:1;
};

enum reloc_type {
Expand Down Expand Up @@ -2209,13 +2211,14 @@ static bool section_have_execinstr(struct bpf_object *obj, int idx)

static void bpf_object__sanitize_btf(struct bpf_object *obj)
{
bool has_func_global = obj->caps.btf_func_global;
bool has_datasec = obj->caps.btf_datasec;
bool has_func = obj->caps.btf_func;
struct btf *btf = obj->btf;
struct btf_type *t;
int i, j, vlen;

if (!obj->btf || (has_func && has_datasec))
if (!obj->btf || (has_func && has_datasec && has_func_global))
return;

for (i = 1; i <= btf__get_nr_types(btf); i++) {
Expand Down Expand Up @@ -2263,6 +2266,9 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj)
} else if (!has_func && btf_is_func(t)) {
/* replace FUNC with TYPEDEF */
t->info = BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0);
} else if (!has_func_global && btf_is_func(t)) {
/* replace BTF_FUNC_GLOBAL with BTF_FUNC_STATIC */
t->info = BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0);
}
}
}
Expand Down Expand Up @@ -3205,6 +3211,32 @@ static int bpf_object__probe_btf_func(struct bpf_object *obj)
return 0;
}

static int bpf_object__probe_btf_func_global(struct bpf_object *obj)
{
static const char strs[] = "\0int\0x\0a";
/* static void x(int a) {} */
__u32 types[] = {
/* int */
BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
/* FUNC_PROTO */ /* [2] */
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0),
BTF_PARAM_ENC(7, 1),
/* FUNC x BTF_FUNC_GLOBAL */ /* [3] */
BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 2),
};
int btf_fd;

btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types),
strs, sizeof(strs));
if (btf_fd >= 0) {
obj->caps.btf_func_global = 1;
close(btf_fd);
return 1;
}

return 0;
}

static int bpf_object__probe_btf_datasec(struct bpf_object *obj)
{
static const char strs[] = "\0x\0.data";
Expand Down Expand Up @@ -3260,6 +3292,7 @@ bpf_object__probe_caps(struct bpf_object *obj)
bpf_object__probe_name,
bpf_object__probe_global_data,
bpf_object__probe_btf_func,
bpf_object__probe_btf_func_global,
bpf_object__probe_btf_datasec,
bpf_object__probe_array_mmap,
};
Expand Down

0 comments on commit 2d3eb67

Please sign in to comment.