Understanding Android Sandbox and Linux Permission Mechanisms
This article explains how Android inherits Linux's UID/GID based permission model, details the sandbox isolation for apps, describes how system and app processes obtain their UID/GID, and shows how adb shell and framework permissions grant extensive access to the device.
When discussing sandboxes, most people know that each app receives a unique UID and cannot freely access other apps' data; this article dives deeper into the Android sandbox mechanism built on Linux's permission model.
Linux permission mechanisms involve users (uid, gid, groups), processes inheriting these IDs from their owners, and file system entries with UID, GID, and rwx permissions.
In Android, the adb shell command runs as the "shell" UID (2000), and any child process inherits this UID/GID, which can be verified with the id command or by inspecting /proc/xxx/status .
File system objects also have UID/GID defined at creation, with definitions found in fs_config.c for directories and files, and in ueventd.*.rc for device nodes. Images illustrate these definitions.
System processes such as servicemanager , vold , and surfaceflinger obtain their UID/GID from corresponding .rc files (e.g., surfaceflinger.rc ).
Each installed app is assigned a UID (e.g., AID_ROOT 0 , AID_SYSTEM 1000 , AID_SHELL 2000 , and apps receive IDs above 10000). The app's data directory is owned by a UID like u0_a504 , ensuring exclusive access.
Permissions are mapped to groups via platform.xml ; when an app requests a permission, its process gains the associated GID, allowing access to files with matching GID (e.g., sdcard_rw for android.permission.WRITE_MEDIA_STORAGE ).
Android permissions are divided into two control layers: low‑level Linux file permissions (e.g., WRITE_MEDIA_STORAGE ) and higher‑level framework checks performed by AMS, PMS, and WMS, which consult cached permission data.
The adb shell process hierarchy is init → adbd → /system/bin/sh → xxx . Although init runs as root, adbd deliberately drops to the "shell" UID, granting it many permissions declared in the shell package.
Example command: adb shell pm grant package_name permission_name works because the shell UID holds the hidden android.permission.GRANT_RUNTIME_PERMISSIONS , which normal apps lack.
Attempting to grant permissions from within an app using Runtime.getRuntime().exec("pm grant package_name permission_name") will fail, as the app does not have the required UID.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.