Reviving a BlackBerry KEY2
I put LineageOS on an old BlackBerry KEY2 from a Guix machine
I’ve had a BlackBerry KEY2 sitting in a drawer since it stopped getting updates. Physical keyboard, small screen. The hardware was fine, the software had been dead for years. This week I finally put LineageOS on it.
There’s a small community keeping this device alive (Lineage-BBKey2, unofficial, actively maintained), and the recipe is well documented:
- Unlock the bootloader with kibo, which exploits a fastboot buffer overflow
- Reflash BlackBerry’s own signed firmware through their autoloader
- Sideload LineageOS and GApps through recovery
None of that is new. The twist: I did it from a Guix machine, and Guix doesn’t play along with anything that expects a normal Linux filesystem.
Guix has no /lib64/ld-linux-x86-64.so.2
Google’s platform-tools and kibo’s prebuilt binary both expect /lib64/ld-linux-x86-64.so.2 and a handful of libraries at fixed paths. None of that exists on Guix. patchelf fixes it:
$ patchelf --set-interpreter $GLIBC/lib/ld-linux-x86-64.so.2 \
--set-rpath "$GLIBC/lib:$LIBUSB/lib" kibo
Point the interpreter and rpath at the right store paths and the binary runs natively; no container, full USB access. Guix does package adb and fastboot, but they’re stuck at 7.1.2 from 2016. Google’s current 37.0.1 splits sparse images properly, which matters when you push a 3.2GB system.img against a 512MB per-transfer limit.
kibo’s device check was wrong
The unlock guide says to flash BlackBerry’s firmware twice (their A/B implementation is that broken). I did, and kibo still reported one of the two boot chains as INVALID and refused to unlock.
I wrote a small USB probe with pyusb to dump the raw response to the info query. Turns out kibo reads fixed-size buffers off the wire and never null-terminates them, so its strcmp() calls sometimes read past the real bytes into whatever is left on the stack. One buffer happened to sit next to a zero; the other didn’t.
kibo is GPL and three source files. Three lines to null-terminate each response at its actual length, then rebuild:
$ guix shell cmake make gcc-toolchain pkg-config libusb-next -- \
cmake -B build && cmake --build build
Second run: Your device is vulnerable.
The result
The unlock went through, LineageOS 22.2 and MindTheGapps sideloaded without trouble, and the KEY2 booted Android 15 on a Snapdragon 660 from 2018. Gboard doesn’t reliably hide itself for the hardware keyboard on this build; K12KB, which the ROM ships for exactly that reason, does.
It’s a 2018 phone on an unofficial port. Dual SIM has a known bug (I only use one). But the keyboard clicks like new, and the phone that sat in a drawer for two years is back in my pocket. Good luck :)
Links
- Lineage-BBKey2 releases (KEY2) and Lineage-BBKey2LE releases (KEY2 LE)
- kibo - the bootloader unlock tool
- XDA: Unlock bootloader, KEY2 / KEY2 LE - firmware versions and step-by-step
- XDA: LineageOS 22.2 for the KEY2
- K12KB - hardware keyboard app