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:   Mon, 19 Jul 2021 14:42:05 +0800
From:   "Leizhen (ThunderTown)" <thunder.leizhen@...wei.com>
To:     Luis Chamberlain <mcgrof@...nel.org>
CC:     Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        "Rafael J . Wysocki" <rafael@...nel.org>,
        Ming Lei <ming.lei@...onical.com>,
        linux-kernel <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH 1/1] firmware: fix use-after-free in _request_firmware()



On 2021/7/17 3:56, Luis Chamberlain wrote:
> On Tue, Jul 13, 2021 at 10:49:42AM +0800, Zhen Lei wrote:
>> 		CPU0			CPU1
>> __device_uncache_fw_images():		assign_fw():
>> 					fw_cache_piggyback_on_request()
>> 					<----- P0
>> 	spin_lock(&fwc->name_lock);
>> 	...
>> 	list_del(&fce->list);
>> 	spin_unlock(&fwc->name_lock);
>>
>> 	uncache_firmware(fce->name);
>> 					<----- P1
>> 					kref_get(&fw_priv->ref);
>>
>> If CPU1 is interrupted at position P0, the new 'fce' has been added to the
>> list fwc->fw_names by the fw_cache_piggyback_on_request(). In this case,
>> CPU0 executes __device_uncache_fw_images() and will be able to see it when
>> it traverses list fwc->fw_names. Before CPU1 executes kref_get() at P1, if
>> CPU0 further executes uncache_firmware(), the count of fw_priv->ref may
>> decrease to 0, causing fw_priv to be released in advance.
>>
>> Move kref_get() to the lock protection range of fwc->name_lock to fix it.
>>
>> Fixes: ac39b3ea73aa ("firmware loader: let caching firmware piggyback on loading firmware")
>> Signed-off-by: Zhen Lei <thunder.leizhen@...wei.com>
> 
> Acked-by: Luis Chamberlain <mcgrof@...nel.org>
> 
> Good catch! Can you resend a v2 patch describing how this race is rather
> difficult to run into given it likely involves looping modprobe / rmod on a
> driver while doing the suspend / resume cycle? I can't see how else to
> trigger this. Additionally if you can describe in the patch how you
> found this, (code inspection, a robot code system which looks for UAF?)
> it would be good for the commit log.


Hi, Luis:
  I will update the description and resend v2. Our fuzz testing reported a
"KASAN: use-after-free Read in firmware_fallback_sysfs", I checked the code in
the entire drivers/base/firmware_loader/ directory. Other than this race, there's
nothing suspicious, maybe it's just that I didn't find. It's hard to explain
the UAF call trace, so I didn't attach it to avoid confusion.

The following is the complete exception information:

platform regulatory.0: Direct firmware load for regulatory.db failed with error -2
platform regulatory.0: Falling back to sysfs fallback for: regulatory.db
==================================================================
BUG: KASAN: use-after-free in __list_add_valid+0x24/0xb4 lib/list_debug.c:23
Read of size 8 at addr ffff0000d7471490 by task syz-executor.1/6045

CPU: 1 PID: 6045 Comm: syz-executor.1 Not tainted 5.10.0-02190-ge9a844e2c44c-dirty #7
Hardware name: linux,dummy-virt (DT)
Call trace:
 dump_backtrace+0x0/0x2d0 arch/arm64/kernel/stacktrace.c:132
 show_stack+0x28/0x34 arch/arm64/kernel/stacktrace.c:196
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x110/0x164 lib/dump_stack.c:118
 print_address_description+0x78/0x5c8 mm/kasan/report.c:385
 __kasan_report mm/kasan/report.c:545 [inline]
 kasan_report+0x148/0x1e4 mm/kasan/report.c:562
 check_memory_region_inline mm/kasan/generic.c:183 [inline]
 __asan_load8+0xb4/0xbc mm/kasan/generic.c:252
 __list_add_valid+0x24/0xb4 lib/list_debug.c:23
 __list_add include/linux/list.h:67 [inline]
 list_add include/linux/list.h:86 [inline]
 fw_load_sysfs_fallback drivers/base/firmware_loader/fallback.c:516 [inline]
 fw_load_from_user_helper drivers/base/firmware_loader/fallback.c:581 [inline]
 firmware_fallback_sysfs+0x2a8/0x588 drivers/base/firmware_loader/fallback.c:657
 _request_firmware+0x728/0x814 drivers/base/firmware_loader/main.c:831
 request_firmware+0x48/0x68 drivers/base/firmware_loader/main.c:875
 reg_reload_regdb+0x40/0x148 net/wireless/reg.c:1083
 nl80211_reload_regdb+0x10/0x18 net/wireless/nl80211.c:7067
 genl_family_rcv_msg_doit net/netlink/genetlink.c:739 [inline]
 genl_family_rcv_msg net/netlink/genetlink.c:783 [inline]
 genl_rcv_msg+0x6e8/0x784 net/netlink/genetlink.c:800
 netlink_rcv_skb+0xe0/0x1bc net/netlink/af_netlink.c:2494
 genl_rcv+0x34/0x48 net/netlink/genetlink.c:811
 netlink_unicast_kernel+0x170/0x228 net/netlink/af_netlink.c:1304
 netlink_unicast+0x118/0x208 net/netlink/af_netlink.c:1330
 netlink_sendmsg+0x3f8/0x4b4 net/netlink/af_netlink.c:1919
 sock_sendmsg_nosec net/socket.c:651 [inline]
 sock_sendmsg net/socket.c:671 [inline]
 ____sys_sendmsg+0x314/0x470 net/socket.c:2353
 ___sys_sendmsg net/socket.c:2407 [inline]
 __sys_sendmsg+0x10c/0x1d8 net/socket.c:2440
 __do_sys_sendmsg net/socket.c:2449 [inline]
 __se_sys_sendmsg net/socket.c:2447 [inline]
 __arm64_sys_sendmsg+0x4c/0x5c net/socket.c:2447
 __invoke_syscall arch/arm64/kernel/syscall.c:36 [inline]
 invoke_syscall arch/arm64/kernel/syscall.c:48 [inline]
 el0_svc_common arch/arm64/kernel/syscall.c:158 [inline]
 do_el0_svc+0x120/0x290 arch/arm64/kernel/syscall.c:220
 el0_svc+0x1c/0x28 arch/arm64/kernel/entry-common.c:367
 el0_sync_handler+0x98/0x170 arch/arm64/kernel/entry-common.c:383
 el0_sync+0x140/0x180 arch/arm64/kernel/entry.S:670

Allocated by task 6022:
 stack_trace_save+0x80/0xb8 kernel/stacktrace.c:121
 kasan_save_stack mm/kasan/common.c:48 [inline]
 kasan_set_track mm/kasan/common.c:56 [inline]
 __kasan_kmalloc+0xdc/0x120 mm/kasan/common.c:461
 kasan_kmalloc+0xc/0x14 mm/kasan/common.c:475
 kmem_cache_alloc_trace include/linux/slab.h:450 [inline]
 kmalloc include/linux/slab.h:552 [inline]
 kzalloc include/linux/slab.h:664 [inline]
 __allocate_fw_priv drivers/base/firmware_loader/main.c:186 [inline]
 alloc_lookup_fw_priv+0xb0/0x344 drivers/base/firmware_loader/main.c:250
 _request_firmware_prepare drivers/base/firmware_loader/main.c:744 [inline]
 _request_firmware+0x1ac/0x814 drivers/base/firmware_loader/main.c:806
 request_firmware+0x48/0x68 drivers/base/firmware_loader/main.c:875
 reg_reload_regdb+0x40/0x148 net/wireless/reg.c:1083
 nl80211_reload_regdb+0x10/0x18 net/wireless/nl80211.c:7067
 genl_family_rcv_msg_doit net/netlink/genetlink.c:739 [inline]
 genl_family_rcv_msg net/netlink/genetlink.c:783 [inline]
 genl_rcv_msg+0x6e8/0x784 net/netlink/genetlink.c:800
 netlink_rcv_skb+0xe0/0x1bc net/netlink/af_netlink.c:2494
 genl_rcv+0x34/0x48 net/netlink/genetlink.c:811
 netlink_unicast_kernel+0x170/0x228 net/netlink/af_netlink.c:1304
 netlink_unicast+0x118/0x208 net/netlink/af_netlink.c:1330
 netlink_sendmsg+0x3f8/0x4b4 net/netlink/af_netlink.c:1919
 sock_sendmsg_nosec net/socket.c:651 [inline]
 sock_sendmsg net/socket.c:671 [inline]
 ____sys_sendmsg+0x314/0x470 net/socket.c:2353
 ___sys_sendmsg net/socket.c:2407 [inline]
 __sys_sendmsg+0x10c/0x1d8 net/socket.c:2440
 __do_sys_sendmsg net/socket.c:2449 [inline]
 __se_sys_sendmsg net/socket.c:2447 [inline]
 __arm64_sys_sendmsg+0x4c/0x5c net/socket.c:2447
 __invoke_syscall arch/arm64/kernel/syscall.c:36 [inline]
 invoke_syscall arch/arm64/kernel/syscall.c:48 [inline]
 el0_svc_common arch/arm64/kernel/syscall.c:158 [inline]
 do_el0_svc+0x120/0x290 arch/arm64/kernel/syscall.c:220
 el0_svc+0x1c/0x28 arch/arm64/kernel/entry-common.c:367
 el0_sync_handler+0x98/0x170 arch/arm64/kernel/entry-common.c:383
 el0_sync+0x140/0x180 arch/arm64/kernel/entry.S:670

Freed by task 6022:
 stack_trace_save+0x80/0xb8 kernel/stacktrace.c:121
 kasan_save_stack mm/kasan/common.c:48 [inline]
 kasan_set_track+0x38/0x6c mm/kasan/common.c:56
 kasan_set_free_info+0x20/0x40 mm/kasan/generic.c:355
 __kasan_slab_free+0x124/0x150 mm/kasan/common.c:422
 kasan_slab_free+0x10/0x1c mm/kasan/common.c:431
 slab_free_hook mm/slub.c:1544 [inline]
 slab_free_freelist_hook mm/slub.c:1577 [inline]
 slab_free mm/slub.c:3142 [inline]
 kfree+0x104/0x38c mm/slub.c:4124
 uvc_delete drivers/media/usb/uvc/uvc_driver.c:1987 [inline]
 kref_put+0x1f8/0x250 include/linux/kref.h:65
 free_fw_priv drivers/base/firmware_loader/main.c:289 [inline]
 firmware_free_data drivers/base/firmware_loader/main.c:584 [inline]
 release_firmware drivers/base/firmware_loader/main.c:1053 [inline]
 _request_firmware+0x534/0x814 drivers/base/firmware_loader/main.c:839
 request_firmware+0x48/0x68 drivers/base/firmware_loader/main.c:875
 reg_reload_regdb+0x40/0x148 net/wireless/reg.c:1083
 nl80211_reload_regdb+0x10/0x18 net/wireless/nl80211.c:7067
 genl_family_rcv_msg_doit net/netlink/genetlink.c:739 [inline]
 genl_family_rcv_msg net/netlink/genetlink.c:783 [inline]
 genl_rcv_msg+0x6e8/0x784 net/netlink/genetlink.c:800
 netlink_rcv_skb+0xe0/0x1bc net/netlink/af_netlink.c:2494
 genl_rcv+0x34/0x48 net/netlink/genetlink.c:811
 netlink_unicast_kernel+0x170/0x228 net/netlink/af_netlink.c:1304
 netlink_unicast+0x118/0x208 net/netlink/af_netlink.c:1330
 netlink_sendmsg+0x3f8/0x4b4 net/netlink/af_netlink.c:1919
 sock_sendmsg_nosec net/socket.c:651 [inline]
 sock_sendmsg net/socket.c:671 [inline]
 ____sys_sendmsg+0x314/0x470 net/socket.c:2353
 ___sys_sendmsg net/socket.c:2407 [inline]
 __sys_sendmsg+0x10c/0x1d8 net/socket.c:2440
 __do_sys_sendmsg net/socket.c:2449 [inline]
 __se_sys_sendmsg net/socket.c:2447 [inline]
 __arm64_sys_sendmsg+0x4c/0x5c net/socket.c:2447
 __invoke_syscall arch/arm64/kernel/syscall.c:36 [inline]
 invoke_syscall arch/arm64/kernel/syscall.c:48 [inline]
 el0_svc_common arch/arm64/kernel/syscall.c:158 [inline]
 do_el0_svc+0x120/0x290 arch/arm64/kernel/syscall.c:220
 el0_svc+0x1c/0x28 arch/arm64/kernel/entry-common.c:367
 el0_sync_handler+0x98/0x170 arch/arm64/kernel/entry-common.c:383
 el0_sync+0x140/0x180 arch/arm64/kernel/entry.S:670

The buggy address belongs to the object at ffff0000d7471400
 which belongs to the cache kmalloc-256 of size 256
The buggy address is located 144 bytes inside of
 256-byte region [ffff0000d7471400, ffff0000d7471500)
The buggy address belongs to the page:
page:0000000001e413c8 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x117470
head:0000000001e413c8 order:2 compound_mapcount:0 compound_pincount:0
flags: 0x5ffc00000010200(slab|head)
raw: 05ffc00000010200 dead000000000100 dead000000000122 ffff0000c0003b00
raw: 0000000000000000 0000000080200020 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff0000d7471380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff0000d7471400: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
> ffff0000d7471480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                         ^
 ffff0000d7471500: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff0000d7471580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================



> 
> Having a possible impact described in the commit log is useful for folks
> who may want to put effort into backporting this for for older kernels
> in case it does not apply as-is.
> 
>  Luis
> .
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ