A recently patched security issue in the Linux kernel, tracked as CVE-2024-36016, exposes devices to a risky out-of-bounds write, potentially leading to system instability or even remote code execution under certain conditions. This vulnerability affects the n_gsm line discipline in the TTY (teletype) subsystem, an optional component for handling GSM 07.10 multiplexing—a feature often used in modems, embedded, and IoT devices.
TL;DR
CVE-2024-36016 allows out-of-bounds writes in the Linux kernel via the TTY n_gsm module caused by missed state resets when switching between basic and advanced option modes during data reception. This can be exploited to corrupt kernel memory, leading to unpredictable consequences, including crash or code execution.
Background: What is n_gsm?
The n_gsm kernel module implements the "GSM 07.10" protocol, a multiplexing protocol commonly used in modems. It lets multiple data streams share one serial line, supported by the gsm_receive() and gsm1_receive() functions.
Side A: Switches back to basic option mode.
6. Side B: Continues sending data; kernel’s gsm_receive() writes past the end of the buffer (because it didn't reset critical state variables after the config changes).
Technical Root Cause
- The function used to check if the buffer is full compared gsm->count == gsm->len, instead of gsm->count >= gsm->len.
gsm->len wasn't enforced as an upper limit after the mode changes.
- No bounds check against the constant MAX_MRU (maximum message receive unit), increasing the risk of memory corruption.
Code Snippet (Before the Fix)
// Snippet from the old kernel source (vulnerable)
if (gsm->count == gsm->len) {
process_frame(gsm->buf, gsm->len);
}
// No upper-bound check on gsm->len, gsm->mru!
Here, data can keep accumulating past gsm->buf if gsm->count never exactly matches gsm->len, leading to out-of-bounds writes.
Code Snippet (After the Fix)
// Fixed version (see kernel.org commit bcc39e29baa)
if (gsm->count >= gsm->len) {
process_frame(gsm->buf, gsm->len);
}
// Additional hardening
if (gsm->len > MAX_MRU || gsm->mru > MAX_MRU) {
// Limit data to sane values
return -EINVAL;
}
Reference
- Upstream patch with full diff
Attack Scenario
> Warning: This section is for educational purposes only. Do not attempt to attack systems you do not own.
Suppose you control "side B" in the above scenario (say, by exploiting a serial-connected modem exposed to untrusted input):
Send a header of a basic mode frame with a very *small* data length (e.g., 1 byte).
3. Convince the remote machine (side A) to switch to *advanced option mode*—this may be possible via software commands or timing tricks.
4. Send more data than intended (2 bytes, up to MAX_MRU)—kernel would now interpret memory incorrectly, as the new mode is not enforcing the correct length.
Switch back to basic option mode.
6. Continue sending data. The kernel's state variables have not been reset—they believe more data is valid. This leads the receive buffer logic to write past the end of the allocated buffer, corrupting adjacent kernel memory.
Data corruption or memory leaks
- Potential code execution if attacker controls what gets written past the buffer (e.g., via crafted payloads)
Embedded devices, routers, and modems using the Linux kernel’s GSM multiplexing features
- Any custom hardware or software relying on GSM 07.10 multiplexed TTY via serial/USB interfaces
How was it Fixed?
1. Corrected the buffer fullness check:
Changed from if (gsm->count == gsm->len) to if (gsm->count >= gsm->len), ensuring no overflow even if the state gets desynchronized.
2. Added upper bound checks:
Explicitly limited gsm->len and gsm->mru to the protocol's maximum, MAX_MRU, to prevent malformed values from being abused.
3. Maintained all existing frame validation:
Existing checks stay, preserving user-specified data limits.
Commit fixing CVE-2024-36016:
bcc39e29baa4: tty: n_gsm: fix possible out-of-bounds in gsm_receive()
CVE details:
Linux kernel changelog:
Update your Linux kernel to a version including this fix (or newer).
- Use input sanitization and authentication between trusted endpoints when using GSM 07.10-multiplexed interfaces.
- Minimize exposure of modem/serial interfaces to untrusted networks or devices.
Final Thoughts
CVE-2024-36016 is a powerful example of how subtle state desynchronization bugs in system software can lead to severe security problems. This bug, hiding deep in a rarely scrutinized subsystem, could allow attackers to compromise or crash devices under very specific—but realistic—conditions. If your devices use GSM multiplexing, patch immediately.
Stay safe, keep your kernels up to date, and watch those state machine transitions!
*Want to dive deeper? Read the fix commit on kernel.org.*
Timeline
Published on: 05/29/2024 19:15:48 UTC
Last modified on: 07/15/2024 07:15:04 UTC