CVE-2026-95622: ModemManager Cell Broadcast Assert Crash
Reachable g_assert_not_reached() in the CBM PDU parser
A remotely reachable assertion in ModemManager's Cell Broadcast parser. A cell broadcast message with an unsupported data coding scheme leaves the encoding field at its zero-initialised value, and the encoding switch aborts the root daemon on it. Reported upstream; fix under review.
- Status
- Assigned CVE
- Identifier
- CVE-2026-95622
- Touches
- ModemManager / Linux / Cellular / DoS / D-Bus
- References
At a glance
ModemManager parses cell broadcast messages that arrive unsolicited from the cellular network. mm_cbm_part_new_from_binary_pdu() in src/mm-cbm-part.c allocates the part with g_slice_new0, so its encoding field starts at zero, which is MM_SMS_ENCODING_UNKNOWN. For the general and UDH coding groups the parser only sets the encoding when the charset bits say GSM7 or UCS2. The two other legal charset values, 8-bit and reserved, leave the field at UNKNOWN. A little later the encoding switch has no case for UNKNOWN and falls through to g_assert_not_reached(), which aborts the process.
ModemManager runs as root and systemd restarts it, so a network that keeps sending the message crashes it on every start. The trigger is a legal data coding scheme byte per 3GPP TS 23.038, not a malformed PDU.
- Class: CWE-617, reachable assertion
- CVSS 3.1: 6.5 (Medium), AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
- Component:
src/mm-cbm-part.c,mm_cbm_part_new_from_binary_pdu() - Impact: remote denial of service of the root daemon, no authentication, no user interaction
- Trigger: a cell broadcast message whose DCS selects an unhandled charset (24 of 256 DCS bytes)
- Affected: ModemManager main at 306f6256, both the AT and QMI ingestion paths
Where does the message come from? Over the air. So the attacker is a rogue base station in radio range, or a compromised carrier, the same scenario the upstream commit calls out. It is not code execution. It is one valid message, sent by whatever your modem is currently camped on, that takes down a root daemon.
Write-ups
I wrote two posts about this one. A technical breakdown of the parser, the zero-initialised default, the DCS layout, and the fix, and a longer story about finding it, proving it with a fork-per-byte sweep, and being handed the maintainer’s patch with the question “is this the correct fix?”