Whose Computer Is This? Yours, or…

Published 2026-09-19
Whose Computer Is This? Yours, or…
Series: Whose computer is it?Part 1 of 8

The opening article of the series. We wrote an OS from scratch in Rust and booted it on a production Samsung Galaxy Tab S6 tablet (Snapdragon 855). What follows is not about Rust and not about the tablet. It is about who else lives inside this device, what rights each of them holds, and why our OS is far from the most privileged tenant. The rest of the series is about how we found this out — one discovery at a time.


1. The naive picture

When you write an OS for a microcontroller, the picture is simple: there is a processor, there is memory, there are peripherals. You are the only code that runs. Whatever you did not write does not exist. All privileges are yours, and so is all responsibility.

We brought that picture to the tablet. The bootloader hands control to our image at EL1, and from there on it is our memory, our MMU, our drivers. Or so it seemed.

It took about ten silent reboots of the entire chip — no panic, no message, no interrupt — for the picture to be replaced with an honest one: at least eight executing entities live in this device, seven of them were written by someone else, and almost every one of them can kill us, while we can kill none of them.

2. The tenants

Here they are, from the most privileged down to us. For each: where it runs, whose code it is, what power it holds over us, and how we found out (usually through a reset).

TenantWhereWhose codeWhat it holds over usHow we found out
TrustZone (secure world, EL3)the same cores, secure modeQualcomm (+ Samsung)Loads and verifies the signatures of the other tenants' firmware (PAS). Puts XPU fences on memory: one byte read past a fence by us — silent reset. Owns the modem registers (QDSP6SS): a read is a bus error. Decides who owns which RAM region (assign_mem). Its own log is encrypted and wiped on resetresets #1, #2, #9; every memory handover to the modem goes through it
Hypervisor (EL2)the same cores, one level above usSamsungOwns the SMMU (qcom,skip-init — the global configuration is his): stage‑2 translation of all DMA masters is his, stage‑1 is left to us. Vetoes writes of S2CR type bypass — they come back as fault. Forwards our smc calls to TrustZone. His memory hyp_mem is no-map: a speculative CPU read into it is a resetattempting to configure the SMMU for Wi‑Fi; reset #10 (preventively)
AOP (Always‑On Processor)a separate Cortex‑M core inside the SoCQualcommControls power and clocks through RPMh: every rail is a vote by name from a command database (cmd-db) that he also stores. The copy of the database in his message RAM is closed: a read stops the processor. Without his load_state modem on the modem does not load; without the qdss clock, Wi‑Fi does not start. Our wrong vote vote(0) for cx.lvl powered down the digital logic of the whole SoCreset #3, reset #8
S‑Boot (bootloader)before us; stays in two slots on diskSamsungDecides what boots at all: boot or recovery, by the reboot‑reason byte in the PMIC. Picks the device tree by msm-id, enters EL1 "wherever it likes" (our image is PIE). Leaves behind rail votes on behalf of APPS and a framebuffer with a logo, which we hijack as our display. A dying recovery is no longer booted — by itselfthe experiment with the recovery reason that led into Download mode
Modem (MPSS, Hexagon)a separate DSP, 160 MiB carve‑outQualcomm, 80 MB of signed firmwareInside — three domains: cellular, GNSS, WLAN. Demands four servers from us (rmtfs, tqftp, pd‑mapper, memshare), shared SMEM memory, GLINK/QRTR/QMI queues. Without EFS it dies in 40 s; on a refusal to open fsg — in 23 ms. Its own radio, its own uplinkresets #4, #5, #6, #7; all of Wi‑Fi stages 3–4
WLAN copy engines12 DMA channels in WCSSexecute descriptors written by the modem firmwareDMA into physical memory — stream 0x640 goes through the SMMU without stage‑1 translation. The only fences are the hypervisor's and the XPU's, not oursSMMU analysis; docs/wifi-threat-model.md
Display controller (MDSS)DMA master, stream 0x800hardware + bootloader setupScans the framebuffer memory through the same SMMU. We never brought up the display — we replaced the contents of what it was already showingmilestone 0: stripes and colour cycles, from which we guessed the stride and byte order
PMIC (PM8150) over SPMIa separate chipQualcommReboot reasons (PON), the byte for the bootloader, and SDAM — the only non‑volatile memory where we can write a word before a dangerous step and read it back after a reset. Our only witnessthe silent‑reset methodology
Us (EL1)APPS cores, a ~85 MiB heap between the image and the first reserveour RustWe vote for rails (with the AOP's permission), ask TrustZone to load the modem, serve the modem, program stage‑1 of the SMMU (not yet), write the word into SDAM. The second core is our watchdog, which names the step on which the first one hung

Read the table like this: above us there are three (TrustZone, the hypervisor, the AOP); beside us — two with DMA into our memory (the modem via copy engines, and the display); before us — one who decides whether we run at all. All seven are someone else's code.

2a. The map of relations

The same table as a graph. This is the shared diagram of the whole series: each individual article shows its own fragment of this diagram, using the same node names.

Diagram: Whose Computer Is This? Yours, or…

How to read it: red is foreign code; green is ours; blue is memory that is contested; dashed means "can, if it wants to" (a reset, a read, DMA outside the window). Every arrow out of our block is a request, a vote, an answer or a translation; every arrow into it is power.

3. What "owning" means

Not every privilege is equal. Let us break it down by what each tenant can do to us — and what we can do to it.

Read our memoryWrite into itPower off / resetDecide whether we bootWhat we can do
TrustZoneall of itall of ityes (XPU → reset)indirectly (verifies signatures)ask (smc)
Hypervisorall of itall of ityesnoask (smc goes through him); accept his veto
AOPnonoyes (power for the whole SoC)novote by his rules
S‑Bootbefore usbefore usnoyesleave a reason byte in the PMIC
Modem via CEall of it (bypass)all of it (bypass)indirectly (reset via TZ on a refusal)noserve it while isolating transparently; lock stage‑1
Modem on its ownits regions + SMEMthe samenonovalidate everything it wrote
Displayframebuffernononodraw into the right place
PMICnonoon commandkeeps the byte for S‑Bootwrite the witness word

Note the asymmetry: the "what we can do" column contains only ask, vote, serve, validate and lock. Not a single "forbid", not a single "verify their code". That is normal for a modern SoC. What is not normal is not knowing it.

4. Three discoveries the series grew out of

4.1 The chip punishes not with an error, but with a reset

On a microcontroller an error is a HardFault with an address in a register. Here an error in front of a TrustZone fence is a reboot from the secure world, indistinguishable from a regular SYSTEM_RESET: the reason registers in the PMIC are clean, the TrustZone log is encrypted, there is no interrupt. The only way to learn on which step we died is to write a word about the step into non‑volatile memory before the step and read it back afterwards. That is how the "witness" in SDAM appeared, and how a dozen resets were turned into a table of "symptom → cause → proof → fix".

A Reset Without Witnesses

4.2 The memory map is a security boundary

One cacheable megabyte in a window we lent to the modem cost a reset: the modem read the empty headers of its file system through our cache, "restored" it, and crashed. A speculative CPU read into hypervisor memory — a reset. Metadata for TrustZone in a heap we later reused — a reset six seconds later, "while idle". Hence the invariants checked by the compiler: everything shared is non‑cacheable, everything foreign is Device, every window is on a 2 MiB boundary.

The Megabyte That Killed the Modem

4.3 The radio is not a peripheral but a tenant

The biggest discovery. On the STM32 + ESP32 breadboard, Wi‑Fi was a module behind a UART: 950 lines of driver, a wire, a text protocol. On the tablet "the same thing" took 32,000 lines, because the Wi‑Fi firmware runs on the cellular modem's processor, demands files, disk, memory and IPC from the host, and walks into our RAM by physical addresses. This concerns more than one tablet: every Android on a Snapdragon, laptops with Qualcomm Wi‑Fi under Windows, iPhones with a Qualcomm modem.

"The Parasite in the Tablet" — the central article: anatomy, threat model, Android/Windows/Apple/ESP32, what it opens up to intelligence agencies, how to check your own device.

Four narrower articles grew out of it:

5. What became OS rules

Every discovery left a rule in the code base. Not in a document — in the code, where it cannot be forgotten.

  1. Read nothing without a request. The first smc and the first SMEM read happen only when an agent asked. Boot must not hang on a question nobody asked.
  2. Every step that can hang or kill is marked. A call into the secure world, the first read of shared memory, every step of the handshake with the modem — under a mark that is read by the watchdog core or by the next boot from SDAM. The answer is "hung on scm detect" or "reset on wlfw fw_ready wait" — instead of "died".
  3. The memory map is constants with const checks. 2 MiB windows, everything shared non‑cacheable, all no‑map — Device, metadata for TrustZone — in its own window outside the heap.
  4. Everything the other side wrote is untrusted input. The FIFO base, the element offset, the length, the address in QMI, the buffer address in HTT — checked against the window before dereferencing. Parsers are safe Rust: a bug is a panic, not a write past the buffer.
  5. Transparent isolation. The modem gets an answer to everything it asks — formally correct, essentially empty: a shadow instead of the disk, scratch in RAM instead of files, named regions instead of arbitrary ones, NOT_SUPPORTED instead of silence.
  6. Vote, do not command. Rails and clocks are votes with a floor, not absolute values: our vote is one of several, and the bootloader has already left its own.
  7. An honest list of "we cannot". A threat model in which everything is closed is not a threat model. The hypervisor, the XPU, the modem firmware, the air and the cellular uplink are not ours; this is written down, not hidden.

6. What is next

7. Reading order

If you read one thing — "The Parasite in the Tablet". If you read everything — in this order:

  1. This article — the map of tenants.
  2. A Reset Without Witnesses — the method without which there would be nothing else.
  3. The Megabyte That Killed the Modem — the memory map as a boundary.
  4. "The Parasite in the Tablet" — the radio as a tenant.
  5. 23 Milliseconds to Lie — how the tenant tests the landlord.
  6. The Hypervisor Said No — who owns the SMMU.
  7. The Password Is Ours, the Key Is the Modem's — where the WPA boundary lies.
  8. Trust the Wire? — where the confidentiality boundary lies.

The technical primary sources are docs/wifi-sm8150.md (hardware, memory map, all resets with causes, methodology) and docs/wifi-threat-model.md (threat model by channel, residual capabilities, comparison with Linux).


The answer to the question in the title: the computer belongs to whoever holds the keys, owns the fences and decides what boots. On the tablet that is TrustZone, the hypervisor, the AOP and the bootloader — Qualcomm and Samsung. We are a tenant at EL1 who has learned not to step on the fences, to serve a neighbour with DMA so that it gets nothing, and to honestly write down what we cannot reach. That is less than we wanted. It is more than any OS that does not know about it has.

Part 1 of 8
  1. 1Whose Computer Is This? Yours, or…
  2. 2A Reset Without Witnesses
  3. 3The Megabyte That Killed the Modem
  4. 4The Parasite in the Tablet
  5. 523 Milliseconds to Lie
  6. 6The Hypervisor Said No
  7. 7The Password Is Ours, the Key Is the Modem's
  8. 8Trust the Wire?

Products in this article

0xd-ossecurityembeddedsnapdragon
Try it