LWN.net Logo

ABS: Android security underpinnings

By Jake Edge
February 28, 2013

In a two-hour session at the 2013 Android Builders Summit, Marko Gargenta described the "underpinnings" of Android security. It was a wide-ranging talk that filled in many details of the Android security model and its implementation. There are multiple layers in the Android stack, Gargenta said, showing a slide [JavaScript] of the Android architecture. He broke the stack up into four layers: kernel, native code, API, and apps. Each of those has its own security concerns, he said.

Apps

In the Android security architecture, apps cannot directly interact with each other, nor with any of the other processes on the system. Those other processes come about as the Android system is initialized. After the kernel boots, init launches a few daemons needed by the rest of the system (vold, netd, installd), then starts the servicemanager. In turn, the servicemanager launches zygote, which is the "initial app" and the root of the app tree. All of those processes run as the root user, but anything started after that (including the system_server and any apps) run under its own user ID (UID).

Each app runs in its own process, and by default is not allowed do anything to adversely affect any other app, the system, or the user. That separation is enforced by the kernel's normal user permissions. On top of that, Android adds a fine-grained permission system that allows users to grant specific privileges to apps, but the apps must declare the privileges they want ahead of time.

Apps can explicitly share resources and data with other apps via the binder inter-process communication (IPC) mechanism, ContentProviders, Intents, the filesystem, local sockets, and so on. That sharing is outside of the scope of the Android security model. All apps are treated equally by the system, with the same level of application sandboxing.

The sole enforcement mechanism for the application sandbox is the Linux kernel. The Dalvik virtual machine (VM) does not provide a security boundary (unlike the Java VM). Each app has its own Dalvik VM as well as all the Android resources (activities, services, receivers, providers, etc.) in its process space.

Apps are stored in a .apk files, which must be signed. The signature is meant to uniquely identify the owner of the app, but that doesn't necessarily translate to a real life entity. It is, instead, used to create a trust relationship between apps. The signature is also used to verify that the contents of .apk file have been correctly signed with the owner's key and have not been corrupted.

App signing uses public-key cryptography as defined by the Java JAR specification. Most developers will already have a key that was created by Eclipse and lives in .android/debug.keystore. The keytool utility should be used to create a more permanent keystore. No third party certificate authority (CA) is needed for signing the keys as they can be self-signed. Google Play store policy for apps requires a key that is valid until at least October 2033, but keys should be valid for 25 years or more, Gargenta said.

Once an app is signed, it is "zipped" into a archive file, which is essentially what an .apk is. Each file in the zip archive is individually signed, and those signatures are stored in a file in the META-INF directory. The .apk contains the classes, resources, and the manifest, along with META-INF. One can use jarsigner to sign the files, and keytool to verify keys and signatures.

The platform itself has four different keys, which are often overlooked by people creating their own ROM. There is a "platform" key used to sign the core frameworks, a "shared" key for ContentProviders, a "media" key for the media frameworks and applications (e.g. Gallery, DrmProvider), and a "testkey" for everything else. Those can be created using keytool. Shipping a ROM with the default keys is a big mistake, Gargenta said, because anyone can create an update.zip firmware update file to replace any part of the system they want.

Users

Android doesn't use Linux users (and UIDs) in the usual way. There are "virtual users" that correspond to each app. When installed, an app gets a UID (and identical group ID) assigned to it. Up until Ice Cream Sandwich (ICS, Android 4.0), the UIDs were assigned starting at 10,001 and given names like app_N, where N is the offset from 10,000. After ICS, the mapping took multiple human users into account, so the names became uM_aN, where M corresponds to the human user, and uses a different formula (100,000 * user + appnum, so u10_a3 becomes 101,003 1,010,003).

There is no passwd file on an Android system, but the mapping from app to UID can be found in the /system/packages.list file. That file lists the app name, UID, and the location of the app's private data storage in the filesystem. When an app is first downloaded, it is put into a quarantine space and examined by installd; if the signature check passes, a UID/GID is assigned and the app is installed. It is possible to have multiple apps (all signed with the same key) running under the same UID, but they are really considered by the system to be part of the same app.

Files

Android has a few separate filesystems. The /system filesystem is "essentially the ROM", Gargenta said. It is mounted read-only and contains the Android OS, system libraries and apps, system executables, and so on. The application developer and user have no access to that filesystem (unless the device is rooted), and it contains no user data, so it doesn't need to be backed up or encrypted.

The /data partition is mounted read-write and contains all of the downloaded apps and the storage for all apps (including the system apps). The /data/data directory is the location where apps store their data. A a subdirectory named after the app is created that is owned by its UID/GID and has permissions that does not allow access from other UIDs. This is how the storage sandbox is handled. There is a lib directory in the app's storage, which holds the native libraries that the app needs. That directory is added to the LD_LIBRARY_PATH of apps before they are started.

The init process mounts the filesystems and sets the permissions for the files in those filesystems, which can be seen in the init.rc file. It ensures that /system is mounted read-only as it may have previously been mounted read-write for an over-the-air (OTA) update.

In Android 4.2 ("Jelly Bean"), support for multiple human users was added for uses like tablets that are shared by multiple family members. The number of supported users is set in a configuration file; for phones the value is 1, but tablets it is often set to 8. When there are multiple users, apps can be installed for one or more of them. In that case, the data is not shared—instead, each user gets their own copy of the app's data directory, but the code and libraries are shared (the latter using a symbolic link from the lib directory).

Permissions

Permissions are at the heart of the app security model for Android. One can see the list of all permissions in the system using the "pm list permissions" command in the adb shell. Also, the "run-as" command can be used to test permissions as granted to specific apps. That is useful for debugging and testing, Gargenta said.

Some permissions are better than others, at least in terms of being featured in the Google Play store, he said. He listed the Top Ten Bad Permissions. These are permissions that, if requested by an app, make it less likely to be featured in the store. For the most part, these are somewhat dangerous permissions that are a red flag that the application is asking for more than it needs—or more than it should need.

For example, the SEND_SMS and RECEIVE_SMS permissions (for sending and receiving text messages) were at the top of the list. Unless the app is an SMS program, it shouldn't be using those. Instead, it should start an SMS composer activity, which will activate an existing SMS app to handle the message. Similarly, using an intent for ACTION_IMAGE_CAPTURE will bring up the camera to allow the user to take a picture and return the result. That avoids requiring the CAMERA permission. He had suggestions for several other permissions as well.

Permissions in Android map to groups (i.e. GIDs). If a particular app is granted a permission, it is added to the group. For example, Android's "paranoid networking" works by checking if the user is in the "inet" group; if so, it allows network access, otherwise not. The permissions for files and devices are set by the init process

Gargenta also briefly looked at some other Android security topics, including encryption, malware, and device administration for companies that are issuing phones to their employees (or allowing those employees to use their own). Those topics were something of an aside to the deep dive into Android security. Overall, there was a lot to digest in a fairly short period of time, as Gargenta's slides would suggest. A longer time slot might have been harder to allocate for a two-day conference like ABS, but there was certainly material enough to fill it.

[ Thanks to the Linux Foundation for assisting with travel costs to San Francisco for ABS. ]


(Log in to post comments)

ABS: Android security underpinnings

Posted Feb 28, 2013 9:24 UTC (Thu) by ekj (guest, #1524) [Link]

Thanks ! This article is informative, concrete and well-written. More articles like this please.

ABS: Android security underpinnings

Posted Feb 28, 2013 18:29 UTC (Thu) by dkrawchuk (subscriber, #21896) [Link]

Regarding the new UID mapping applying the formula 100,000 * user + appnum to u10_a3 would be 100,000 * 10 + 3 which equals 1,000,003 not 101,003. Or am I missing something.

ABS: Android security underpinnings

Posted Feb 28, 2013 18:58 UTC (Thu) by jake (editor, #205) [Link]

> Or am I missing something.

I had 1,010,003 in my notes and (briefly) in the article before changing it, but I clearly messed it all up. In rereading, its not completely clear that 'appnum' corresponds to the 10,000 + N earlier in that paragraph, but it does.

So it should be M*100,000 + 10,000+N = 1,010,003 for u10_a3.

My apologies for not being clearer (and for being wrong, of course :)

thanks for spotting it ...

jake

ABS: Android security underpinnings

Posted Feb 28, 2013 19:12 UTC (Thu) by leoc (subscriber, #39773) [Link]

I've always been curious what rooting an android phone does to this security model. Am I just being overly paranoid in avoiding doing it for the added functionality?

ABS: Android security underpinnings

Posted Mar 1, 2013 2:49 UTC (Fri) by dmag (subscriber, #17775) [Link]

I'm no expert, but I don't think you should worry.

Upon rooting, you install an app called Super User. Any app can ask for SU permissions via an intent, and SU asks you if it's OK.

And I think my phone is much more secure now that it's free of CarrierIQ, and the preinstalled bloatware.

CyanogenMod has been rock solid.

Worrying about root

Posted Mar 6, 2013 13:16 UTC (Wed) by alex (subscriber, #1355) [Link]

You may have to worry. When you give root access to an app you really want to trust it won't abuse it. While "good" root apps are meant to only grab root privileges for the minimum amount of work possible it's not enforced. Every app running with root privileges presents another potential attack vector onto your device which could be exploited.

Personally though I'm not overly paranoid, although I only tend to grant root access to apps install via F-Droid (and hence source code available FLOSS). Of course the availability of the source code doesn't guarantee anyone has actually audited it for badness.

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds