Skip to content

Commit 7337632

Browse files
author
Alexei Starovoitov
committed
Merge branch 'bpf-token-support-in-libbpf-s-bpf-object'
Andrii Nakryiko says: ==================== BPF token support in libbpf's BPF object Add fuller support for BPF token in high-level BPF object APIs. This is the most frequently used way to work with BPF using libbpf, so supporting BPF token there is critical. Patch #1 is improving kernel-side BPF_TOKEN_CREATE behavior by rejecting to create "empty" BPF token with no delegation. This seems like saner behavior which also makes libbpf's caching better overall. If we ever want to create BPF token with no delegate_xxx options set on BPF FS, we can use a new flag to enable that. Patches #2-#5 refactor libbpf internals, mostly feature detection code, to prepare it from BPF token FD. Patch #6 adds options to pass BPF token into BPF object open options. It also adds implicit BPF token creation logic to BPF object load step, even without any explicit involvement of the user. If the environment is setup properly, BPF token will be created transparently and used implicitly. This allows for all existing application to gain BPF token support by just linking with latest version of libbpf library. No source code modifications are required. All that under assumption that privileged container management agent properly set up default BPF FS instance at /sys/bpf/fs to allow BPF token creation. Patches #7-#8 adds more selftests, validating BPF object APIs work as expected under unprivileged user namespaced conditions in the presence of BPF token. Patch #9 extends libbpf with LIBBPF_BPF_TOKEN_PATH envvar knowledge, which can be used to override custom BPF FS location used for implicit BPF token creation logic without needing to adjust application code. This allows admins or container managers to mount BPF token-enabled BPF FS at non-standard location without the need to coordinate with applications. LIBBPF_BPF_TOKEN_PATH can also be used to disable BPF token implicit creation by setting it to an empty value. Patch #10 tests this new envvar functionality. v2->v3: - move some stray feature cache refactorings into patch #4 (Alexei); - add LIBBPF_BPF_TOKEN_PATH envvar support (Alexei); v1->v2: - remove minor code redundancies (Eduard, John); - add acks and rebase. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents f04f2ce + 322122b commit 7337632

File tree

14 files changed

+1065
-473
lines changed

14 files changed

+1065
-473
lines changed

kernel/bpf/token.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,15 @@ int bpf_token_create(union bpf_attr *attr)
152152
goto out_path;
153153
}
154154

155+
mnt_opts = path.dentry->d_sb->s_fs_info;
156+
if (mnt_opts->delegate_cmds == 0 &&
157+
mnt_opts->delegate_maps == 0 &&
158+
mnt_opts->delegate_progs == 0 &&
159+
mnt_opts->delegate_attachs == 0) {
160+
err = -ENOENT; /* no BPF token delegation is set up */
161+
goto out_path;
162+
}
163+
155164
mode = S_IFREG | ((S_IRUSR | S_IWUSR) & ~current_umask());
156165
inode = bpf_get_inode(path.mnt->mnt_sb, NULL, mode);
157166
if (IS_ERR(inode)) {
@@ -181,7 +190,6 @@ int bpf_token_create(union bpf_attr *attr)
181190
/* remember bpffs owning userns for future ns_capable() checks */
182191
token->userns = get_user_ns(userns);
183192

184-
mnt_opts = path.dentry->d_sb->s_fs_info;
185193
token->allowed_cmds = mnt_opts->delegate_cmds;
186194
token->allowed_maps = mnt_opts->delegate_maps;
187195
token->allowed_progs = mnt_opts->delegate_progs;

tools/lib/bpf/Build

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o str_error.o \
22
netlink.o bpf_prog_linfo.o libbpf_probes.o hashmap.o \
33
btf_dump.o ringbuf.o strset.o linker.o gen_loader.o relo_core.o \
4-
usdt.o zip.o elf.o
4+
usdt.o zip.o elf.o features.o

tools/lib/bpf/bpf.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts)
103103
* [0] https://lore.kernel.org/bpf/[email protected]/
104104
* [1] d05512618056 ("bpf: Add bpf_ktime_get_coarse_ns helper")
105105
*/
106-
int probe_memcg_account(void)
106+
int probe_memcg_account(int token_fd)
107107
{
108108
const size_t attr_sz = offsetofend(union bpf_attr, attach_btf_obj_fd);
109109
struct bpf_insn insns[] = {
@@ -120,6 +120,7 @@ int probe_memcg_account(void)
120120
attr.insns = ptr_to_u64(insns);
121121
attr.insn_cnt = insn_cnt;
122122
attr.license = ptr_to_u64("GPL");
123+
attr.prog_token_fd = token_fd;
123124

124125
prog_fd = sys_bpf_fd(BPF_PROG_LOAD, &attr, attr_sz);
125126
if (prog_fd >= 0) {
@@ -146,7 +147,7 @@ int bump_rlimit_memlock(void)
146147
struct rlimit rlim;
147148

148149
/* if kernel supports memcg-based accounting, skip bumping RLIMIT_MEMLOCK */
149-
if (memlock_bumped || kernel_supports(NULL, FEAT_MEMCG_ACCOUNT))
150+
if (memlock_bumped || feat_supported(NULL, FEAT_MEMCG_ACCOUNT))
150151
return 0;
151152

152153
memlock_bumped = true;
@@ -181,7 +182,7 @@ int bpf_map_create(enum bpf_map_type map_type,
181182
return libbpf_err(-EINVAL);
182183

183184
attr.map_type = map_type;
184-
if (map_name && kernel_supports(NULL, FEAT_PROG_NAME))
185+
if (map_name && feat_supported(NULL, FEAT_PROG_NAME))
185186
libbpf_strlcpy(attr.map_name, map_name, sizeof(attr.map_name));
186187
attr.key_size = key_size;
187188
attr.value_size = value_size;
@@ -265,7 +266,7 @@ int bpf_prog_load(enum bpf_prog_type prog_type,
265266
attr.kern_version = OPTS_GET(opts, kern_version, 0);
266267
attr.prog_token_fd = OPTS_GET(opts, token_fd, 0);
267268

268-
if (prog_name && kernel_supports(NULL, FEAT_PROG_NAME))
269+
if (prog_name && feat_supported(NULL, FEAT_PROG_NAME))
269270
libbpf_strlcpy(attr.prog_name, prog_name, sizeof(attr.prog_name));
270271
attr.license = ptr_to_u64(license);
271272

tools/lib/bpf/btf.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,9 @@ struct btf *btf__parse_split(const char *path, struct btf *base_btf)
13171317

13181318
static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian);
13191319

1320-
int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 log_level)
1320+
int btf_load_into_kernel(struct btf *btf,
1321+
char *log_buf, size_t log_sz, __u32 log_level,
1322+
int token_fd)
13211323
{
13221324
LIBBPF_OPTS(bpf_btf_load_opts, opts);
13231325
__u32 buf_sz = 0, raw_size;
@@ -1367,6 +1369,7 @@ int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 lo
13671369
opts.log_level = log_level;
13681370
}
13691371

1372+
opts.token_fd = token_fd;
13701373
btf->fd = bpf_btf_load(raw_data, raw_size, &opts);
13711374
if (btf->fd < 0) {
13721375
/* time to turn on verbose mode and try again */
@@ -1394,7 +1397,7 @@ int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 lo
13941397

13951398
int btf__load_into_kernel(struct btf *btf)
13961399
{
1397-
return btf_load_into_kernel(btf, NULL, 0, 0);
1400+
return btf_load_into_kernel(btf, NULL, 0, 0, 0);
13981401
}
13991402

14001403
int btf__fd(const struct btf *btf)

tools/lib/bpf/elf.c

-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
#include "libbpf_internal.h"
1212
#include "str_error.h"
1313

14-
#define STRERR_BUFSIZE 128
15-
1614
/* A SHT_GNU_versym section holds 16-bit words. This bit is set if
1715
* the symbol is hidden and can only be seen when referenced using an
1816
* explicit version number. This is a GNU extension.

0 commit comments

Comments
 (0)