Skip to content

Commit 95bf01c

Browse files
tstrukKernel Patches Daemon
authored and
Kernel Patches Daemon
committed
bpf: Fix KASAN use-after-free Read in compute_effective_progs
Syzbot found a Use After Free bug in compute_effective_progs(). The reproducer creates a number of BPF links, and causes a fault injected alloc to fail, while calling bpf_link_detach on them. Link detach triggers the link to be freed by bpf_link_free(), which calls __cgroup_bpf_detach() and update_effective_progs(). If the memory allocation in this function fails, the function restores the pointer to the bpf_cgroup_link on the cgroup list, but the memory gets freed just after it returns. After this, every subsequent call to update_effective_progs() causes this already deallocated pointer to be dereferenced in prog_list_length(), and triggers KASAN UAF error. To fix this don't preserve the pointer to the link on the cgroup list in __cgroup_bpf_detach(), but proceed with the cleanup and retry calling update_effective_progs() again afterwards. Cc: "Alexei Starovoitov" <[email protected]> Cc: "Daniel Borkmann" <[email protected]> Cc: "Andrii Nakryiko" <[email protected]> Cc: "Martin KaFai Lau" <[email protected]> Cc: "Song Liu" <[email protected]> Cc: "Yonghong Song" <[email protected]> Cc: "John Fastabend" <[email protected]> Cc: "KP Singh" <[email protected]> Cc: <[email protected]> Cc: <[email protected]> Cc: <[email protected]> Cc: <[email protected]> Link: https://syzkaller.appspot.com/bug?id=8ebf179a95c2a2670f7cf1ba62429ec044369db4 Fixes: af6eea5 ("bpf: Implement bpf_link-based cgroup BPF program attachment") Reported-by: <[email protected]> Signed-off-by: Tadeusz Struk <[email protected]>
1 parent 0c82d5d commit 95bf01c

File tree

1 file changed

+14
-11
lines changed

1 file changed

+14
-11
lines changed

kernel/bpf/cgroup.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -723,10 +723,11 @@ static int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
723723
pl->link = NULL;
724724

725725
err = update_effective_progs(cgrp, atype);
726-
if (err)
727-
goto cleanup;
728-
729-
/* now can actually delete it from this cgroup list */
726+
/*
727+
* Proceed regardless of error. The link and/or prog will be freed
728+
* just after this function returns so just delete it from this
729+
* cgroup list and retry calling update_effective_progs again later.
730+
*/
730731
list_del(&pl->node);
731732
kfree(pl);
732733
if (list_empty(progs))
@@ -735,12 +736,11 @@ static int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
735736
if (old_prog)
736737
bpf_prog_put(old_prog);
737738
static_branch_dec(&cgroup_bpf_enabled_key[atype]);
738-
return 0;
739739

740-
cleanup:
741-
/* restore back prog or link */
742-
pl->prog = old_prog;
743-
pl->link = link;
740+
/* In case of error call update_effective_progs again */
741+
if (err)
742+
err = update_effective_progs(cgrp, atype);
743+
744744
return err;
745745
}
746746

@@ -881,6 +881,7 @@ static void bpf_cgroup_link_release(struct bpf_link *link)
881881
struct bpf_cgroup_link *cg_link =
882882
container_of(link, struct bpf_cgroup_link, link);
883883
struct cgroup *cg;
884+
int err;
884885

885886
/* link might have been auto-detached by dying cgroup already,
886887
* in that case our work is done here
@@ -896,8 +897,10 @@ static void bpf_cgroup_link_release(struct bpf_link *link)
896897
return;
897898
}
898899

899-
WARN_ON(__cgroup_bpf_detach(cg_link->cgroup, NULL, cg_link,
900-
cg_link->type));
900+
err = __cgroup_bpf_detach(cg_link->cgroup, NULL, cg_link,
901+
cg_link->type);
902+
if (err)
903+
pr_warn("cgroup_bpf_detach() failed, err %d\n", err);
901904

902905
cg = cg_link->cgroup;
903906
cg_link->cgroup = NULL;

0 commit comments

Comments
 (0)