Threat-model an Android system

Compare assets, attacker capabilities, trust boundaries, and residual risks.

11 min readChapter 43 of 50Advanced
In this chapter

Before you start#

Required: Android’s Security Model, Verified Boot and Encryption, Rooting Methods, and Magisk and Systemless Root. Optional: SELinux Policy Lab for access-policy evidence. This chapter teaches structured analysis, not exploit development, concealment, or device modification. The configurations are archetypes; they are not universal descriptions of every Android product.

Learning goals#

Define assets, adversaries, trust boundaries and assumptions; draw a request/data flow; identify the trusted computing base (TCB); compare assurance deltas across four Android configurations without declaring a universal safety ranking; distinguish source-derived statements from device observations and unknowns; and make a reasoned stop/continue decision for an owner-authorized lab.

A small threat-modeling method

A threat model is a compact account of what needs protection, from whom, through which paths, and under which assumptions. It is not a list of every imaginable attack and not proof that no vulnerability exists. Use these steps:

  1. Name assets. Examples: CE user files, account tokens, app-private data, verified OS integrity, signing/update keys, availability/recoverability, and secrets held by hardware-backed services.
  2. Name adversaries and capability. Examples: someone holding a locked lost phone; a malicious ordinary app; an app that the owner has explicitly granted root; a person with physical access and an authorized unlocked bootloader; a compromised update/root manager. Specify what they can actually do. “Attacker” without capability is not a useful model.
  3. Draw the path. Mark app/process, Binder service, kernel/DAC/SELinux, bootloader and storage-key boundaries as relevant. Show both control flow (who authorizes) and data flow (where the sensitive data moves).
  4. List assumptions and evidence. Separate claims established by pinned source, observed on an exact build, documented by a vendor, and merely assumed. Missing evidence stays unknown.
  5. Compare the delta. What trust anchor, privileged component, policy, or recovery path changed? Which controls remain? What is the residual risk for the chosen adversary?

Worked request and data-flow sketch

A service reads on your behalf
A service reads on your behalf1. App identity to System service: Binder request with caller identity. 2. System service to Kernel / storage: after authorization: open under service credentials. 3. Kernel / storage to System service (return): DAC / SELinux / key-state outcome. 4. System service to App identity (return): authorized response or error.App identitySystem serviceKernel / storageBinder request withcaller identityafter authorization:open under servicecredentialsDAC / SELinux /key-state outcomeauthorized response orerror
  1. App identitySystem service

    Binder request with caller identity

  2. System serviceKernel / storage

    after authorization: open under service credentials

  3. Kernel / storageSystem service

    Return. DAC / SELinux / key-state outcome

  4. System serviceApp identity

    Return. authorized response or error

Time runs downward. Dashed arrows show returns.

Read the text version
  1. App identity → System service: Binder request with caller identity
  2. System service → Kernel / storage: after authorization: open under service credentials
  3. Kernel / storage → System service (return): DAC / SELinux / key-state outcome
  4. System service → App identity (return): authorized response or error
Conceptual model. A hypothetical protected-setting request, not a specific service’s implementation. Boot trust is separate; storage availability may also depend on FBE key state.

Consider an ordinary app asking a system service to read a protected setting. The framework permission is granted to that app. Android assigns apps UIDs for the kernel sandbox (AOSP Application Sandbox), while framework permissions authorize selected operations (AOSP permissions). A simplified path is:

text
app process (UID + SELinux domain)
   │ Binder transaction; caller identity accompanies request
   ▼
system service (checks caller UID / Android permission / service policy)
   │ service opens backing file with its own credentials
   ▼
Linux kernel: DAC + SELinux policy + other kernel checks
   │
   ▼
storage: file availability may depend on FBE key state

Separate boot path:
device trust anchor → bootloader / AVB policy → boot images and verified partitions

A permission grant only matters where a framework/API checks it; it does not make the app UID 0. The service may be allowed to read a file the app cannot open directly. If the backing data is CE-encrypted and its key is unavailable, root UID alone does not produce that key; AOSP distinguishes CE availability after user unlock from DE availability during Direct Boot in its FBE documentation. The boot chain answers which code is accepted, not whether a particular API caller may read a file (Verified Boot). These are independent dimensions.

Four configurations: assurance deltas, not rankings

The table describes common conceptual differences. Actual policies, partitions, hardware roots, build flags, and vendor integration vary. No physical device was tested for this chapter.

ConfigurationTrust/authorization pathWhat changes or is added to TCBControls that may remainImportant residual risk / unknown
Stock, locked, production-oriented buildBootloader enforces its configured chain; framework services and kernel policy mediate runtime access.Manufacturer boot/update keys, bootloader, verified components, kernel, framework/service policy and hardware integration must be trusted.App UID separation, DAC, SELinux, framework checks, FBE, verified boot and rollback where implemented.Locked does not mean bug-free, every partition covered identically, or data safe against every physical/online adversary. Verify exact state and device documentation.
Unlocked, no root managerBootloader accepts a less-trusted/owner-authorized boot state according to implementation; OS apps may still run without a root grant.Owner-selected boot content and any modified early boot/kernel now matter; trust state changes even if no app is UID 0.Runtime app sandbox, DAC, SELinux and FBE may still operate, but their effective policy depends on booted image.“No root app” does not restore original Verified Boot assurance. Wipe/state warning behavior is device-specific.
userdebug/eng root development imageOwner builds/boots a debug configuration; adbd or another configured debug component may provide a root shell.Development signing/configuration, debug services, build flags, kernel/policy and the host/build pipeline enter the trust story.Many Android controls may remain active, including enforcing SELinux; exact settings vary.Root shell is not equivalent to stock retail root or a vendor production chain. Debug affordances can expose extra attack surface.
Modified kernel/root manager (e.g. a pinned Magisk configuration)Boot path starts modified early userspace/kernel components; daemon/manager/policy decide privileged requests.Boot image/kernel, manager, daemon, policy database or key, SELinux policy/context handling, module/update path and build provenance become security-critical.Some stock controls may remain; exact runtime domain, capabilities, namespaces, FBE and boot state must be inspected.A compromised granted app or manager can have broad access. “Systemless” and “kernel mode” do not imply invisible, safer, or universally less secure.

Do not order these as “configuration A is always safer than B.” The answer changes with asset/adversary. A debug image may be the best choice for reproducible source learning and a poor choice for sensitive personal data. An unlocked non-root image changes boot trust without granting every app root. Root may help an owner inspect a lab while making compromise of the requester/manager more consequential.

TCB inventory and evidence discipline

For each claim, tag it S (pinned source), O (observed on exact build), D (device/vendor documentation), or U (unknown). Example: “AOSP Android 14 adbd checks ro.debuggable in the root request branch” is S for the pinned AOSP revision; “this phone’s bootloader is locked” requires O/D evidence; “this manager revokes a running child immediately” is U unless exact source or a controlled test proves it.

Common TCB components to inventory:

ComponentWhy it mattersEvidence to collect
Boot ROM/bootloader and trust materialEstablishes initial trust and accepted next-stage codeDevice-specific documentation and supported read-only boot-state observations; do not infer from UI color alone
AVB metadata, rollback state, verified partitionsBind code/content to trust and freshness policyExact image metadata/source plus device-state evidence; offline parsing alone is insufficient
Kernel and SELinux policyEnforce credentials, MAC decisions and filesystem/device accessKernel/build identity, process context and policy source; vendor compiled policy may differ
Framework services and Binder checksAuthorize app requests and mediate privileged operationsService implementation and observed caller/result; API permission alone is not all kernel access
Root boot component, daemon, manager and policy storeEstablish root path and decide who may request itExact pinned release/source, grant state and manager integrity; never assume UI equals enforcement
Update/recovery path and build hostReplace trusted code and recover from errorsVendor procedure, matching build artifacts, verified backup/restore plan; hardware recovery is not tested here
FBE and hardware-backed key servicesProtect data while keys are unavailable and constrain key useAOSP/vendor documentation and exact authentication/key path; UID 0 is not key derivation

The TCB can expand or change after root modifications. A statement about stock system/sepolicy is evidence about that source tree, not automatically about a rooted vendor device. A global getenforce result says mode, not the effective domain or every rule. Inspect process context and actual policy where available, and mark missing facts unknown.

Adversarial worksheet

Complete this table for one configuration and one adversary. Keep it specific; “root is dangerous” is not an answer.

PromptYour analysis
Asset and consequence if lostWhich exact data, integrity property, key, or availability goal matters?
Adversary and capabilityWhat do they control: ordinary app, authorized root app, physical possession, unlocked boot path, manager/update channel?
Entry/request pathWhich process, Binder service, file, boot component or manager is involved?
Relevant enforcement layersUID/GID/capabilities; DAC; SELinux domain/type/policy; Android permission/service check; AVB/FBE; other?
TCB additions/changesWhich code, key, policy store, manager, kernel, or host/build artifact must now be trusted?
Evidence and unknownsFor each material claim, tag S/O/D/U and cite exact revision/build or observation.
Residual riskWhat can this adversary still do if one component is compromised? What remains protected, and why?
DecisionProceed with a read-only lab, isolate/recreate, seek vendor documentation, or stop? State a reason.

Review case and reasoned answer

Case: An owner has a disposable userdebug emulator. adb root succeeds. id reports UID 0, getenforce reports Enforcing, and id -Z reports a process context. The owner concludes that SELinux is unchanged, the OS has production assurance, and any denied read must be a DAC problem.

Reasoned answer: Only the first two observations are established (assuming the commands targeted the intended emulator): this shell has UID 0, and the global SELinux mode reports enforcing. The context gives another distinct process property. None proves the loaded policy is byte-for-byte stock, that this root domain has narrow permissions, or that build/boot assurance matches a retail production device. A refusal could be DAC, SELinux, a framework/service check, or another kernel condition; an AVC can support SELinux attribution, but absent logs do not clear SELinux. Record build fingerprint/type and inspect exact policy/context; do not disable SELinux. For sensitive-data threat modeling, the debug build and host pipeline are additional trust assumptions. This case has no universal risk ranking; the conclusion depends on assets and adversary.

Practice#

Pick one asset and one adversary from the table. Fill the worksheet for (a) stock locked, (b) unlocked but no root manager, (c) development root image, and (d) modified kernel/root manager. Write one sentence per configuration stating assurance gained/lost for that specific threat. Use citations for source claims and unknown for unobserved vendor facts. No device change is part of the exercise.

Knowledge check#

  1. Does bootloader unlock imply UID 0 for apps?
  2. Does getenforce=Enforcing prove an effective stock policy for a modified root build?
  3. Why can an unlocked non-root device have lower boot assurance than a locked stock device?
  4. Name three root-configuration TCB elements beyond the requesting app.
  5. What is the right response when the device-specific recovery/rollback state is unknown before a proposed hardware change?

Answers#

  1. No. Unlock changes boot acceptance policy; root is runtime privilege/authorization.
  2. No. It reports global mode, not effective policy provenance, domain, capabilities or every permission.
  3. The bootloader may accept software outside the manufacturer’s normal verified chain even though no app has root.
  4. Examples: modified boot component/kernel, daemon, manager, policy store/key, SELinux policy, update/recovery tooling.
  5. Stop before irreversible modification; obtain exact vendor instructions and a verified recovery plan. This chapter does not authorize a generic flash/relock procedure.

Checkpoint#

Submit four configuration rows, one adversary-specific data-flow diagram, a TCB inventory with S/O/D/U evidence tags, and a decision with residual risk. Ready if the comparison is conditional on assets/adversary and unknowns remain explicit; revise if “locked/rooted/green” is used as a complete verdict; not yet evidenced if device state is asserted without observation or exact documentation. Remediation: redo the worksheet using one narrower adversary and cite the evidence for each gate.

Sources#


Next: OTA updates and rollback analysis

A little further beneath the surface.

Check your understanding with the checkpoint. Marking a chapter as read saves a bookmark, not a proficiency assessment.