Famous bugs and incidents
Stagefright, Janus, the VINTF boot failure, the Oracle lawsuit. Five incidents that changed Android's architecture, told as engineering stories: what broke, why the design allowed it, and what was rebuilt afterwards.
The most useful incidents in a platform's history are the ones where the architecture, not just the code, was wrong. Five Android episodes fit that description. In each one, the fix was not a patch but a structural change, and the structure is still visible today.
TL;DR#
- Stagefright (2015) was a media-codec vulnerability class. The response changed Android's security posture: monthly bulletins, and media services split into separately sandboxed processes.
- Janus (2017) exploited the gap between what the v1 APK signature verified and what the runtime loaded. It is the argument for whole-file signature schemes.
- VINTF mismatches cause devices to refuse to boot after an update, by design: the vendor interface is checked rather than assumed.
- The Oracle lawsuit was about API copyright and ended in a fair-use ruling in 2021 without settling whether APIs are copyrightable.
- SELinux enforcement rolled out permissively and then strictly, and the phased model became the template for how Android introduces hard security changes.
Mental model#
Think of a bridge that develops a crack.
The first response is to patch the crack. The second is to inspect every bridge of the same design. The third — the one that matters — is to change the design so that a crack in one member does not propagate to the whole span.
Android's major incidents followed that arc. Stagefright was a crack in the media code; the fix was to put the media code in its own span. Janus was a crack in signature verification; the fix was to change what a signature covers. VINTF was a crack in the update contract; the fix was to check the contract at boot rather than trust it.
Where the analogy breaks#
A bridge's design change is invisible to its users. Android's structural fixes change what apps and device makers must do: new signature schemes mean re-signing, and vendor interface checks mean a device can refuse to boot rather than degrade. The cost of the fix is paid by the ecosystem, not just by the platform team.
The big picture#
Text description of this diagram
A timeline of the platform's era changes, with the architecture lane marking the structural responses: Project Butter in 2012, ART in 2014, Treble in 2017 and adaptive-first in 2026, and the update lane marking Treble, Mainline and GKI. Read against the incidents described on this page, the timeline shows that several of the platform's biggest reorganisations followed a security or compatibility failure rather than a product plan.
Deep dive#
Stagefright and the media split#
In 2015, a class of vulnerabilities in Android's media framework became public. The details mattered less than the shape: a specially crafted media file could compromise a device during processing, often with no user interaction. The code that parsed untrusted media ran in a process with broad access, so a codec bug could reach much of the system.
The response changed Android in two ways.
Monthly security bulletins became normal. Before Stagefright, Android security updates were irregular and device-specific. After it, a monthly cadence with a published bulletin became the expectation, and the security patch level became a property you could check on a device.
Media services were split into separately sandboxed processes. In Android 7.0, the monolithic media server was broken up so that a codec bug could not reach the whole system. The architectural principle is general: put parsers of untrusted input behind a process boundary, so a memory-safety bug in the parser is contained.1
Janus and the signature gap#
Janus, disclosed in 2017, was a flaw in APK signature verification. An attacker could craft an APK that the v1 signature scheme would verify while the runtime executed different code. The mechanism exploited the difference between what the verifier hashed and what the installer actually loaded.
The v1 scheme signed individual entries inside the ZIP archive. That left parts of the archive unprotected: the structure of the ZIP itself, and the relationship between entries, were not covered by the signature. If the verifier checked one view of the file and the runtime used another, the two views could disagree.
The fix was APK Signature Scheme v2, which signs the entire file rather than individual entries. Any byte change invalidates the signature. Later schemes extended the idea: v3 adds key rotation, and v4 supports incremental installation.2
The lesson is about what a signature should cover. "Sign the parts you care about" is fragile, because the attacker chooses which parts matter. "Sign the whole file" is simpler and harder to subvert, at the cost of making the signature format depend on the file layout.
VINTF: refusing to boot#
After Treble, the relation between the system image and the vendor image became a contract: a vendor manifest declares what the vendor provides, and a compatibility matrix declares what the framework requires. At boot, the device checks that the two match.3
A mismatch is a hard failure: the device refuses to boot rather than starting with a missing or incompatible HAL. That is deliberate. A phone that boots into a half-working state — no camera, no radio, no audio — is worse for users and much harder to diagnose than a device that fails cleanly and can be rolled back.
The cost is real: a misconfigured update can brick a device. The benefit is that the failure is deterministic and discoverable rather than a runtime mystery. This is the same trade as a compiler error versus a runtime crash.
The Oracle lawsuit#
In 2010, Oracle sued Google over Android's use of Java. The dispute ran for a decade and reached the US Supreme Court, which in 2021 ruled that Google's use of Java API declarations in Android was fair use.4
The ruling ended the litigation but did not settle the underlying question of whether APIs are copyrightable. That distinction matters: the case is often summarised as "APIs are not copyrightable", which is not what was decided.
The engineering consequence is less discussed. Android's Java compatibility layer, and the subsequent move toward Kotlin as the preferred language, both sit in the shadow of that dispute. A platform that depends on another company's language and libraries has a legal exposure that a platform with its own language does not.
SELinux: the phased rollout#
SELinux enforcement did not arrive all at once. It started behind the scenes in Android 4.2 and 4.3 in permissive mode — logging violations without blocking them — and became mandatory in Android 5.0. Enforcement then expanded domain by domain.5
The phased model is the interesting part. A permissive first phase lets the platform team see what would break without breaking it, and lets device makers and app developers fix violations before they become failures. The same pattern later appeared in other hard changes: introduce, observe, then enforce.
What the incidents have in common#
Four properties recur:
- The failure was in a boundary, not a function. Media parsing crossed from untrusted input into privileged code; signature verification crossed from file bytes to runtime; the vendor interface crossed from one image to another.
- The fix moved or formalised the boundary. A separate process, a whole-file signature, a checked contract.
- The cost was paid by the ecosystem. Re-signing, re-certifying, re-testing.
- The fix is still visible. Each one is now a normal part of the platform that nobody discusses.
That last property is the test of a good post-mortem. If the fix is invisible a decade later because it became the default, it worked.
How it evolved#
| API | Version | What changed |
|---|---|---|
| 23 | 6.0 Marshmallow |
|
| 28 | 9 Pie |
|
| 30 | 11 |
|
| 31 | 12 |
|
| 33 | 13 Tiramisu |
|
| 37 | 17 Cinnamon Bun |
|
The security rows trace the post-Stagefright posture: signature schemes, sandboxing, permission narrowing. The incidents are the reason the rows exist.
Under the hood#
- the media framework that the 2015 split reorganised
- PackageParser.javaAPK parsing and the validation path around signatures
- the policy sources whose phased enforcement is described above
Curiosity corner#
- Janus is named after the two-faced Roman god. The bug is a file that shows one face to the verifier and another to the runtime.
- A device that refuses to boot may be working correctly. The VINTF check is a feature; a mismatch means the update contract was violated.
- The Oracle case did not decide that APIs are uncopyrightable. It decided fair use, which is a narrower and more fact-specific holding.
Try it#
adb shell getenforce
adb shell getprop ro.build.version.security_patch
adb shell dumpsys package com.android.settings | grep -i signatureExample output
Illustrative output — values differ per device.Build it#
B04 — Permissions playground makes the permission boundary concrete; the sandbox and SELinux material behind these incidents is in the security module.
Check yourself#
Check yourself
Android is a conventional GNU/Linux distribution with a different desktop environment.
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- docsMedia framework overviewsource.android.comaccessed 2026-10-27↩
- docsAPK Signature Scheme v2source.android.comaccessed 2026-10-27↩
- docsVendor interface objects (VINTF)source.android.comaccessed 2026-10-27↩
- specGoogle LLC v. Oracle America, Inc., 593 U.S. (2021)Supreme Court of the United Statesaccessed 2026-10-27↩
- docsSELinuxsource.android.comaccessed 2026-10-27↩
- docsAPK signature schemesource.android.comaccessed 2026-10-27↩
- docsVerified bootsource.android.comaccessed 2026-10-27↩
- wikiAndroid (operating system)Wikipediaaccessed 2026-10-27↩