diff options
author | Christian Brauner <brauner@kernel.org> | 2024-11-26 18:15:06 +0100 |
---|---|---|
committer | Christian Brauner <brauner@kernel.org> | 2024-11-26 18:15:06 +0100 |
commit | cf87766dd6f9ddcceaa8ee26e3cbd7538e42dd19 (patch) | |
tree | 8531685628a090333db2f874688ac07624b51072 /kernel/bpf/arraymap.c | |
parent | c66f759832a83cb273ba5a55c66dcc99384efa74 (diff) | |
parent | 2957fa4931a3b658d8e54eda9439d4c57967e8ad (diff) | |
download | linux-cf87766dd6f9ddcceaa8ee26e3cbd7538e42dd19.tar.gz linux-cf87766dd6f9ddcceaa8ee26e3cbd7538e42dd19.tar.bz2 linux-cf87766dd6f9ddcceaa8ee26e3cbd7538e42dd19.zip |
Merge branch 'ovl.fixes'
Bring in an overlayfs fix for v6.13-rc1 that fixes a bug introduced by
the overlayfs changes merged for v6.13.
Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'kernel/bpf/arraymap.c')
-rw-r--r-- | kernel/bpf/arraymap.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 79660e3fca4c..6cdbb4c33d31 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -947,22 +947,44 @@ static void *prog_fd_array_get_ptr(struct bpf_map *map, struct file *map_file, int fd) { struct bpf_prog *prog = bpf_prog_get(fd); + bool is_extended; if (IS_ERR(prog)) return prog; - if (!bpf_prog_map_compatible(map, prog)) { + if (prog->type == BPF_PROG_TYPE_EXT || + !bpf_prog_map_compatible(map, prog)) { bpf_prog_put(prog); return ERR_PTR(-EINVAL); } + mutex_lock(&prog->aux->ext_mutex); + is_extended = prog->aux->is_extended; + if (!is_extended) + prog->aux->prog_array_member_cnt++; + mutex_unlock(&prog->aux->ext_mutex); + if (is_extended) { + /* Extended prog can not be tail callee. It's to prevent a + * potential infinite loop like: + * tail callee prog entry -> tail callee prog subprog -> + * freplace prog entry --tailcall-> tail callee prog entry. + */ + bpf_prog_put(prog); + return ERR_PTR(-EBUSY); + } + return prog; } static void prog_fd_array_put_ptr(struct bpf_map *map, void *ptr, bool need_defer) { + struct bpf_prog *prog = ptr; + + mutex_lock(&prog->aux->ext_mutex); + prog->aux->prog_array_member_cnt--; + mutex_unlock(&prog->aux->ext_mutex); /* bpf_prog is freed after one RCU or tasks trace grace period */ - bpf_prog_put(ptr); + bpf_prog_put(prog); } static u32 prog_fd_array_sys_lookup_elem(void *ptr) |