Messages in this thread Patch in this message | | | From | Ben Gamari <> | Subject | [REGRESSION] Kernel panic in firmware_request since v4.9 | Date | Mon, 02 Jan 2017 00:51:05 -0500 |
| |
Hello everyone,
After a recent upgrade to 4.10-rc2 I noticed that my wireless adapter didn't come up due to a kernel panic in the firmware class induced by iwlwifi,
BUG: unable to handle kernel NULL pointer dereference at 0000000000000038 IP: _request_firmware+0x995/0xa40 PGD 0
Oops: 0000 [#1] SMP Modules linked in: i915(+) joydev rtsx_pci_sdmmc irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc iTCO_wdt iTCO_vendor_support uvcvideo dell_smm_hwmon aesni_intel aes_x86_64 crypto_simd videobuf2_vmalloc glue_helper videobuf2_memops cryptd videobuf2_v4l2 videobuf2_core snd_hda_intel videodev coretemp snd_hda_codec tg3 snd_hda_core iwlwifi pcspkr hid_multitouch psmouse drm_kms_helper snd_hwdep drm snd_pcm snd_timer rtsx_pci snd cfg80211 i2c_algo_bit mei_me soundcore fb_sys_fops mei syscopyarea i2c_i801 sysfillrect sg sysimgblt shpchp hci_uart wmi acpi_als video intel_lpss_acpi kfifo_buf intel_lpss industrialio i2c_hid acpi_pad e1000e ptp pps_core e1000 sunrpc parport_pc ppdev lp parport ip_tables x_tables autofs4 raid10 raid456 libcrc32c async_raid6_recov async_memcpy async_pq async_xor xor async_tx btusb btrtl btbcm btintel bluetooth raid6_pq raid1 raid0 multipath linear hid_generic usbkbd usbhid hid ahci serio_raw libahci pinctrl_sunrisepoint pinctrl_intel CPU: 0 PID: 321 Comm: kworker/0:2 Not tainted 4.9.0+ #4 Hardware name: Dell Inc. Latitude E7470/0T6HHJ, BIOS 1.6.3 06/15/2016 Workqueue: events request_firmware_work_func task: ffff880824200000 task.stack: ffffc90003a94000 RIP: 0010:_request_firmware+0x995/0xa40 RSP: 0000:ffffc90003a97db8 EFLAGS: 00010246 RAX: 00000000fffffffe RBX: ffff88082441b000 RCX: ffff88082441b028 RDX: ffff880824200000 RSI: 0000000000000287 RDI: 0000000000000000 RBP: ffffc90003a97e30 R08: ffff88084cc104e0 R09: 0000000000000000 R10: 000000017a1c7c3f R11: 00007f894759ed80 R12: ffffc90003a97e40 R13: 0000000000000007 R14: ffff88081c4a4800 R15: 0000000000003a98 FS: 0000000000000000(0000) GS:ffff88084cc00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000038 CR3: 0000000824ef3000 CR4: 00000000003406f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: request_firmware_work_func+0x2b/0x60 process_one_work+0x1fc/0x490 worker_thread+0x4b/0x500 kthread+0x101/0x140 ? process_one_work+0x490/0x490 ? kthread_create_on_node+0x40/0x40 ? do_syscall_64+0x6e/0x180 ret_from_fork+0x25/0x30 Code: 9e d0 81 e8 4e 6d fe ff b8 f4 ff ff ff e9 db f9 ff ff 48 c7 c7 60 91 ed 81 89 45 b0 e8 95 a3 29 00 49 8b be 00 03 00 00 8b 45 b0 <83> 7f 38 02 74 08 e8 40 eb ff ff 8b 45 b0 49 c7 86 00 03 00 00 RIP: _request_firmware+0x995/0xa40 RSP: ffffc90003a97db8 CR2: 0000000000000038 ---[ end trace 94dd071852e99747 ]---
This occurs while iwlwifi is trying to load a firmware image that (expectedly) does not exist on my system. In prior kernel versions this would fail with,
iwlwifi 0000:01:00.0: Direct firmware load for iwlwifi-8000C-26.ucode failed with error -2 iwlwifi 0000:01:00.0: Falling back to user helper
and continue to load other images until it found an available version (-22.ucode). Note that this is a Debian Sid system running systemd 232. I believe this failure is also reproducible in the 4.9 kernel.
A bit of digging revealed that the non-existent firmware image triggers an unchecked dereference of buf->fw_st in __fw_load_abort. The attached patch avoids the issue although it's unclear whether this is the correct fix. It appears there have been a few refactorings in driver/base/firmware_class.c recently. I've CC'd the authors of these patches in hopes that this will ring a bell with someone.
Cheers,
- Ben
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 4497d263209f..badc5737bad2 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -546,7 +546,8 @@ static void __fw_load_abort(struct firmware_buf *buf) * There is a small window in which user can write to 'loading' * between loading done and disappearance of 'loading' */ - if (fw_state_is_done(&buf->fw_st)) + if (!buf || fw_state_is_done(&buf->fw_st)) return; list_del_init(&buf->pending_list); -- 2.11.0 [unhandled content-type:application/pgp-signature]
| |