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

17 views
Skip to first unread message

Tadeusz Struk

unread,
May 17, 2022, 2:09:40 PM5/17/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..6f1a6160c99e 100644
--- a/kernel/bpf/cgroup.c
+++ b/kernel/bpf/cgroup.c
@@ -681,6 +681,60 @@ static struct bpf_prog_list *find_detach_entry(struct list_head *progs,
return ERR_PTR(-ENOENT);
}

+/**
+ * purge_effective_progs() - After compute_effective_progs fails to alloc new
+ * cgrp->bpf.inactive table we can recover by
+ * recomputing the array in place.
+ *
+ * @cgrp: The cgroup which descendants to travers
+ * @prog: A program to detach or NULL
+ * @link: A link to detach or NULL
+ * @atype: Type of detach operation
+ */
+static void purge_effective_progs(struct cgroup *cgrp, struct bpf_prog *prog,
+ struct bpf_cgroup_link *link,
+ enum cgroup_bpf_attach_type atype)
+{
+ struct cgroup_subsys_state *css;
+ struct bpf_prog_array *progs;
+ struct bpf_prog_list *pl;
+ struct list_head *head;
+ struct cgroup *cg;
+ int pos;
+
+ /* recompute effective prog array in place */
+ css_for_each_descendant_pre(css, &cgrp->self) {
+ struct cgroup *desc = container_of(css, struct cgroup, self);
+
+ if (percpu_ref_is_zero(&desc->bpf.refcnt))
+ continue;
+
+ /* find position of link or prog in effective progs array */
+ for (pos = 0, cg = desc; cg; cg = cgroup_parent(cg)) {
+ if (pos && !(cg->bpf.flags[atype] & BPF_F_ALLOW_MULTI))
+ continue;
+
+ head = &cg->bpf.progs[atype];
+ list_for_each_entry(pl, head, node) {
+ if (!prog_list_prog(pl))
+ continue;
+ if (pl->prog == prog && pl->link == link)
+ goto found;
+ pos++;
+ }
+ }
+found:
+ BUG_ON(!cg);
+ progs = rcu_dereference_protected(
+ desc->bpf.effective[atype],
+ lockdep_is_held(&cgroup_mutex));
+
+ /* Remove the program from the array */
+ WARN_ONCE(bpf_prog_array_delete_safe_at(progs, pos),
+ "Failed to purge a prog from array at index %d", pos);
+ }
+}
+
/**
* __cgroup_bpf_detach() - Detach the program or link from a cgroup, and
* propagate the change to descendants
@@ -723,8 +777,12 @@ 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;
+ if (err) {
+ /* If update affective array failed replace the prog with a dummy prog*/
+ pl->prog = old_prog;
+ pl->link = link;
+ purge_effective_progs(cgrp, old_prog, link, atype);
+ }

/* now can actually delete it from this cgroup list */
list_del(&pl->node);
@@ -736,12 +794,6 @@ static int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *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;
- return err;
}

static int cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog,
--
2.36.1

Tadeusz Struk

unread,
May 17, 2022, 2:10:26 PM5/17/22
to syzbot+f264bf...@syzkaller.appspotmail.com, syzkaller-a...@googlegroups.com, tadeus...@linaro.org
#syz test: https://android.googlesource.com/kernel/common android12-5.10-lts

syzbot

unread,
May 17, 2022, 2:55:12 PM5/17/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: 42226c98 Linux 5.18-rc7
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
kernel config: https://syzkaller.appspot.com/x/.config?x=3105f4ccd2ac0c7f
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=1220a1e6f00000

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

syzbot

unread,
May 17, 2022, 2:56:10 PM5/17/22
to syzkaller-a...@googlegroups.com, tadeus...@linaro.org
Hello,

syzbot tried to test the proposed patch but the build/boot failed:

failed to apply patch:
checking file kernel/bpf/cgroup.c
Hunk #1 succeeded at 653 (offset -28 lines).
Hunk #2 FAILED at 777.
Hunk #3 succeeded at 754 with fuzz 2 (offset -36 lines).
1 out of 3 hunks FAILED



Tested on:

commit: 0577ff1c Merge 5.10.116 into android12-5.10-lts
git tree: android12-5.10-lts
patch: https://syzkaller.appspot.com/x/patch.diff?x=114401e6f00000

syzbot

unread,
May 26, 2022, 11:06:09 PM5/26/22
to syzkaller-a...@googlegroups.com, tadeus...@linaro.org
Hello,

syzbot tried to test the proposed patch but the build/boot failed:

failed to copy test binary to VM: timedout after 1m0s ["scp" "-P" "22" "-F" "/dev/null" "-o" "UserKnownHostsFile=/dev/null" "-o" "BatchMode=yes" "-o" "IdentitiesOnly=yes" "-o" "StrictHostKeyChecking=no" "-o" "ConnectTimeout=10" "/syzkaller/jobs/linux/gopath/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer" "ro...@10.128.1.108:./syz-fuzzer"]
Warning: Permanently added '10.128.1.108' (ECDSA) to the list of known hosts.





Tested on:

commit: 3bb1d665 css_put test
git tree: https://github.com/tstruk/linux.git master
kernel config: https://syzkaller.appspot.com/x/.config?x=d9d47df610aa7cc7
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

Note: no patches were applied.

syzbot

unread,
May 27, 2022, 10:53:09 AM5/27/22
to syzkaller-a...@googlegroups.com, tadeus...@linaro.org
Hello,

syzbot tried to test the proposed patch but the build/boot failed:

failed to copy test binary to VM: timedout after 1m0s ["scp" "-P" "22" "-F" "/dev/null" "-o" "UserKnownHostsFile=/dev/null" "-o" "BatchMode=yes" "-o" "IdentitiesOnly=yes" "-o" "StrictHostKeyChecking=no" "-o" "ConnectTimeout=10" "/syzkaller/jobs/linux/gopath/src/github.com/google/syzkaller/bin/linux_amd64/syz-fuzzer" "ro...@10.128.1.89:./syz-fuzzer"]
Warning: Permanently added '10.128.1.89' (ECDSA) to the list of known hosts.

syzbot

unread,
May 27, 2022, 11:37:09 AM5/27/22
to syzkaller-a...@googlegroups.com, tadeus...@linaro.org
Hello,

syzbot has tested the proposed patch but the reproducer is still triggering an issue:
KASAN: use-after-free Read in compute_effective_progs

R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007fff97e4ea3f R14: 00007f4a64da6300 R15: 0000000000022000
</TASK>
---[ end trace 0000000000000000 ]---
!!! css_put css ffff888114170000 !!!
==================================================================
BUG: KASAN: use-after-free in prog_list_prog kernel/bpf/cgroup.c:213 [inline]
BUG: KASAN: use-after-free in prog_list_length kernel/bpf/cgroup.c:226 [inline]
BUG: KASAN: use-after-free in compute_effective_progs+0x1d3/0x6d0 kernel/bpf/cgroup.c:279
Read of size 8 at addr ffff88810ad54e18 by task syz-executor.0/416

CPU: 1 PID: 416 Comm: syz-executor.0 Tainted: G W 5.18.0-syzkaller-10038-gd2058918035f #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0x151/0x1b7 lib/dump_stack.c:106
print_address_description mm/kasan/report.c:313 [inline]
print_report+0x15f/0x620 mm/kasan/report.c:429
kasan_report+0xe6/0x110 mm/kasan/report.c:491
__asan_report_load8_noabort+0x14/0x20 mm/kasan/report_generic.c:307
prog_list_prog kernel/bpf/cgroup.c:213 [inline]
prog_list_length kernel/bpf/cgroup.c:226 [inline]
compute_effective_progs+0x1d3/0x6d0 kernel/bpf/cgroup.c:279
update_effective_progs+0x79/0x320 kernel/bpf/cgroup.c:382
__cgroup_bpf_detach+0x2fa/0x550 kernel/bpf/cgroup.c:764
bpf_cgroup_link_release+0xaf/0x270 kernel/bpf/cgroup.c:938
bpf_link_free kernel/bpf/syscall.c:2693 [inline]
bpf_link_put+0x1e9/0x270 kernel/bpf/syscall.c:2719
bpf_link_release+0x3b/0x40 kernel/bpf/syscall.c:2728
__fput+0x3ee/0x880 fs/file_table.c:317
____fput+0x15/0x20 fs/file_table.c:350
task_work_run+0x147/0x1b0 kernel/task_work.c:177
resume_user_mode_work include/linux/resume_user_mode.h:49 [inline]
exit_to_user_mode_loop+0x8b/0xd0 kernel/entry/common.c:169
exit_to_user_mode_prepare+0x59/0x80 kernel/entry/common.c:201
__syscall_exit_to_user_mode_work kernel/entry/common.c:283 [inline]
syscall_exit_to_user_mode+0x24/0x40 kernel/entry/common.c:294
do_syscall_64+0x3b/0x50 arch/x86/entry/common.c:86
entry_SYSCALL_64_after_hwframe+0x46/0xb0
RIP: 0033:0x7f4a63c890e9
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f4a64da6168 EFLAGS: 00000246 ORIG_RAX: 00000000000001b4
RAX: 0000000000000000 RBX: 00007f4a63d9bf60 RCX: 00007f4a63c890e9
RDX: 0000000000000000 RSI: ffffffffffffffff RDI: 0000000000000003
RBP: 00007f4a64da61d0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007fff97e4ea3f R14: 00007f4a64da6300 R15: 0000000000022000
</TASK>

Allocated by task 416:
kasan_save_stack mm/kasan/common.c:38 [inline]
kasan_set_track mm/kasan/common.c:45 [inline]
set_alloc_info mm/kasan/common.c:436 [inline]
____kasan_kmalloc+0xdc/0x110 mm/kasan/common.c:515
__kasan_kmalloc+0x9/0x10 mm/kasan/common.c:524
kasan_kmalloc include/linux/kasan.h:234 [inline]
kmem_cache_alloc_trace+0x1f0/0x320 mm/slub.c:3255
kmalloc include/linux/slab.h:600 [inline]
kzalloc include/linux/slab.h:733 [inline]
cgroup_bpf_link_attach+0x12d/0x4f0 kernel/bpf/cgroup.c:1023
link_create+0x5bc/0x8d0 kernel/bpf/syscall.c:4524
__sys_bpf+0x614/0x690 kernel/bpf/syscall.c:4987
__do_sys_bpf kernel/bpf/syscall.c:5021 [inline]
__se_sys_bpf kernel/bpf/syscall.c:5019 [inline]
__x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:5019
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x2f/0x50 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x46/0xb0

Freed by task 416:
kasan_save_stack mm/kasan/common.c:38 [inline]
kasan_set_track+0x4c/0x70 mm/kasan/common.c:45
kasan_set_free_info+0x23/0x40 mm/kasan/generic.c:370
____kasan_slab_free+0x133/0x170 mm/kasan/common.c:366
__kasan_slab_free+0x11/0x20 mm/kasan/common.c:374
kasan_slab_free include/linux/kasan.h:200 [inline]
slab_free_hook mm/slub.c:1727 [inline]
slab_free_freelist_hook+0xc9/0x1a0 mm/slub.c:1753
slab_free mm/slub.c:3507 [inline]
kfree+0xb9/0x200 mm/slub.c:4555
bpf_cgroup_link_dealloc+0x15/0x20 kernel/bpf/cgroup.c:954
bpf_link_free kernel/bpf/syscall.c:2697 [inline]
bpf_link_put+0x243/0x270 kernel/bpf/syscall.c:2719
bpf_link_release+0x3b/0x40 kernel/bpf/syscall.c:2728
__fput+0x3ee/0x880 fs/file_table.c:317
____fput+0x15/0x20 fs/file_table.c:350
task_work_run+0x147/0x1b0 kernel/task_work.c:177
resume_user_mode_work include/linux/resume_user_mode.h:49 [inline]
exit_to_user_mode_loop+0x8b/0xd0 kernel/entry/common.c:169
exit_to_user_mode_prepare+0x59/0x80 kernel/entry/common.c:201
__syscall_exit_to_user_mode_work kernel/entry/common.c:283 [inline]
syscall_exit_to_user_mode+0x24/0x40 kernel/entry/common.c:294
do_syscall_64+0x3b/0x50 arch/x86/entry/common.c:86
entry_SYSCALL_64_after_hwframe+0x46/0xb0

The buggy address belongs to the object at ffff88810ad54e00
which belongs to the cache kmalloc-96 of size 96
The buggy address is located 24 bytes inside of
96-byte region [ffff88810ad54e00, ffff88810ad54e60)

The buggy address belongs to the physical page:
page:ffffea00042b5500 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x10ad54
flags: 0x8000000000000200(slab|zone=2)
raw: 8000000000000200 ffffea0004364980 dead000000000004 ffff888100041780
raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
page_owner tracks the page as allocated
page last allocated via order 0, migratetype Unmovable, gfp_mask 0x12cc0(GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY), pid 1, tgid 1 (swapper/0), ts 2124636408, free_ts 0
set_page_owner include/linux/page_owner.h:31 [inline]
post_alloc_hook+0x15b/0x160 mm/page_alloc.c:2429
prep_new_page mm/page_alloc.c:2436 [inline]
get_page_from_freelist+0x412/0x8e0 mm/page_alloc.c:4178
__alloc_pages+0x3d1/0x7c0 mm/page_alloc.c:5406
allocate_slab+0x69/0x480 mm/slub.c:1942
new_slab mm/slub.c:2002 [inline]
___slab_alloc+0x2c2/0x6a0 mm/slub.c:3002
__slab_alloc+0x4a/0x90 mm/slub.c:3089
slab_alloc_node mm/slub.c:3180 [inline]
slab_alloc mm/slub.c:3222 [inline]
kmem_cache_alloc_trace+0x221/0x320 mm/slub.c:3253
kmalloc include/linux/slab.h:600 [inline]
kzalloc include/linux/slab.h:733 [inline]
acpi_os_allocate_zeroed include/acpi/platform/aclinuxex.h:57 [inline]
acpi_evaluate_object+0x155/0xac6 drivers/acpi/acpica/nsxfeval.c:177
acpi_evaluate_integer+0x112/0x230 drivers/acpi/utils.c:260
acpi_bus_get_status_handle drivers/acpi/bus.c:84 [inline]
acpi_bus_get_status+0x14e/0x250 drivers/acpi/bus.c:113
acpi_serdev_check_resources drivers/tty/serdev/core.c:645 [inline]
acpi_serdev_add_device+0x12a/0x770 drivers/tty/serdev/core.c:717
acpi_ns_walk_namespace+0x242/0x4a5
acpi_walk_namespace+0xf2/0x121 drivers/acpi/acpica/nsxfeval.c:606
acpi_serdev_register_devices drivers/tty/serdev/core.c:745 [inline]
serdev_controller_add+0x36e/0x430 drivers/tty/serdev/core.c:785
serdev_tty_port_register+0x17b/0x280 drivers/tty/serdev/serdev-ttyport.c:289
tty_port_register_device_attr_serdev+0xcd/0x140 drivers/tty/tty_port.c:171
page_owner free stack trace missing

Memory state around the buggy address:
ffff88810ad54d00: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff88810ad54d80: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
>ffff88810ad54e00: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
^
ffff88810ad54e80: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
ffff88810ad54f00: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
==================================================================
!!! css_put css ffff888114170000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff88810023a000 !!!
!!! css_put css ffff88810023a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!
!!! css_put css ffff888113f9a000 !!!


Tested on:

commit: d2058918 css_put test
console output: https://syzkaller.appspot.com/x/log.txt?x=11d74523f00000
kernel config: https://syzkaller.appspot.com/x/.config?x=af0f8c697adc9063
Reply all
Reply to author
Forward
0 new messages