Jolla announced a new phone coming later this year. A purpose built device running Sailfish OS. I do not throw words like this around lightly but this genuinely got me excited in a way no phone announcement has in years. The last time I felt this way about a mobile device was the Nokia N9. We all know how that ended. This feels different.

So I dug out my Xperia 10 with Sailfish flashed, and started doing what you can only do when you have a real Linux phone. I started scripting.

GrapheneOS is Android with lipstick

Before anyone comes at me, GrapheneOS is impressive work. Serious people built it and the hardening is real. But it is still Android underneath. You are working within a security model that Google designed, with permissions Google defined, on an architecture Google controls. You are hardening a cage. A very nice cage, but a cage.

Sailfish is different. It runs a real Linux kernel. udev works. systemd works. Shell scripts are first class citizens. The same tools I use on my servers run on my phone without modification. That is not a small thing. That changes what is actually possible.

What Cellebrite does and why it matters

Cellebrite UFED is a commercial forensic extraction tool used by law enforcement and border agencies worldwide. It connects via USB and extracts data from phones. The attack surface is the USB connection. The device speaks to your phone before you can do anything about it at the application layer.

The defense is equally simple. Do not let unauthorized USB devices communicate with your phone in the first place. Handle it at the kernel level before any userspace application gets a chance to respond. This is exactly what udev was built for.

The implementation

I wrote a udev rule that fires on any USB add event. It checks the connecting device against a whitelist of authorized vendor and product IDs. Every charging cable I own is on that list. Everything else triggers the response.

The rule itself is one line:

ACTION=="add", SUBSYSTEM=="usb", \
  RUN+="/usr/local/sbin/usb-check.sh"

Fires on connection. Passes execution to a script immediately. No delay, no user interaction required, no chance for the connecting device to establish communication first.

The whitelist check:

#!/bin/sh

VENDOR=$(cat /sys$DEVPATH/idVendor 2>/dev/null)
PRODUCT=$(cat /sys$DEVPATH/idProduct 2>/dev/null)

# Authorized devices
# Get these by running lsusb with your own cables
WHITELIST="
05c6:9205
0fce:5196
"

for DEVICE in $WHITELIST; do
    if [ "$VENDOR:$PRODUCT" = "$DEVICE" ]; then
        exit 0
    fi
done

# Not on the list
/usr/local/sbin/usb-response.sh &

To build your own whitelist plug in every cable and charger you own and run lsusb. Note the vendor and product IDs. Add them. Everything else is not authorized.

The rule file lives in a root owned location with a filename chosen to be unremarkable among the other rules already present. I know where it is. Nobody else needs to.

The response

When an unauthorized device connects the response script runs as root immediately. Here is the full sequence.

The display wakes up via D-Bus so whoever is holding the phone can see exactly what is about to happen to them:

dbus-send --system --print-reply \
  --dest=com.nokia.mce \
  /com/nokia/mce/request \
  com.nokia.mce.request.req_display_state_on \
  >/dev/null 2>&1

Then one of several GIFs starts playing. I made a few. Blinking text saying "not today officer". A Theoden meme. Gandalf. You shall not pass energy but aimed specifically at forensic extraction tools. The script picks one at random:

GIFS=(/home/nemo/Pictures/unauthorized*.gif)
RANDOM_GIF="${GIFS[RANDOM % ${#GIFS[@]}]}"
su nemo -c "xdg-open $RANDOM_GIF" &
sleep 20

Twenty seconds. Long enough to be seen. Long enough to be uncomfortable.

Then a random message from the array:

messages=(
    "UNAUTHORIZED SNOOP DETECTED\nGo fuck yourself, piggy. Smile — you're being recorded while reading this. My data stays private. 🖕"
    "ACCESS DENIED, RENT-A-COP\nNice try with the forensics kit. This phone doesn't bend over for tyrants. Recording your fail in 4K."
    "INTRUSION BLOCKED\nSilent capture active. Got your face forever, officer. Better luck raiding an iPhone next time. 😈"
)

RANDOM_MSG="${messages[RANDOM % ${#messages[@]}]}"
su nemo -c "notify-send '$RANDOM_MSG'" &
sleep 5

I have spent genuine time on these messages. This is not accidental rudeness. This is considered, deliberate rudeness toward tools and people attempting unauthorized extraction of private data. I feel no obligation to be gracious about it.

Then the finale:

notificationtool add \
    --summary="RECORDING COMPLETE" \
    --body="Gotcha forever. Shutting down now. GG, bootlicker." \
    --urgency=2 \
    --expire=5000

sleep 5

logger "Unauthorized USB connection — response triggered — shutting down"

systemctl poweroff

"GG bootlicker" is the last thing displayed before the screen goes black.

The full response script assembled:

#!/bin/sh

# Wake display
dbus-send --system --print-reply \
  --dest=com.nokia.mce \
  /com/nokia/mce/request \
  com.nokia.mce.request.req_display_state_on \
  >/dev/null 2>&1

# Random GIF
GIFS=(/home/nemo/Pictures/unauthorized*.gif)
RANDOM_GIF="${GIFS[RANDOM % ${#GIFS[@]}]}"
su nemo -c "xdg-open $RANDOM_GIF" &
sleep 20

# Random message
messages=(
    "UNAUTHORIZED SNOOP DETECTED\nGo fuck yourself, piggy. Smile — you're being recorded while reading this. My data stays private. 🖕"
    "ACCESS DENIED, RENT-A-COP\nNice try with the forensics kit. This phone doesn't bend over for tyrants. Recording your fail in 4K."
    "INTRUSION BLOCKED\nSilent capture active. Got your face forever, officer. Better luck raiding an iPhone next time. 😈"
)
RANDOM_MSG="${messages[RANDOM % ${#messages[@]}]}"
su nemo -c "notify-send '$RANDOM_MSG'" &
sleep 5

# Finale
notificationtool add \
    --summary="RECORDING COMPLETE" \
    --body="Gotcha forever. Shutting down now. GG, bootlicker." \
    --urgency=2 \
    --expire=5000

sleep 5

# Log and shut down
logger "Unauthorized USB — response complete — powering off"
systemctl poweroff

What this actually protects against

Cellebrite and similar tools require the device to be running and communicating over USB. Shutdown removes that. A powered off encrypted device is a fundamentally different forensic proposition than a running one.

This does not make the device indestructible. A sufficiently resourced attacker with physical access, time and the right tools has options that go beyond USB extraction. I am not claiming otherwise. What this does is remove the USB attack surface entirely, log the attempt, and move the device to its most secure state while making the experience as unpleasant as possible for whoever triggered it.

The twenty seconds of GIF and messages before shutdown is not purely entertainment. It means there is no quiet extraction attempt. Anyone watching sees exactly what happened. There is a cartoon telling them to go away, then an insult, then "GG bootlicker", then a dead phone.

The new Jolla device

What excites me about the new phone is not the specs. It is the signal. Jolla building purpose built hardware for Sailfish means they still believe there is a real market for people who want actual Linux in their pocket and are willing to work for it.

The Xperia adaptation program has kept Sailfish alive on Sony hardware for years. Community ports have gone further. But a device designed from the ground up for Sailfish changes the development story entirely. No fighting Android hardware abstraction layers. No hoping Sony does not break something in a firmware update. A real platform built for the OS from the start.

I cannot wait to get one and immediately start doing things to it that nobody intended.


Jolla Phone (Sep 2026)
The independent European Do It Together (DIT) Linux phone, shaped by the people who use it.
The Privacy Respecting European OS and AI Solution Provider
Jolla offers privacy-first OS and Edge AI solutions continuing the legacy of Nokia and MeeGo, driving mobile innovation into the human-centric AI era.