[PATCH] bpf: Fix KASAN use-after-free Read in compute_effective_progs

0 views
Skip to first unread message

Tadeusz Struk

unread,
Apr 5, 2022, 2:30:55 PM4/5/22
to syzbot+f264bf...@syzkaller.appspotmail.com, syzkaller-a...@googlegroups.com, tadeus...@linaro.org
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master

=======================================
index 128028efda64..b6307337a3c7 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -723,10 +723,11 @@ static int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
pl->link = NULL;

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

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

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

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

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

cg = cg_link->cgroup;
cg_link->cgroup = NULL;
--
2.35.1

syzbot

unread,
Apr 5, 2022, 2:42:15 PM4/5/22
to syzkaller-a...@googlegroups.com, tadeus...@linaro.org
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-and-tested-by: syzbot+f264bf...@syzkaller.appspotmail.com

Tested on:

commit: 3e732ebf Merge tag 'for_linus' of git://git.kernel.org..
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
kernel config: https://syzkaller.appspot.com/x/.config?x=43e74a6abb9c3fce
dashboard link: https://syzkaller.appspot.com/bug?extid=f264bffdfbd5614f3bb2
compiler: Debian clang version 11.0.1-2, GNU ld (GNU Binutils for Debian) 2.35.2
patch: https://syzkaller.appspot.com/x/patch.diff?x=169a0df8f00000

Note: testing is done by a robot and is best-effort only.

Tadeusz Struk

unread,
Apr 14, 2022, 9:37:47 PM4/14/22
to syzbot+f264bf...@syzkaller.appspotmail.com, syzkaller-a...@googlegroups.com, tadeus...@linaro.org
======================================================
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 128028efda64..5a84543db616 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -738,9 +738,50 @@ static int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
return 0;

cleanup:
- /* restore back prog or link */
- pl->prog = old_prog;
- pl->link = link;
+ /*
+ * If compute_effective_progs failed with -ENOMEM, i.e. alloc for
+ * cgrp->bpf.inactive table failed, we can recover by removing
+ * the detached prog from effective table and rearranging it.
+ */
+ if (err == -ENOMEM) {
+ struct bpf_prog_array_item *item;
+ struct bpf_prog *prog_tmp, *prog_detach, *prog_last;
+ struct bpf_prog_array *array;
+ int index = 0, index_detach = -1;
+
+ array = cgrp->bpf.effective[atype];
+ item = &array->items[0];
+
+ if (prog)
+ prog_detach = prog;
+ else
+ prog_detach = link->link.prog;
+
+ if (!prog_detach)
+ return -EINVAL;
+
+ while ((prog_tmp = READ_ONCE(item->prog))) {
+ if (prog_tmp == prog_detach)
+ index_detach = index;
+ item++;
+ index++;
+ prog_last = prog_tmp;
+ }
+
+ /* Check if we found what's needed for removing the prog */
+ if (index_detach == -1 || index_detach == index-1)
+ return -EINVAL;
+
+ /* Remove the last program in the array */
+ if (bpf_prog_array_delete_safe_at(array, index-1))
+ return -EINVAL;
+
+ /* and update the detached with the last just removed */
+ if (bpf_prog_array_update_at(array, index_detach, prog_last))
+ return -EINVAL;
+
+ err = 0;
+ }
return err;
}

--
2.35.1

Tadeusz Struk

unread,
Apr 14, 2022, 9:50:17 PM4/14/22
to syzbot+f264bf...@syzkaller.appspotmail.com, syzkaller-a...@googlegroups.com, tadeus...@linaro.org
#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master

======================================================
diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c
index 128028efda64..5a64cece09f3 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -723,10 +723,8 @@ static int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
pl->link = NULL;

err = update_effective_progs(cgrp, atype);
- if (err)
- goto cleanup;

- /* now can actually delete it from this cgroup list */
+ /* now can delete it from this cgroup list */
list_del(&pl->node);
kfree(pl);
if (list_empty(progs))
@@ -735,12 +733,55 @@ static int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
if (old_prog)
bpf_prog_put(old_prog);
static_branch_dec(&cgroup_bpf_enabled_key[atype]);
- return 0;
+
+ if (!err)
+ return 0;

syzbot

unread,
Apr 15, 2022, 12:53:06 AM4/15/22
to syzkaller-a...@googlegroups.com, tadeus...@linaro.org
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-and-tested-by: syzbot+f264bf...@syzkaller.appspotmail.com

Tested on:

commit: 028192fe Merge tag 'drm-fixes-2022-04-15' of git://ano..
kernel config: https://syzkaller.appspot.com/x/.config?x=e5c1703829c231c4
dashboard link: https://syzkaller.appspot.com/bug?extid=f264bffdfbd5614f3bb2
compiler: Debian clang version 13.0.1-++20220126092033+75e33f71c2da-1~exp1~20220126212112.63, GNU ld (GNU Binutils for Debian) 2.35.2
patch: https://syzkaller.appspot.com/x/patch.diff?x=15393248f00000

syzbot

unread,
Apr 15, 2022, 1:07:08 AM4/15/22
to syzkaller-a...@googlegroups.com, tadeus...@linaro.org
Hello,

syzbot has tested the proposed patch and the reproducer did not trigger any issue:

Reported-and-tested-by: syzbot+f264bf...@syzkaller.appspotmail.com

Tested on:

commit: 028192fe Merge tag 'drm-fixes-2022-04-15' of git://ano..
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
kernel config: https://syzkaller.appspot.com/x/.config?x=e5c1703829c231c4
dashboard link: https://syzkaller.appspot.com/bug?extid=f264bffdfbd5614f3bb2
compiler: Debian clang version 13.0.1-++20220126092033+75e33f71c2da-1~exp1~20220126212112.63, GNU ld (GNU Binutils for Debian) 2.35.2
patch: https://syzkaller.appspot.com/x/patch.diff?x=1771937f700000
Reply all
Reply to author
Forward
0 new messages