lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Thu, 16 May 2024 21:33:19 +0800
From: Hou Tao <houtao@...weicloud.com>
To: Hou Tao <houtao@...weicloud.com>, netdev@...r.kernel.org,
 Jamal Hadi Salim <jhs@...atatu.com>, Cong Wang <xiyou.wangcong@...il.com>,
 Jiri Pirko <jiri@...nulli.us>, "David S . Miller" <davem@...emloft.net>,
 Eric Dumazet <edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>,
 Paolo Abeni <pabeni@...hat.com>, Davide Caratti <dcaratti@...hat.com>
Cc: bpf@...r.kernel.org
Subject: Re: [PATCH] net/sched: unregister root_lock_key in the error path of
 qdisc_alloc()

Oops. Forgot to add the target git tree for the patch. It is targeted
for net- tree.

On 5/16/2024 9:30 PM, Hou Tao wrote:
> From: Hou Tao <houtao1@...wei.com>
>
> The following slab-use-after-free problem was reported by syzbot:
>
> ==================================================================
> BUG: KASAN: slab-use-after-free in lockdep_register_key+0x253/0x3f0 kernel/locking/lockdep.c:1225
> Read of size 8 at addr ffff88805fe2c298 by task syz-executor.1/5906
>
> CPU: 1 PID: 5906 Comm: syz-executor.1 Not tainted 6.9.0-rc5-syzkaller-01473-g2506f6229bd0 #0
> ......
> Call Trace:
>  <TASK>
>  __dump_stack lib/dump_stack.c:88 [inline]
>  dump_stack_lvl+0x241/0x360 lib/dump_stack.c:114
>  print_address_description mm/kasan/report.c:377 [inline]
>  print_report+0x169/0x550 mm/kasan/report.c:488
>  kasan_report+0x143/0x180 mm/kasan/report.c:601
>  lockdep_register_key+0x253/0x3f0 kernel/locking/lockdep.c:1225
>  htab_map_alloc+0x9b/0xe60 kernel/bpf/hashtab.c:506
>  map_create+0x90c/0x1200 kernel/bpf/syscall.c:1333
>  __sys_bpf+0x6d1/0x810 kernel/bpf/syscall.c:5659
>  do_syscall_x64 arch/x86/entry/common.c:52 [inline]
> ......
>  </TASK>
>
> Allocated by task 5593:
>  kasan_save_stack mm/kasan/common.c:47 [inline]
>  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
>  poison_kmalloc_redzone mm/kasan/common.c:370 [inline]
>  __kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:387
>  kasan_kmalloc include/linux/kasan.h:211 [inline]
>  __do_kmalloc_node mm/slub.c:3966 [inline]
>  __kmalloc_node_track_caller+0x24e/0x4e0 mm/slub.c:3986
>  kmalloc_reserve+0x111/0x2a0 net/core/skbuff.c:597
>  __alloc_skb+0x1f3/0x440 net/core/skbuff.c:666
>  alloc_skb include/linux/skbuff.h:1308 [inline]
>  alloc_skb_with_frags+0xc3/0x770 net/core/skbuff.c:6455
>  ......
>
> Freed by task 5593:
>  kasan_save_stack mm/kasan/common.c:47 [inline]
>  kasan_save_track+0x3f/0x80 mm/kasan/common.c:68
>  kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:579
>  poison_slab_object+0xa6/0xe0 mm/kasan/common.c:240
>  __kasan_slab_free+0x37/0x60 mm/kasan/common.c:256
>  kasan_slab_free include/linux/kasan.h:184 [inline]
>  slab_free_hook mm/slub.c:2106 [inline]
>  slab_free mm/slub.c:4280 [inline]
>  kfree+0x153/0x3a0 mm/slub.c:4390
>  skb_kfree_head net/core/skbuff.c:1033 [inline]
>  skb_free_head net/core/skbuff.c:1045 [inline]
>  ......
>
> The buggy address belongs to the object at ffff88805fe2c000
>  which belongs to the cache kmalloc-2k of size 2048
> The buggy address is located 664 bytes inside of
>  freed 2048-byte region [ffff88805fe2c000, ffff88805fe2c800)
>
> At first glance, it seems there is a problem with bpf hash-table,
> because the use-after-free problem is reported when invoking
> htab_map_alloc(). However, after checking the reported error more
> carefully, it appears that qdiscs_alloc() is the culprit. The most
> important clue regarding why qdisc_alloc() is involved is the following:
> "The buggy address is located 664 bytes inside of freed 2048-byte
> region". lockdep_register_key() has several callers, and only the
> offset of lock_class_key in Qdisc in 664. The problem occurs as follow:
>
> (1) call qdisc_alloc()
> After calling lockdep_register_key(), qdisc_alloc() jumps to errout1
> label because netdev_alloc_pcpu_stats() or alloc_percpu() fails (e.g.,
> due to mem-cg limitation or SIGKILL). However it doesn't call
> lockdep_unregister_key() to unregister root_lock_key, but it frees the
> allocated memory.
>
> (2) call htab_map_alloc
> During the calling of lockdep_register_key(), it finds the lockdep_key
> registered by free-ed Qdisc and triggers the use-after-free.
>
> Fix it by invoking lockdep_unregister_key() in the error path of
> qdisc_alloc().
>
> Reported-by: syzbot+061f58eec3bde7ee8ffa@...kaller.appspotmail.com
> Closes: https://lore.kernel.org/bpf/d28e4f02-965d-96de-ee56-f7a001b67fe7@huaweicloud.com/T/#m47c0670021ada17869bf887c73438133d879d326
> Fixes: af0cb3fa3f9e ("net/sched: fix false lockdep warning on qdisc root lock")
> Signed-off-by: Hou Tao <houtao1@...wei.com>
> ---
>  net/sched/sch_generic.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
> index 31dfd6c7405b0..d3f6006b563cc 100644
> --- a/net/sched/sch_generic.c
> +++ b/net/sched/sch_generic.c
> @@ -982,6 +982,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
>  
>  	return sch;
>  errout1:
> +	lockdep_unregister_key(&sch->root_lock_key);
>  	kfree(sch);
>  errout:
>  	return ERR_PTR(err);


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ