CVE-2024-46692 - Linux Kernel Qualcomm SCM get_wq_ctx() Deadlock Vulnerability Explained
On May 2024, a vulnerability was assigned CVE-2024-46692 involving the Qualcomm Secure Channel Manager (SCM) in the Linux kernel. If your Linux device relies on Qualcomm firmware support (common in Android smartphones and embedded devices), this affects system stability. This write-up explains the underlying bug, exploit scenario, technical details, and why marking get_wq_ctx() as an atomic ("fast") call fixes it.
TL;DR
CVE-2024-46692 is a kernel bug where the Qualcomm firmware management code (qcom_scm) could deadlock if two or more secure monitor calls (SMCs) sleep/wake at the wrong times. The core fix is marking get_wq_ctx() as an atomic ("fast") call, preventing it from sleeping and avoiding deadlocks.
Background: What is Qualcomm SCM?
Qualcomm Secure Channel Manager (SCM) lets the Linux kernel make requests to the secure world (TrustZone) via Secure Monitor Calls (SMC). This is essential on Qualcomm-based systems for operations like secure boot, cryptography, and firmware updates.
The Linux kernel provides a driver at drivers/firmware/qcom_scm.c for this.
The Vulnerable Flow: Understanding The Deadlock
- Wait Queues: To track which threads are waiting on a Secure Monitor Call, the kernel uses "wait queue contexts".
- get_wq_ctx(): This function allocates or locates these contexts before transferring control to secure firmware.
Problem:
get_wq_ctx() was marked as a standard SMC call, which means it could sleep or block.
- If two SMC calls went to sleep (e.g., awaiting hardware/service), and one SMC returned and woke up, it would call get_wq_ctx() to resume.
- If, during get_wq_ctx(), the function was interrupted or put to sleep—and at the same time another SMC waited for a waitq context—this created a classic deadlock: each thread waits for the other, and nothing can progress.
The Simple Fix
Atomic SMC Calls:
Some Secure Monitor Calls must *never* sleep—called 'fast' or 'atomic' calls. These always run to completion without interruption.
Patch Summary:
Patch Snippet
- ret = qcom_scm_call(scm, &desc, &res);
+ ret = qcom_scm_call_atomic(scm, &desc, &res);
Exploit Scenario
This bug is about system availability (DoS), not directly gaining root or code execution.
What could happen?
- If an attacker triggers multiple SMCs in a row and forces them to sleep, they might purposely exhaust wait queue contexts.
- When one thread wakes up and calls get_wq_ctx(), it could hang, deadlocking the kernel based on timing.
Who does this affect?
- Any system using the qcom_scm kernel driver (mainly Android/embedded Qualcomm devices).
Pseudocode
/* PSEUDO: Thread 1 */
desc = prepare_smc_desc();
ret = qcom_scm_call(&desc, &res); // Goes to sleep
/* PSEUDO: Thread 2 */
desc2 = prepare_smc_desc();
ret2 = qcom_scm_call(&desc2, &res2); // Goes to sleep
// Thread 1 wakes up
get_wq_ctx(); // SLEEPS! Potential deadlock
Fixed version
// Thread 1 wakes up
qcom_scm_call_atomic(&desc, &res); // Cannot sleep - avoids deadlock!
CVE Record:
https://cve.org/CVERecord?id=CVE-2024-46692 *(May be pending update)*
Upstream Patch:
or
Linux Firmware qcom_scm code:
linux/drivers/firmware/qcom_scm.c
What Should You Do?
- Device vendors: Backport this patch as soon as possible, especially for actively supported phones, tablets, routers, and IoT devices running Qualcomm chips.
Users: Watch for OS updates, especially custom ROMs and embedded device firmware.
- Developers: Never use standard SMC calls for waitq management functions—always consider atomicity in low-level kernel-firmware protocols.
Final Thoughts
CVE-2024-46692 is a subtle but critical bug: not a typical security hole, but a kernel-level DoS against Qualcomm-equipped Linux systems. The real value is in learning: in kernel/firmware work, always identify which calls must be atomic! For embedded devices, this deadlock could make your product randomly hang, crash, or reboot—so get patching!
*For more detail, see the upstream patch discussion or follow the kernel.org log. Stay secure!*
Timeline
Published on: 09/13/2024 06:15:14 UTC
Last modified on: 09/15/2024 17:57:46 UTC