Android from the foundation · Puzzle 1 of 6

An app is a Linux process with its own user

Each app gets its own Linux user ID and its own process. The kernel keeps them apart, so one app can't open another's files or read its memory.

The problem

In puzzle 0, your app was a house. But a phone has dozens of houses from different companies, and a banking app must be safe from a game that wants to read its files or its memory. How do you keep them apart without trusting either of them?

See it

Two app houses with different keys (UIDs); the game's key doesn't fit the bank's door, so the kernel refuses; the official way is a letter through the town hall UID 10101Bank app UID 10202Game kernel: checks the key town hall
  1. Android installs each app as its own Linux user, with its own UID (user ID): its own key. Each app runs in its own process, a house with its own memory.

    Step 1 of 4
  2. The game tries to open the bank's file with its own key. It doesn't fit: the kernel checks the UID on every file and every process, and refuses. Predict: so how can apps share anything?

    Step 2 of 4
  3. Through official doors. The game writes a letter (an Intent) to the town hall, system_server, which checks it…

    Step 3 of 4
  4. …and delivers it to the bank if it's allowed. Apps never walk into each other's houses; the system carries what they share.

    Step 4 of 4

The building block

Android is built on Linux, and Linux already knows how to keep users apart. So Android turns each app into its own user: at install time the app gets a unique user ID (UID), and it runs in its own process.

  • Files the app creates belong to its UID; other apps can't open them.
  • A process can't read another process's memory.
  • The kernel enforces both, so a buggy or hostile app can't switch them off.

You'll see the same UID written two ways: 10101 is the number, u0_a101 is its name in tools like ps. The kernel guards files and memory; in puzzle 5 you'll see how system_server guards everything else, using the same UID.

The analogy

Every app is a house with its own key. The kernel is the lock on every door: it only opens for the right key. Neighbours who want something send a letter through the town hall.

Check yourself

A game wants to read the bank app's database file directly. Does it work?

Not quite. Same phone, different users. Linux keeps users apart even on one machine.

Not quite. Permissions don't let one app into another app's private files. The key (UID) has to match the door, and it never does.

Right. Each app is a separate Linux user, and the kernel checks the UID on every file. Apps share only through official doors like Intents.

Who enforces the sandbox?

Right. The kernel enforces it, which is why a buggy or hostile app can't switch it off.

Not quite. The town hall carries letters between apps (step 4), but the walls around files and memory are the kernel's job.

Not quite. If apps had to behave, a hostile app simply wouldn't. The walls hold because the kernel checks every access, whatever the app does.

How should a game get data from the bank app?

Not quite. Running at the same time doesn't open the walls: each app's memory belongs to its own process.

Right. Apps never reach into each other. They send letters, and the system decides whether to deliver them.

Sources

What you now know

Your app is a house with its own key (a UID) and its own walls (a process). The kernel checks the key on every file. To get anything from another app, you send a letter through the town hall.