Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libbpf: Pass BPF token from find_prog_btf_id to BPF_BTF_GET_FD_BY_ID

Pass BPF token from bpf_program__set_attach_target to
BPF_BTF_GET_FD_BY_ID bpf command.
When freplace program attaches to target program, it needs to look up
for BTF of the target, this may require BPF token, if, for example,
running from user namespace.

Signed-off-by: Mykyta Yatsenko <yatsenko@meta.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
Link: https://lore.kernel.org/bpf/20250317174039.161275-4-mykyta.yatsenko5@gmail.com

authored by

Mykyta Yatsenko and committed by
Andrii Nakryiko
974ef9f0 07651ccd

+23 -9
+2 -1
tools/lib/bpf/bpf.c
··· 1097 1097 int bpf_btf_get_fd_by_id_opts(__u32 id, 1098 1098 const struct bpf_get_fd_by_id_opts *opts) 1099 1099 { 1100 - const size_t attr_sz = offsetofend(union bpf_attr, open_flags); 1100 + const size_t attr_sz = offsetofend(union bpf_attr, fd_by_id_token_fd); 1101 1101 union bpf_attr attr; 1102 1102 int fd; 1103 1103 ··· 1107 1107 memset(&attr, 0, attr_sz); 1108 1108 attr.btf_id = id; 1109 1109 attr.open_flags = OPTS_GET(opts, open_flags, 0); 1110 + attr.fd_by_id_token_fd = OPTS_GET(opts, token_fd, 0); 1110 1111 1111 1112 fd = sys_bpf_fd(BPF_BTF_GET_FD_BY_ID, &attr, attr_sz); 1112 1113 return libbpf_err_errno(fd);
+2 -1
tools/lib/bpf/bpf.h
··· 487 487 struct bpf_get_fd_by_id_opts { 488 488 size_t sz; /* size of this struct for forward/backward compatibility */ 489 489 __u32 open_flags; /* permissions requested for the operation on fd */ 490 + __u32 token_fd; 490 491 size_t :0; 491 492 }; 492 - #define bpf_get_fd_by_id_opts__last_field open_flags 493 + #define bpf_get_fd_by_id_opts__last_field token_fd 493 494 494 495 LIBBPF_API int bpf_prog_get_fd_by_id(__u32 id); 495 496 LIBBPF_API int bpf_prog_get_fd_by_id_opts(__u32 id,
+13 -2
tools/lib/bpf/btf.c
··· 1619 1619 return btf; 1620 1620 } 1621 1621 1622 - struct btf *btf__load_from_kernel_by_id_split(__u32 id, struct btf *base_btf) 1622 + struct btf *btf_load_from_kernel(__u32 id, struct btf *base_btf, int token_fd) 1623 1623 { 1624 1624 struct btf *btf; 1625 1625 int btf_fd; 1626 + LIBBPF_OPTS(bpf_get_fd_by_id_opts, opts); 1626 1627 1627 - btf_fd = bpf_btf_get_fd_by_id(id); 1628 + if (token_fd) { 1629 + opts.open_flags |= BPF_F_TOKEN_FD; 1630 + opts.token_fd = token_fd; 1631 + } 1632 + 1633 + btf_fd = bpf_btf_get_fd_by_id_opts(id, &opts); 1628 1634 if (btf_fd < 0) 1629 1635 return libbpf_err_ptr(-errno); 1630 1636 ··· 1638 1632 close(btf_fd); 1639 1633 1640 1634 return libbpf_ptr(btf); 1635 + } 1636 + 1637 + struct btf *btf__load_from_kernel_by_id_split(__u32 id, struct btf *base_btf) 1638 + { 1639 + return btf_load_from_kernel(id, base_btf, 0); 1641 1640 } 1642 1641 1643 1642 struct btf *btf__load_from_kernel_by_id(__u32 id)
+5 -5
tools/lib/bpf/libbpf.c
··· 10024 10024 return libbpf_err(err); 10025 10025 } 10026 10026 10027 - static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd) 10027 + static int libbpf_find_prog_btf_id(const char *name, __u32 attach_prog_fd, int token_fd) 10028 10028 { 10029 10029 struct bpf_prog_info info; 10030 10030 __u32 info_len = sizeof(info); ··· 10044 10044 pr_warn("The target program doesn't have BTF\n"); 10045 10045 goto out; 10046 10046 } 10047 - btf = btf__load_from_kernel_by_id(info.btf_id); 10047 + btf = btf_load_from_kernel(info.btf_id, NULL, token_fd); 10048 10048 err = libbpf_get_error(btf); 10049 10049 if (err) { 10050 10050 pr_warn("Failed to get BTF %d of the program: %s\n", info.btf_id, errstr(err)); ··· 10127 10127 pr_warn("prog '%s': attach program FD is not set\n", prog->name); 10128 10128 return -EINVAL; 10129 10129 } 10130 - err = libbpf_find_prog_btf_id(attach_name, attach_prog_fd); 10130 + err = libbpf_find_prog_btf_id(attach_name, attach_prog_fd, prog->obj->token_fd); 10131 10131 if (err < 0) { 10132 10132 pr_warn("prog '%s': failed to find BPF program (FD %d) BTF ID for '%s': %s\n", 10133 10133 prog->name, attach_prog_fd, attach_name, errstr(err)); ··· 12923 12923 if (target_fd) { 12924 12924 LIBBPF_OPTS(bpf_link_create_opts, target_opts); 12925 12925 12926 - btf_id = libbpf_find_prog_btf_id(attach_func_name, target_fd); 12926 + btf_id = libbpf_find_prog_btf_id(attach_func_name, target_fd, prog->obj->token_fd); 12927 12927 if (btf_id < 0) 12928 12928 return libbpf_err_ptr(btf_id); 12929 12929 ··· 13744 13744 13745 13745 if (attach_prog_fd) { 13746 13746 btf_id = libbpf_find_prog_btf_id(attach_func_name, 13747 - attach_prog_fd); 13747 + attach_prog_fd, prog->obj->token_fd); 13748 13748 if (btf_id < 0) 13749 13749 return libbpf_err(btf_id); 13750 13750 } else {
+1
tools/lib/bpf/libbpf_internal.h
··· 409 409 int btf_load_into_kernel(struct btf *btf, 410 410 char *log_buf, size_t log_sz, __u32 log_level, 411 411 int token_fd); 412 + struct btf *btf_load_from_kernel(__u32 id, struct btf *base_btf, int token_fd); 412 413 413 414 struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf); 414 415 void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type,