· 5 min read ·

The Compliance Theater Inside Lenovo's WWAN Unlock Binary

Source: lobsters

A developer recently posted a 100-line bash script that replaces Lenovo’s proprietary WWAN unlock binary, and it works. The modem initializes, registers on the network, and behaves exactly as it does with the official executable. The script exists because someone sat down with strace, usbmon, and a Wireshark session, documented what the binary was sending, and wrote the equivalent in shell.

The more interesting question is why the binary existed in the first place, given that the Linux modem ecosystem had already built a proper, open architecture for exactly this purpose.

What FCC Unlock Requires

The regulatory justification for modem unlock blobs traces to FCC equipment authorization rules and, for unlicensed spectrum, the software-defined radio provisions of Part 15. Modems certified for specific frequency bands and power limits must not be trivially reconfigurable outside those parameters. OEMs solve this by shipping modems in a locked state and providing a controlled unlock mechanism that enables only the certified configuration.

This is a legitimate regulatory requirement. What the rules do not specify is that the unlock mechanism be a compiled binary executable. They require that the configuration not be “freely modifiable by the user,” a phrase interpreted in practice as “not a plain-text configuration file that any user can edit at will.” Scripts delivered through system package management, invoked by a daemon running as root, qualify as not-freely-modifiable in the same sense that binaries do. ModemManager ships shell scripts in its fcc-unlock.d directory for exactly this purpose, without regulatory objection, which confirms the interpretation.

Three Pressures That Produce a Binary

The FCC argument is the public-facing justification for the blob. Two others do more work in practice.

The first is vendor NDAs. Fibocom, Sierra Wireless, and Quectel license modem initialization sequences to OEMs under agreements that typically forbid republication. The modem vendor wants to protect firmware internals; the NDA forbids shipping the initialization sequence in readable form. A compiled binary satisfies the letter of that restriction. A shell script does not, because the sequence is visible to anyone with a text editor.

The second is gray-market protection. WWAN modules on ThinkPads are paid add-ons. Higher-tier modules with broader band support carry meaningfully higher prices than entry-level variants. If the unlock mechanism validates hardware identity against a whitelist, an aftermarket module cannot be trivially unlocked in a machine that shipped with a lower-tier option. An opaque binary provides that check without documenting how it works. A readable script makes the check visible and therefore gameable.

Neither concern is served by a compiled binary in any security-meaningful sense. A determined person with strace and usbmon can extract the initialization sequence from any blob in an afternoon, as this episode demonstrates. The binary model provides obscurity, not security.

What the Binary Was Doing

The reverse engineering work in the Hofstede article, cross-referenced with the community project the-sz/lenovo-wwan, shows the mechanism varies by modem generation.

For older Fibocom modules like the L850-GL (Intel XMM7360, USB ID 2cb7:0007), the primary operation is a write to the Linux rfkill subsystem. The thinkpad_acpi driver places a soft rfkill block on the modem at initialization. The blob iterates /sys/class/rfkill/rfkill*, identifies the interface with type wwan, and writes 1 to its state file; the rest of the binary is scaffolding around that single kernel call.

For newer MBIM-based modems (L860-GL, FM350-GL), the mechanism moves to a vendor extension command over the modem’s USB control channel. MBIM structures messages as service-UUID plus command-ID pairs. Standard services handle registration, SMS, and bearer management; Lenovo uses a proprietary UUID with command ID 0x0F, sending a payload derived from the modem’s IMEI. The wire format of that command looks like this:

MBIM_COMMAND_MSG {
  MessageType:             0x00000003
  ServiceId:               {Lenovo-proprietary UUID}
  CID:                     0x0F
  CommandType:             0x01  (SET)
  InformationBuffer:       {IMEI-derived token}
}

The token derivation is simple enough that two data points are sufficient to reverse it; XOR against a static key embedded in the binary reveals the pattern immediately. On Sierra Wireless modules using Qualcomm chipsets, like the EM7455, the equivalent lives in the AT! vendor namespace. Commands like AT!ENTERCND="A710" unlock command mode, followed by band configuration via AT!BAND and a reset. The mbimcli tool from libmbim handles the MBIM path; a file descriptor to /dev/ttyUSB2 handles the AT path.

Across all variants, the binary was obscuring a sequence of calls to documented interfaces. Nothing about those interfaces required opacity to function.

ModemManager’s Answer

ModemManager 1.18 introduced the fcc-unlock.d drop-in system specifically because this problem was already understood. Place an executable file named after the device’s USB VID:PID (such as 2cb7:0111 for a Fibocom module) into /usr/share/ModemManager/fcc-unlock.d/, and ModemManager invokes it automatically when it detects a modem requiring authorization. The plugin receives CONTROL_PORT and MODEM_PHYSDEV_UID as environment variables and signals success or failure by exit code.

ModemManager already ships unlock scripts for several Fibocom and Quectel variants. Inspecting the ModemManager source tree shows plain shell scripts using mbimcli and qmicli to send vendor initialization sequences. These are version-controlled, auditable, and updated through normal package management when modem variants change. The FCC has not intervened.

Lenovo chose to bypass this architecture and deliver an opaque binary installed outside ModemManager’s lifecycle, triggered via a standalone udev rule, running as root with no source available for review. The fcc-unlock.d system exists for exactly Lenovo’s use case. Lenovo never contributed to it.

The Security Cost

A root-level executable triggered on every device attach is not a trivial trust surface. On Qualcomm modems, the AT! namespace reaches NV storage modification and firmware image slot selection, interfaces a compromised binary could interact with silently, since its actions are opaque by design. The IMEI-derived token means the binary processes hardware identity information; a compromised version could exfiltrate it without any observable OS-level behavior.

Binary blobs also do not receive security updates after device end-of-life. A ThinkPad T490 on a recent kernel runs the same unlock binary it shipped with, regardless of vulnerabilities found since. A script in the ModemManager plugin directory is updated when the package maintainer updates ModemManager. These are not equivalent maintenance models.

The contrast sharpens when you consider that the reverse engineering tools that exposed this blob are standard Linux utilities. The usbmon kernel module captures USB bus traffic at the host controller level; loading it and opening /dev/usbmon0 in Wireshark gives a live decode of every MBIM message, with the built-in MBIM dissector labeling service UUIDs and command IDs. Running strace -e trace=read,write,open,ioctl against the blob reveals the device nodes it touches and the raw bytes it writes. Interposing a pseudo-terminal with socat -v PTY,link=/tmp/modem_fake,rawer /dev/ttyUSB2,rawer logs the full AT command transcript verbatim. These tools come with any Linux distribution. The blob was never meaningfully hidden from anyone willing to look.

What the Bash Replacement Confirms

The 100-line bash script confirms there was no novel cryptography, no proprietary protocol, no initialization sequence that the modem vendor would be embarrassed to publish in a public source tree. There was a sysfs write, an MBIM vendor command with a simple IMEI-based token, and in some variants a handful of AT commands documented in vendor developer references.

The right long-term home for that script is a ModemManager fcc-unlock.d plugin, deployed through normal package management, auditable by any user or distribution maintainer. The infrastructure for that has existed since ModemManager 1.18. The bash replacement made visible what a vendor binary had been obscuring, and confirmed that the obscuration was not serving any of the purposes it claimed to serve.

Was this interesting?