Security Vulnerability Report
中文
CVE-2022-50551 CVSS 7.1 HIGH

CVE-2022-50551

Published: 2025-10-07 16:15:41
Last Modified: 2026-02-26 23:17:55
Source: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

Description

In the Linux kernel, the following vulnerability has been resolved: wifi: brcmfmac: Fix potential shift-out-of-bounds in brcmf_fw_alloc_request() This patch fixes a shift-out-of-bounds in brcmfmac that occurs in BIT(chiprev) when a 'chiprev' provided by the device is too large. It should also not be equal to or greater than BITS_PER_TYPE(u32) as we do bitwise AND with a u32 variable and BIT(chiprev). The patch adds a check that makes the function return NULL if that is the case. Note that the NULL case is later handled by the bus-specific caller, brcmf_usb_probe_cb() or brcmf_usb_reset_resume(), for example. Found by a modified version of syzkaller. UBSAN: shift-out-of-bounds in drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c shift exponent 151055786 is too large for 64-bit type 'long unsigned int' CPU: 0 PID: 1885 Comm: kworker/0:2 Tainted: G O 5.14.0+ #132 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014 Workqueue: usb_hub_wq hub_event Call Trace: dump_stack_lvl+0x57/0x7d ubsan_epilogue+0x5/0x40 __ubsan_handle_shift_out_of_bounds.cold+0x53/0xdb ? lock_chain_count+0x20/0x20 brcmf_fw_alloc_request.cold+0x19/0x3ea ? brcmf_fw_get_firmwares+0x250/0x250 ? brcmf_usb_ioctl_resp_wait+0x1a7/0x1f0 brcmf_usb_get_fwname+0x114/0x1a0 ? brcmf_usb_reset_resume+0x120/0x120 ? number+0x6c4/0x9a0 brcmf_c_process_clm_blob+0x168/0x590 ? put_dec+0x90/0x90 ? enable_ptr_key_workfn+0x20/0x20 ? brcmf_common_pd_remove+0x50/0x50 ? rcu_read_lock_sched_held+0xa1/0xd0 brcmf_c_preinit_dcmds+0x673/0xc40 ? brcmf_c_set_joinpref_default+0x100/0x100 ? rcu_read_lock_sched_held+0xa1/0xd0 ? rcu_read_lock_bh_held+0xb0/0xb0 ? lock_acquire+0x19d/0x4e0 ? find_held_lock+0x2d/0x110 ? brcmf_usb_deq+0x1cc/0x260 ? mark_held_locks+0x9f/0xe0 ? lockdep_hardirqs_on_prepare+0x273/0x3e0 ? _raw_spin_unlock_irqrestore+0x47/0x50 ? trace_hardirqs_on+0x1c/0x120 ? brcmf_usb_deq+0x1a7/0x260 ? brcmf_usb_rx_fill_all+0x5a/0xf0 brcmf_attach+0x246/0xd40 ? wiphy_new_nm+0x1476/0x1d50 ? kmemdup+0x30/0x40 brcmf_usb_probe+0x12de/0x1690 ? brcmf_usbdev_qinit.constprop.0+0x470/0x470 usb_probe_interface+0x25f/0x710 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 ? usb_match_id.part.0+0x88/0xc0 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 ? driver_allows_async_probing+0x120/0x120 bus_for_each_drv+0x123/0x1a0 ? bus_rescan_devices+0x20/0x20 ? lockdep_hardirqs_on_prepare+0x273/0x3e0 ? trace_hardirqs_on+0x1c/0x120 __device_attach+0x207/0x330 ? device_bind_driver+0xb0/0xb0 ? kobject_uevent_env+0x230/0x12c0 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 ? __mutex_unlock_slowpath+0xe7/0x660 ? __fw_devlink_link_to_suppliers+0x550/0x550 usb_set_configuration+0x984/0x1770 ? kernfs_create_link+0x175/0x230 usb_generic_driver_probe+0x69/0x90 usb_probe_device+0x9c/0x220 really_probe+0x1be/0xa90 __driver_probe_device+0x2ab/0x460 driver_probe_device+0x49/0x120 __device_attach_driver+0x18a/0x250 ? driver_allows_async_probing+0x120/0x120 bus_for_each_drv+0x123/0x1a0 ? bus_rescan_devices+0x20/0x20 ? lockdep_hardirqs_on_prepare+0x273/0x3e0 ? trace_hardirqs_on+0x1c/0x120 __device_attach+0x207/0x330 ? device_bind_driver+0xb0/0xb0 ? kobject_uevent_env+0x230/0x12c0 bus_probe_device+0x1a2/0x260 device_add+0xa61/0x1ce0 ? __fw_devlink_link_to_suppliers+0x550/0x550 usb_new_device.cold+0x463/0xf66 ? hub_disconnect+0x400/0x400 ? _raw_spin_unlock_irq+0x24/0x30 hub_event+0x10d5/0x3330 ? hub_port_debounce+0x280/0x280 ? __lock_acquire+0x1671/0x5790 ? wq_calc_node_cpumask+0x170/0x2a0 ? lock_release+0x640/0x640 ? rcu_read_lock_sched_held+0xa1/0xd0 ? rcu_read_lock_bh_held+0xb0/0xb0 ? lockdep_hardirqs_on_prepare+0x273/0x3e0 process_one_work+0x873/0x13e0 ? lock_release+0x640/0x640 ? pwq_dec_nr_in_flight+0x320/0x320 ? rwlock_bug.part.0+0x90/0x90 worker_thread+0x8b/0xd10 ? __kthread_parkme+0xd9/0x1d0 ? pr ---truncated---

CVSS Details

CVSS Score
7.1
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H

Configurations (Affected Products)

cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
Linux kernel < 5.10.150
Linux kernel 5.11.x - 5.15.x(部分版本)
Linux kernel 5.16.x - 5.19.x(部分版本)
Linux kernel 6.0.x(部分版本)

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
/* * CVE-2022-50551 PoC - Trigger shift-out-of-bounds in brcmf_fw_alloc_request() * * This PoC demonstrates how to trigger the vulnerability by providing * an out-of-range chiprev value to the brcmfmac driver via a malicious * USB WiFi device emulation (using QEMU or a hardware USB device). * * The vulnerability is triggered when BIT(chiprev) is called with * chiprev >= BITS_PER_TYPE(u32) (i.e., >= 32). * * In the syzkaller report, the actual chiprev value was 151055786, * which is far beyond the valid range. */ #include <linux/usb.h> #include <linux/bits.h> #include <linux/types.h> /* Simulate the vulnerable function from brcmfmac/firmware.c */ static u32 brcmf_fw_alloc_request_vulnerable(u32 chiprev, u32 chipid) { /* VULNERABLE: No bounds check on chiprev before BIT() operation */ u32 fwflags = (chipid << 16) | BIT(chiprev); return fwflags; } /* Simulate the fixed function with bounds check */ static u32 brcmf_fw_alloc_request_fixed(u32 chiprev, u32 chipid) { /* FIXED: Check chiprev against BITS_PER_TYPE(u32) */ if (chiprev >= BITS_PER_TYPE(u32)) return 0; /* Return NULL-equivalent */ u32 fwflags = (chipid << 16) | BIT(chiprev); return fwflags; } /* Trigger the vulnerability */ void trigger_cve_2022_50551(void) { u32 malicious_chiprev = 151055786; /* Value from syzkaller report */ u32 chipid = 0x4359; /* Example Broadcom chip ID */ pr_info("Triggering CVE-2022-50551 with chiprev=%u\n", malicious_chiprev); /* This call will trigger UBSAN: shift-out-of-bounds */ brcmf_fw_alloc_request_vulnerable(malicious_chiprev, chipid); /* The fixed version safely returns 0 */ brcmf_fw_alloc_request_fixed(malicious_chiprev, chipid); } /* * To reproduce in a real environment: * 1. Set up a QEMU VM with USB emulation support * 2. Create a malicious USB device descriptor that reports an * invalid chiprev value in the Broadcom firmware handshake * 3. Attach the device to the VM * 4. The kernel will trigger the UBSAN report when brcmfmac * driver attempts to allocate firmware request * * Expected kernel log output: * UBSAN: shift-out-of-bounds in drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c * shift exponent 151055786 is too large for 64-bit type 'long unsigned int' */

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2022-50551", "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "published": "2025-10-07T16:15:41.397", "lastModified": "2026-02-26T23:17:54.647", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nwifi: brcmfmac: Fix potential shift-out-of-bounds in brcmf_fw_alloc_request()\n\nThis patch fixes a shift-out-of-bounds in brcmfmac that occurs in\nBIT(chiprev) when a 'chiprev' provided by the device is too large.\nIt should also not be equal to or greater than BITS_PER_TYPE(u32)\nas we do bitwise AND with a u32 variable and BIT(chiprev). The patch\nadds a check that makes the function return NULL if that is the case.\nNote that the NULL case is later handled by the bus-specific caller,\nbrcmf_usb_probe_cb() or brcmf_usb_reset_resume(), for example.\n\nFound by a modified version of syzkaller.\n\nUBSAN: shift-out-of-bounds in drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c\nshift exponent 151055786 is too large for 64-bit type 'long unsigned int'\nCPU: 0 PID: 1885 Comm: kworker/0:2 Tainted: G O 5.14.0+ #132\nHardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014\nWorkqueue: usb_hub_wq hub_event\nCall Trace:\n dump_stack_lvl+0x57/0x7d\n ubsan_epilogue+0x5/0x40\n __ubsan_handle_shift_out_of_bounds.cold+0x53/0xdb\n ? lock_chain_count+0x20/0x20\n brcmf_fw_alloc_request.cold+0x19/0x3ea\n ? brcmf_fw_get_firmwares+0x250/0x250\n ? brcmf_usb_ioctl_resp_wait+0x1a7/0x1f0\n brcmf_usb_get_fwname+0x114/0x1a0\n ? brcmf_usb_reset_resume+0x120/0x120\n ? number+0x6c4/0x9a0\n brcmf_c_process_clm_blob+0x168/0x590\n ? put_dec+0x90/0x90\n ? enable_ptr_key_workfn+0x20/0x20\n ? brcmf_common_pd_remove+0x50/0x50\n ? rcu_read_lock_sched_held+0xa1/0xd0\n brcmf_c_preinit_dcmds+0x673/0xc40\n ? brcmf_c_set_joinpref_default+0x100/0x100\n ? rcu_read_lock_sched_held+0xa1/0xd0\n ? rcu_read_lock_bh_held+0xb0/0xb0\n ? lock_acquire+0x19d/0x4e0\n ? find_held_lock+0x2d/0x110\n ? brcmf_usb_deq+0x1cc/0x260\n ? mark_held_locks+0x9f/0xe0\n ? lockdep_hardirqs_on_prepare+0x273/0x3e0\n ? _raw_spin_unlock_irqrestore+0x47/0x50\n ? trace_hardirqs_on+0x1c/0x120\n ? brcmf_usb_deq+0x1a7/0x260\n ? brcmf_usb_rx_fill_all+0x5a/0xf0\n brcmf_attach+0x246/0xd40\n ? wiphy_new_nm+0x1476/0x1d50\n ? kmemdup+0x30/0x40\n brcmf_usb_probe+0x12de/0x1690\n ? brcmf_usbdev_qinit.constprop.0+0x470/0x470\n usb_probe_interface+0x25f/0x710\n really_probe+0x1be/0xa90\n __driver_probe_device+0x2ab/0x460\n ? usb_match_id.part.0+0x88/0xc0\n driver_probe_device+0x49/0x120\n __device_attach_driver+0x18a/0x250\n ? driver_allows_async_probing+0x120/0x120\n bus_for_each_drv+0x123/0x1a0\n ? bus_rescan_devices+0x20/0x20\n ? lockdep_hardirqs_on_prepare+0x273/0x3e0\n ? trace_hardirqs_on+0x1c/0x120\n __device_attach+0x207/0x330\n ? device_bind_driver+0xb0/0xb0\n ? kobject_uevent_env+0x230/0x12c0\n bus_probe_device+0x1a2/0x260\n device_add+0xa61/0x1ce0\n ? __mutex_unlock_slowpath+0xe7/0x660\n ? __fw_devlink_link_to_suppliers+0x550/0x550\n usb_set_configuration+0x984/0x1770\n ? kernfs_create_link+0x175/0x230\n usb_generic_driver_probe+0x69/0x90\n usb_probe_device+0x9c/0x220\n really_probe+0x1be/0xa90\n __driver_probe_device+0x2ab/0x460\n driver_probe_device+0x49/0x120\n __device_attach_driver+0x18a/0x250\n ? driver_allows_async_probing+0x120/0x120\n bus_for_each_drv+0x123/0x1a0\n ? bus_rescan_devices+0x20/0x20\n ? lockdep_hardirqs_on_prepare+0x273/0x3e0\n ? trace_hardirqs_on+0x1c/0x120\n __device_attach+0x207/0x330\n ? device_bind_driver+0xb0/0xb0\n ? kobject_uevent_env+0x230/0x12c0\n bus_probe_device+0x1a2/0x260\n device_add+0xa61/0x1ce0\n ? __fw_devlink_link_to_suppliers+0x550/0x550\n usb_new_device.cold+0x463/0xf66\n ? hub_disconnect+0x400/0x400\n ? _raw_spin_unlock_irq+0x24/0x30\n hub_event+0x10d5/0x3330\n ? hub_port_debounce+0x280/0x280\n ? __lock_acquire+0x1671/0x5790\n ? wq_calc_node_cpumask+0x170/0x2a0\n ? lock_release+0x640/0x640\n ? rcu_read_lock_sched_held+0xa1/0xd0\n ? rcu_read_lock_bh_held+0xb0/0xb0\n ? lockdep_hardirqs_on_prepare+0x273/0x3e0\n process_one_work+0x873/0x13e0\n ? lock_release+0x640/0x640\n ? pwq_dec_nr_in_flight+0x320/0x320\n ? rwlock_bug.part.0+0x90/0x90\n worker_thread+0x8b/0xd10\n ? __kthread_parkme+0xd9/0x1d0\n ? pr\n---truncated---"}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H", "baseScore": 7.1, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.8, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-125"}]}], "configurations": [{"nodes": ... (truncated)