Skip to content
Kees Jongenburger edited this page Jun 12, 2014 · 9 revisions

Android Security

Upfront

Android now has more documentation about security see The android tech info pages about security

Enforcement at the unix level

Security in Android is enforced in different ways. Android use the standard
process isolation to split application it therefore performs fork/exec when
starting application. At the Unix level application are also (by default) run
as different Unix users. This isolates application and protects applications
from reading each-others data. By requesting permissions in the apk’s
AndroidManifest it is possible to get those granted by the PackageManager. Such
permissions can result in applications being run under the same user id as a
ohter package or run with additional unix groups. Some group will give the
application access to devices nodes or other files. Other Unix groups are
mapped to Linux process capabilities being granted.

More information can be found in the security section on the Android website and in the manifest documentation

Enforcement at the binder level

The second way security can be enforced is at the Binder level. As packages by
default are run as separate user and process when they need to communicate the
need to use some form of Inter process communication. In Android the preferred
communication mechanism is binder. When processes communicate with each-other
using binder Android will allow the service side code code to check if package
manager was granted certain permissions by calling
checkCallingOrSelfPermission() of the context class. The implementation of this
is done in the (native) service manager class. This class uses the service
called “permission” that is implemented by the ActivityManagerService.java in
the checkComponentPermission(permission, pid, uid, reqUid) method and follow
the following logic

-The root and system user will always be granted all permissions
-If the permissions == NULL the permission will be granted
-In the other situation a request is sent to the package manager to check the permission based on the user id of the package.

Permission definitions

Permissions are declared in frameworks/base/core/res/AndroidManifest.xml but
can also be declared in other manifest files. Defining rules like starting
processes with extra groups or capabilities is done in
frameworks/base/data/etc/platform.xml or /etc/permissions/*.xml on the target.
The platform.xml will be read last so the security definitions there are
leading.

frameworks/base/services/java/com/android/server/PackageManagerService.java reads etc/permissions/platform.xml and
all other xml files in that directory at runtime.

The following diagram shows the permission scheme.

Permission schemePermission scheme

  • A permission definition is declared in a manifest file. The manifest frameworks/base/core/res/AndroidManifest.xml)
    contains many if not all of the platform permissions.
  • A permission defines it’s own security level(more on that later).
  • A permission belongs to a package and it has it’s certificate associated to it.
  • A permission belongs to a group of permissions (this is mostly used by the UI to tag permissions).

There are different Permission levels(read frameworks/base/core/res/res/values/attrs_manifest.xml)

  • Level 0 protection normal (A lower-risk permission that gives an application access to isolated application-level
    features)
  • Level 1 protection dangerous (A higher-risk permission that would give a requesting application access to private
    user data or control over the device that can negatively impact the user)
  • Level 2 protection signature (A permission that the system is to grant only if the requesting application is signed
    with the same certificate as the application that declared the permission.)
  • Level 3 protection signature or system (A permission that the system is to grant only to packages in the Android
    system image or that are signed with the same certificates. )

**NOTE: “system” application are application that where originally installed on the device. It is possible to update
system application during the life cycle of the application. they are then installed under /data/app and will keep

User ID and permissions assignment

/data/system/packages.list contains the list of installed packages.
/data/system/packages.xml contains the list of permissions per package their issuer and many more

These files are created by com.android.server.PackageManagerService.Settings.writeLP().
The first contains 4 fields: the package name , the user id for the package , a flag (1 means debugable) and the data
dir of the packages.

The second file , packages.xml is more complex. it describes known permissions, packages and their signatures

Given these files are written and read there is probably an attac possible by
modifying the package files “offline” An other problem that exist is the usage
of the dalvik cache dex optimized files are written to the cache directory this
is also true for system jar files(unless the packages are already dexopt during
the build).

Shared-User ID and permissions assignment

How do things work when a shared user id is used.

on http://developer.android.com/guide/topics/security/security.html it is stated that

Purposes of security the two packages are then treated as being the same application, with the same user ID and file
permissions. Note that in order to retain security, only two applications signed with the same signature
(and requesting the same sharedUserId) will be given the same user ID.

Now imagine two packages with different permissions using the same user-id.
As we know that the permissions are granted on user level we expect that booth packages will have the union of
permissions, This is indeed the case see https://groups.google.com/d/topic/android-platform/-wDFTpxgKU4/discussion

Signing using the platform keys

By default build/target/product/security will contain a set of pre-generated certificates that are used for signing
packages in the platform. Prior to releasing a device these keys must be replaced as having access to these keys gives
people access to the whole platform.

The normal platform way

The normal way to sign a package using the platform key is to tel the Android build system about this in the Android.mk

LOCAL_CERTIFICATE := platform

If you are using eclipse and such you can use the following script to sing a package with the platform key. As you will
notice the platform key is not generated during the build so in real product some other keys need to be generated read
build/target/product/security/README to get more information.

When not in the platform. The clean way

When not building in platform-android it gets harder to sign using the platform key. You can use the following code to
sign a package by hand( there are also well documented methods for doing this in ant scripts)

#!/bin/sh
#MY_SDK_HOME=~/projects/android/
MY_SDK_HOME=~/build/W20_FairPhone

#
PEM=${MY_SDK_HOME}/build/target/product/security/platform.x509.pem
PK8=${MY_SDK_HOME}/build/target/product/security/platform.pk8
OPT=""

while getopts w opt
do
	case $opt in
		w)
			#needed when creating OTA packages
			#this includes a copy  of the cerfiticate in 
			#META-INF/com/android/otacert "for easy access"...
			echo signing whole archieve
			OPT="-w"
			shift #remove arguments from the command line
		;;
		*)
			echo invalid option $opt
		;;
	esac
done

if [ $# -ne 2 ]
then
    echo Usage $0 [-w] in.apk out.apk
    exit 1
fi
java -jar ${MY_SDK_HOME}/out/host/linux-x86/framework/signapk.jar $OPT  \
    ${PEM} ${PK8} $1 $2

When using an IDE

When using an IDE it usually is possible to export a signed APK. But booth intelij and eclipse by default IDE when doing
development and testing use a different key. That the key used is generated in the .android/debug.keystore with an
alias or androiddebugkey. The following method is “hackish” but allows us to develop in an IDE while gaining platfom
level permissions.

First import the platform key into your .android debug keystore overriding the key with alias androidebugkey. This can
be done by using the keytool-import-keypair. https://github.com/getfatday/keytool-importkeypair/tree/

keytool-importkeypair -k ~/.android/debug.keystore -p android -pk8 platform.pk8 -cert platform.×509.pem -alias androidebugkey

kejo@kejo-fakedistro:~/platform/android/main/mydroid/build/target/product/security$ keytool-importkeypair -k ~/.android/debug.keystore -p android -pk8 platform.pk8 -cert platform.x509.pem -alias androiddebugkey
Importing "androiddebugkey" with SHA1 Fingerprint=27:19:6E:38:6B:87:5E:76:AD:F7:00:E7:EA:84:E4:C6:EE:E3:3D:FA
Existing entry alias androiddebugkey exists, overwrite? [no]:  yes
Entry for alias androiddebugkey successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

Now verify that the package you create in the ide are signed using the platfom key

Before:

jarsigner -verify -certs -verbose out/production/PlatformHacking/PlatformHacking.apk
sm       704 Tue May 10 17:22:08 CEST 2011 res/layout/main.xml

      X.509, CN=Android Debug, O=Android, C=US
      [certificate is valid from 2/24/11 2:23 PM to 2/24/12 2:23 PM]

After:

jarsigner -verify  -certs -verbose out/production/PlatformHacking/PlatformHacking.apk

sm       704 Tue May 10 17:42:12 CEST 2011 res/layout/main.xml

      X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
      [certificate is valid from 4/16/08 12:40 AM to 9/2/35 12:40 AM]