In this exclusive writeup, we’ll walk you through the CVE-2021-46970 Linux kernel vulnerability, specifically within the Qualcomm MHI (Modem Host Interface) generic PCI bus driver. We’ll cover technical background, bug impact, warning messages, the actual exploit surface, and how it was resolved—all in plain American English, with code snippets and links to original references.
What is CVE-2021-46970?
- CVE ID: CVE-2021-46970
- Component Affected: Linux kernel MHI PCI generic driver (drivers/bus/mhi/pci_generic.c)
- Type: Misuse of Workqueue Flags, potential kernel warning/crash (not classic privilege escalation)
The Linux kernel’s MHI PCI generic bus driver wrongly set the WQ_MEM_RECLAIM flag on a workqueue used for state changes, even though the work performed there isn’t supposed to participate in reclaiming memory. This causes the kernel to log a warning and, in tighter configurations, could potentially trigger disruptions in the memory management path.
Technical Background: Workqueues and WQ_MEM_RECLAIM
Linux kernel workers can be scheduled on workqueues (WQ). If a workqueue is marked with the WQ_MEM_RECLAIM flag, it means tasks queued here are NECESSARY to reclaim memory, so the kernel schedules them even under memory pressure.
But if you put non-reclaim tasks on such a queue, the kernel will still treat it specially—which can be dangerous, since your code might then _block_ or make further memory allocations, which is not what you want during a memory-shortage emergency. It can also cause dependency warnings.
The Vulnerable Code
The MHI driver created a high-priority workqueue with both WQ_HIGHPRI and WQ_MEM_RECLAIM flags, then scheduled state change workers (mhi_pm_st_worker) on it.
// Excerpt from old driver bus/mhi/pci_generic.c
mhi_cntrl->hiprio_wq = alloc_workqueue("mhi_hiprio_wq",
WQ_HIGHPRI | WQ_MEM_RECLAIM, );
But the state worker it runs (mhi_pm_st_worker) sometimes waits for MORE memory (like firmware allocations, device creation) and certainly can block—not appropriate for memory reclaim path.
The system’s workqueue checks noticed this, emitting a warning basically saying
> “Hey, you’re flushing work from a memory reclaim workqueue, but the work isn’t suitable for memory reclaim!”
Here is the kernel warning log
[ 40.969601] workqueue: WQ_MEM_RECLAIM mhi_hiprio_wq:mhi_pm_st_worker [mhi] is flushing !WQ_MEM_RECLAIM events_highpri:flush_backlog
[ 40.969612] WARNING: CPU: 4 PID: 158 at kernel/workqueue.c:2607 check_flush_dependency+x11c/x140
...
[ 40.969804] mhi_pm_st_worker+x921/xf50 [mhi]
Bottom line: While this isn’t a root exploit by itself, it sets up a dangerous kernel state and can provoke issues in heavy-load or memory-pressure scenarios.
Provoking memory pressure (e.g., via stress tests or crafted workloads).
2. Force the MHI state change worker to run (e.g., by rapidly plugging/removing MHI devices or triggering firmware loads).
3. Trigger kernel warnings and possible kernel panic (in strict configs or with kernel line parameters like panic_on_warn=1).
Here’s a (pseudo) shell way to reproduce the warning if running a vulnerable kernel
#!/bin/bash
# WARNING: Only run in a VM or test box!
for i in {1..100}; do
echo "Simulating hot-plug of MHI device #$i"
# Unplug device (simulate, real device unplug if possible)
# ... or unload/load module, e.g.:
modprobe -r mhi_pci_generic
modprobe mhi_pci_generic
# Optionally stress the memory
stress --vm 2 --vm-bytes 512M --timeout 10 &
sleep 1
done
dmesg | grep workqueue
If the kernel is vulnerable, you’ll likely see the warning logs like the ones above.
The Fix
The fix is super simple: remove the improper WQ_MEM_RECLAIM flag.
Here’s the fixed code
- mhi_cntrl->hiprio_wq = alloc_workqueue("mhi_hiprio_wq",
- WQ_HIGHPRI | WQ_MEM_RECLAIM, );
+ mhi_cntrl->hiprio_wq = alloc_workqueue("mhi_hiprio_wq",
+ WQ_HIGHPRI, );
Reference Commit:
- Upstream Patch: “bus: mhi: pci_generic: Remove WQ_MEM_RECLAIM flag from state workqueue”
References & Original Sources
- Linux kernel commit fixing the bug
- CVE Database: CVE-2021-46970
- Linux kernel workqueue documentation
Should You Worry?
- Who is affected? Systems running kernels with MHI modem support (e.g. Android devices, ARM SoCs, some laptops with Qualcomm WWAN)
- Practical consequences: Usually just kernel log warnings, but CAN crash or panic hardened systems.
Is it privilege escalation? No, but can cause DoS in edge cases.
- How do I fix? Upgrade your kernel to a version after this patch (v5.14+), or backport the patch to your own build.
Conclusion
CVE-2021-46970 shows how even subtle kernel flag mistakes can lead to stability problems, and why careful workqueue configuration is critical for driver developers. While not “hackable” in the usual sense, these bugs can still knock over mission-critical or high-security Linux systems.
For maintainers, always double-check your workqueue flag logic!
For users, keep your kernels up to date.
Timeline
Published on: 02/27/2024 19:04:07 UTC
Last modified on: 01/08/2025 17:22:48 UTC