Skip to content

Commit 60197cf

Browse files
iamkafaiborkmann
authored andcommitted
bpf: btf: Add BPF_OBJ_GET_INFO_BY_FD support to BTF fd
This patch adds BPF_OBJ_GET_INFO_BY_FD support to BTF fd. The original BTF data, which was used to create the BTF fd during the earlier BPF_BTF_LOAD call, will be returned. The userspace is expected to allocate buffer to info.info and the buffer size is set to info.info_len before calling BPF_OBJ_GET_INFO_BY_FD. The original BTF data is copied to the userspace buffer (info.info). Only upto the user's specified info.info_len will be copied. The original BTF data size is set to info.info_len. The userspace needs to check if it is bigger than its allocated buffer size. If it is, the userspace should realloc with the kernel-returned info.info_len and call the BPF_OBJ_GET_INFO_BY_FD again. Signed-off-by: Martin KaFai Lau <[email protected]> Acked-by: Alexei Starovoitov <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent f56a653 commit 60197cf

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

include/linux/btf.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,14 @@ struct btf;
1010
struct btf_type;
1111
union bpf_attr;
1212

13+
extern const struct file_operations btf_fops;
14+
1315
void btf_put(struct btf *btf);
1416
int btf_new_fd(const union bpf_attr *attr);
1517
struct btf *btf_get_by_fd(int fd);
18+
int btf_get_info_by_fd(const struct btf *btf,
19+
const union bpf_attr *attr,
20+
union bpf_attr __user *uattr);
1621
/* Figure out the size of a type_id. If type_id is a modifier
1722
* (e.g. const), it will be resolved to find out the type with size.
1823
*

kernel/bpf/btf.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2002,7 +2002,7 @@ static int btf_release(struct inode *inode, struct file *filp)
20022002
return 0;
20032003
}
20042004

2005-
static const struct file_operations btf_fops = {
2005+
const struct file_operations btf_fops = {
20062006
.release = btf_release,
20072007
};
20082008

@@ -2047,3 +2047,18 @@ struct btf *btf_get_by_fd(int fd)
20472047

20482048
return btf;
20492049
}
2050+
2051+
int btf_get_info_by_fd(const struct btf *btf,
2052+
const union bpf_attr *attr,
2053+
union bpf_attr __user *uattr)
2054+
{
2055+
void __user *udata = u64_to_user_ptr(attr->info.info);
2056+
u32 copy_len = min_t(u32, btf->data_size,
2057+
attr->info.info_len);
2058+
2059+
if (copy_to_user(udata, btf->data, copy_len) ||
2060+
put_user(btf->data_size, &uattr->info.info_len))
2061+
return -EFAULT;
2062+
2063+
return 0;
2064+
}

kernel/bpf/syscall.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,8 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
20172017
else if (f.file->f_op == &bpf_map_fops)
20182018
err = bpf_map_get_info_by_fd(f.file->private_data, attr,
20192019
uattr);
2020+
else if (f.file->f_op == &btf_fops)
2021+
err = btf_get_info_by_fd(f.file->private_data, attr, uattr);
20202022
else
20212023
err = -EINVAL;
20222024

0 commit comments

Comments
 (0)