Skip to content

Commit 2d3eb67

Browse files
Alexei Starovoitovborkmann
authored andcommitted
libbpf: Sanitize global functions
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]
1 parent f41aa38 commit 2d3eb67

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

tools/include/uapi/linux/btf.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ enum {
146146
BTF_VAR_GLOBAL_EXTERN = 2,
147147
};
148148

149+
enum btf_func_linkage {
150+
BTF_FUNC_STATIC = 0,
151+
BTF_FUNC_GLOBAL = 1,
152+
BTF_FUNC_EXTERN = 2,
153+
};
154+
149155
/* BTF_KIND_VAR is followed by a single "struct btf_var" to describe
150156
* additional information related to the variable such as its linkage.
151157
*/

tools/lib/bpf/libbpf.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ struct bpf_capabilities {
173173
__u32 btf_datasec:1;
174174
/* BPF_F_MMAPABLE is supported for arrays */
175175
__u32 array_mmap:1;
176+
/* BTF_FUNC_GLOBAL is supported */
177+
__u32 btf_func_global:1;
176178
};
177179

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

22102212
static void bpf_object__sanitize_btf(struct bpf_object *obj)
22112213
{
2214+
bool has_func_global = obj->caps.btf_func_global;
22122215
bool has_datasec = obj->caps.btf_datasec;
22132216
bool has_func = obj->caps.btf_func;
22142217
struct btf *btf = obj->btf;
22152218
struct btf_type *t;
22162219
int i, j, vlen;
22172220

2218-
if (!obj->btf || (has_func && has_datasec))
2221+
if (!obj->btf || (has_func && has_datasec && has_func_global))
22192222
return;
22202223

22212224
for (i = 1; i <= btf__get_nr_types(btf); i++) {
@@ -2263,6 +2266,9 @@ static void bpf_object__sanitize_btf(struct bpf_object *obj)
22632266
} else if (!has_func && btf_is_func(t)) {
22642267
/* replace FUNC with TYPEDEF */
22652268
t->info = BTF_INFO_ENC(BTF_KIND_TYPEDEF, 0, 0);
2269+
} else if (!has_func_global && btf_is_func(t)) {
2270+
/* replace BTF_FUNC_GLOBAL with BTF_FUNC_STATIC */
2271+
t->info = BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0);
22662272
}
22672273
}
22682274
}
@@ -3205,6 +3211,32 @@ static int bpf_object__probe_btf_func(struct bpf_object *obj)
32053211
return 0;
32063212
}
32073213

3214+
static int bpf_object__probe_btf_func_global(struct bpf_object *obj)
3215+
{
3216+
static const char strs[] = "\0int\0x\0a";
3217+
/* static void x(int a) {} */
3218+
__u32 types[] = {
3219+
/* int */
3220+
BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */
3221+
/* FUNC_PROTO */ /* [2] */
3222+
BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0),
3223+
BTF_PARAM_ENC(7, 1),
3224+
/* FUNC x BTF_FUNC_GLOBAL */ /* [3] */
3225+
BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 2),
3226+
};
3227+
int btf_fd;
3228+
3229+
btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types),
3230+
strs, sizeof(strs));
3231+
if (btf_fd >= 0) {
3232+
obj->caps.btf_func_global = 1;
3233+
close(btf_fd);
3234+
return 1;
3235+
}
3236+
3237+
return 0;
3238+
}
3239+
32083240
static int bpf_object__probe_btf_datasec(struct bpf_object *obj)
32093241
{
32103242
static const char strs[] = "\0x\0.data";
@@ -3260,6 +3292,7 @@ bpf_object__probe_caps(struct bpf_object *obj)
32603292
bpf_object__probe_name,
32613293
bpf_object__probe_global_data,
32623294
bpf_object__probe_btf_func,
3295+
bpf_object__probe_btf_func_global,
32633296
bpf_object__probe_btf_datasec,
32643297
bpf_object__probe_array_mmap,
32653298
};

0 commit comments

Comments
 (0)