Skip to content

Commit 3d1af4b

Browse files
committed
Merge branch 'add-fd_array_cnt-attribute-for-bpf_prog_load'
Anton Protopopov says: ==================== Add fd_array_cnt attribute for BPF_PROG_LOAD Add a new attribute to the bpf(BPF_PROG_LOAD) system call. If this new attribute is non-zero, then the fd_array is considered to be a continuous array of the fd_array_cnt length and to contain only proper map file descriptors or btf file descriptors. This change allows maps (and btfs), which aren't referenced directly by a BPF program, to be bound to the program _and_ also to be present during the program verification (so BPF_PROG_BIND_MAP is not enough for this use case). The primary reason for this change is that it is a prerequisite for adding "instruction set" maps, which are both non-referenced by the program and must be present during the program verification. The first five commits add the new functionality, the sixth adds corresponding self-tests, and the last one is a small additional fix. v1 -> v2: * rewrite the add_fd_from_fd_array() function (Eduard) * a few cleanups in selftests (Eduard) v2 -> v3: * various renamings (Alexei) * "0 is not special" (Alexei, Andrii) * do not alloc memory on fd_array init (Alexei) * fix leaking maps for error path (Hou Tao) * use libbpf helpers vs. raw syscalls (Andrii) * add comments on __btf_get_by_fd/__bpf_map_get (Alexei) * remove extra code (Alexei) v3 -> v4: * simplify error path when parsing fd_array * libbpf: pass fd_array_cnt only in prog_load (Alexei) * selftests patch contained extra code (Alexei) * renames, fix comments (Alexei) v4 -> v5: * Add btfs to env->used_btfs (Andrii) * Fix an integer overflow (Andrii) * A set of cleanups for selftests (Andrii) ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Andrii Nakryiko <[email protected]>
2 parents 6a10d2d + d677a10 commit 3d1af4b

File tree

10 files changed

+701
-137
lines changed

10 files changed

+701
-137
lines changed

include/linux/bpf.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,6 +2301,14 @@ void __bpf_obj_drop_impl(void *p, const struct btf_record *rec, bool percpu);
23012301
struct bpf_map *bpf_map_get(u32 ufd);
23022302
struct bpf_map *bpf_map_get_with_uref(u32 ufd);
23032303

2304+
/*
2305+
* The __bpf_map_get() and __btf_get_by_fd() functions parse a file
2306+
* descriptor and return a corresponding map or btf object.
2307+
* Their names are double underscored to emphasize the fact that they
2308+
* do not increase refcnt. To also increase refcnt use corresponding
2309+
* bpf_map_get() and btf_get_by_fd() functions.
2310+
*/
2311+
23042312
static inline struct bpf_map *__bpf_map_get(struct fd f)
23052313
{
23062314
if (fd_empty(f))
@@ -2310,6 +2318,15 @@ static inline struct bpf_map *__bpf_map_get(struct fd f)
23102318
return fd_file(f)->private_data;
23112319
}
23122320

2321+
static inline struct btf *__btf_get_by_fd(struct fd f)
2322+
{
2323+
if (fd_empty(f))
2324+
return ERR_PTR(-EBADF);
2325+
if (unlikely(fd_file(f)->f_op != &btf_fops))
2326+
return ERR_PTR(-EINVAL);
2327+
return fd_file(f)->private_data;
2328+
}
2329+
23132330
void bpf_map_inc(struct bpf_map *map);
23142331
void bpf_map_inc_with_uref(struct bpf_map *map);
23152332
struct bpf_map *__bpf_map_inc_not_zero(struct bpf_map *map, bool uref);

include/uapi/linux/bpf.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,16 @@ union bpf_attr {
15731573
* If provided, prog_flags should have BPF_F_TOKEN_FD flag set.
15741574
*/
15751575
__s32 prog_token_fd;
1576+
/* The fd_array_cnt can be used to pass the length of the
1577+
* fd_array array. In this case all the [map] file descriptors
1578+
* passed in this array will be bound to the program, even if
1579+
* the maps are not referenced directly. The functionality is
1580+
* similar to the BPF_PROG_BIND_MAP syscall, but maps can be
1581+
* used by the verifier during the program load. If provided,
1582+
* then the fd_array[0,...,fd_array_cnt-1] is expected to be
1583+
* continuous.
1584+
*/
1585+
__u32 fd_array_cnt;
15761586
};
15771587

15781588
struct { /* anonymous struct used by BPF_OBJ_* commands */

kernel/bpf/btf.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7746,14 +7746,9 @@ struct btf *btf_get_by_fd(int fd)
77467746
struct btf *btf;
77477747
CLASS(fd, f)(fd);
77487748

7749-
if (fd_empty(f))
7750-
return ERR_PTR(-EBADF);
7751-
7752-
if (fd_file(f)->f_op != &btf_fops)
7753-
return ERR_PTR(-EINVAL);
7754-
7755-
btf = fd_file(f)->private_data;
7756-
refcount_inc(&btf->refcnt);
7749+
btf = __btf_get_by_fd(f);
7750+
if (!IS_ERR(btf))
7751+
refcount_inc(&btf->refcnt);
77577752

77587753
return btf;
77597754
}

kernel/bpf/syscall.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2730,7 +2730,7 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
27302730
}
27312731

27322732
/* last field in 'union bpf_attr' used by this command */
2733-
#define BPF_PROG_LOAD_LAST_FIELD prog_token_fd
2733+
#define BPF_PROG_LOAD_LAST_FIELD fd_array_cnt
27342734

27352735
static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
27362736
{

0 commit comments

Comments
 (0)