Skip to content

Commit 5329722

Browse files
anakryikoAlexei Starovoitov
authored andcommitted
bpf: Assign ID to vmlinux BTF and return extra info for BTF in GET_OBJ_INFO
Allocate ID for vmlinux BTF. This makes it visible when iterating over all BTF objects in the system. To allow distinguishing vmlinux BTF (and later kernel module BTF) from user-provided BTFs, expose extra kernel_btf flag, as well as BTF name ("vmlinux" for vmlinux BTF, will equal to module's name for module BTF). We might want to later allow specifying BTF name for user-provided BTFs as well, if that makes sense. But currently this is reserved only for in-kernel BTFs. Having in-kernel BTFs exposed IDs will allow to extend BPF APIs that require in-kernel BTF type with ability to specify BTF types from kernel modules, not just vmlinux BTF. This will be implemented in a follow up patch set for fentry/fexit/fmod_ret/lsm/etc. Signed-off-by: Andrii Nakryiko <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Acked-by: Song Liu <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 951bb64 commit 5329722

File tree

3 files changed

+46
-3
lines changed

3 files changed

+46
-3
lines changed

include/uapi/linux/bpf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4466,6 +4466,9 @@ struct bpf_btf_info {
44664466
__aligned_u64 btf;
44674467
__u32 btf_size;
44684468
__u32 id;
4469+
__aligned_u64 name;
4470+
__u32 name_len;
4471+
__u32 kernel_btf;
44694472
} __attribute__((aligned(8)));
44704473

44714474
struct bpf_link_info {

kernel/bpf/btf.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ struct btf {
214214
struct btf *base_btf;
215215
u32 start_id; /* first type ID in this BTF (0 for base BTF) */
216216
u32 start_str_off; /* first string offset (0 for base BTF) */
217+
char name[MODULE_NAME_LEN];
218+
bool kernel_btf;
217219
};
218220

219221
enum verifier_phase {
@@ -4429,6 +4431,8 @@ struct btf *btf_parse_vmlinux(void)
44294431

44304432
btf->data = __start_BTF;
44314433
btf->data_size = __stop_BTF - __start_BTF;
4434+
btf->kernel_btf = true;
4435+
snprintf(btf->name, sizeof(btf->name), "vmlinux");
44324436

44334437
err = btf_parse_hdr(env);
44344438
if (err)
@@ -4454,8 +4458,13 @@ struct btf *btf_parse_vmlinux(void)
44544458

44554459
bpf_struct_ops_init(btf, log);
44564460

4457-
btf_verifier_env_free(env);
44584461
refcount_set(&btf->refcnt, 1);
4462+
4463+
err = btf_alloc_id(btf);
4464+
if (err)
4465+
goto errout;
4466+
4467+
btf_verifier_env_free(env);
44594468
return btf;
44604469

44614470
errout:
@@ -5553,7 +5562,9 @@ int btf_get_info_by_fd(const struct btf *btf,
55535562
struct bpf_btf_info info;
55545563
u32 info_copy, btf_copy;
55555564
void __user *ubtf;
5556-
u32 uinfo_len;
5565+
char __user *uname;
5566+
u32 uinfo_len, uname_len, name_len;
5567+
int ret = 0;
55575568

55585569
uinfo = u64_to_user_ptr(attr->info.info);
55595570
uinfo_len = attr->info.info_len;
@@ -5570,11 +5581,37 @@ int btf_get_info_by_fd(const struct btf *btf,
55705581
return -EFAULT;
55715582
info.btf_size = btf->data_size;
55725583

5584+
info.kernel_btf = btf->kernel_btf;
5585+
5586+
uname = u64_to_user_ptr(info.name);
5587+
uname_len = info.name_len;
5588+
if (!uname ^ !uname_len)
5589+
return -EINVAL;
5590+
5591+
name_len = strlen(btf->name);
5592+
info.name_len = name_len;
5593+
5594+
if (uname) {
5595+
if (uname_len >= name_len + 1) {
5596+
if (copy_to_user(uname, btf->name, name_len + 1))
5597+
return -EFAULT;
5598+
} else {
5599+
char zero = '\0';
5600+
5601+
if (copy_to_user(uname, btf->name, uname_len - 1))
5602+
return -EFAULT;
5603+
if (put_user(zero, uname + uname_len - 1))
5604+
return -EFAULT;
5605+
/* let user-space know about too short buffer */
5606+
ret = -ENOSPC;
5607+
}
5608+
}
5609+
55735610
if (copy_to_user(uinfo, &info, info_copy) ||
55745611
put_user(info_copy, &uattr->info.info_len))
55755612
return -EFAULT;
55765613

5577-
return 0;
5614+
return ret;
55785615
}
55795616

55805617
int btf_get_fd_by_id(u32 id)

tools/include/uapi/linux/bpf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4466,6 +4466,9 @@ struct bpf_btf_info {
44664466
__aligned_u64 btf;
44674467
__u32 btf_size;
44684468
__u32 id;
4469+
__aligned_u64 name;
4470+
__u32 name_len;
4471+
__u32 kernel_btf;
44694472
} __attribute__((aligned(8)));
44704473

44714474
struct bpf_link_info {

0 commit comments

Comments
 (0)