2.2 Tutorial on Android Security
3.1.1 Threat Model
Most security evaluations focus their scope by defining a threat model. In fact, as stated earlier, Google recommends sharing multi-user devices only with trustworthy people. Unfortunately, varying definitions of trust, different expectations for security and privacy, and a wide variety of use cases make this a very ambiguous statement. Because of this, and since the methodology is intentionally generic with respect to the types of Android access controls being evaluated, we do not immediately identify a specific threat or scenario. Instead, insights and knowledge are produced first, through a systematic, exhaustive analysis, independent of any particular threat mindset. The hypotheses which can then be generated factor in the specific threat scenarios.
The rest of the chapter is organized as follows: a background on how multi-user has been implemented in Android is first provided in Section3.2so that later descriptions of the
methodology can include the multi-user case study context for clarity and as an example. Next, Section3.3describes the systematic methodology for gaining insights into relevant access controls and hypothesizing about potential vulnerabilities. A sampling of the most interesting hypotheses are given in Section3.3.3. Finally, Section3.4presents the findings from experiments designed to test the hypotheses. Related work is consolidated in Chapter6.
2A high confidence anonymous reviewer of [34], the peer-reviewed publication describing this work, stated that the
3.2
Background
Before describing our investigation, a brief technical overview of Android’s implementation of multiple users is needed. The following section expands on the general background material of Chapter2, and is divided into four subsections: Android framework extensions, filesystem configuration, kernel mechanisms, and run-time considerations. Each subsection may contain a brief security discussion in order to emphasize aspects that are important for later discussions. Throughout the chapter, the Linux user ID and group ID are referred to as uid and gid, respectively, while IDs within the Android framework are denoted by userId, and appId.
3.2.1
Framework - userId
Version 4.2 added android.os.UserHandle class to represent multiple users on the device. This class designates userId 0 as the device owner, and several special userIds to represent all users (userId -1), the current user (userId -2), the current user or self (userId -3) and the null user (userId -10000). Actual userIds are assigned by the UserManagerService class (also introduced in 4.2) when
new users or new restricted profiles are created by the device owner. This class defines the starting userId as 10, and increments it by 1 every time a new user or profile is created, until the number of current users equals the maximum number defined by the system property
fw.max_users from build.prop. State is maintained in /data/system/users/userlist.xml, where a list of currently-assigned users and the next available userId is stored. On devices where users or profiles have been repeatedly added and deleted, the userIds may be re-used, although the next available counter continues to increment as shown by the example of Listing3.3. userIds are assigned in the same way regardless if they are for a secondary user or a restricted profile.
For example, Listing3.1shows a representative userlist.xml file from a fresh device with one secondary user and one restricted profile added. After deleting these two accounts and adding a third secondary user, the file appears as shown in Listing3.2.
Listing 3.1: userlist.xml showing users 0 (owner), 10, 11, and next available userId 12. 1 < ? xml v e r s i o n = ’ 1.0 ’ e n c o d i n g = ’ utf -8 ’ s t a n d a l o n e = ’ yes ’ ? > 2 < u s e r s n e x t S e r i a l N u m b e r = " 12 " v e r s i o n = " 4 " > 3 < u s e r id = " 0 " / > 4 < u s e r id = " 10 " / > 5 < u s e r id = " 11 " / > 6 < / u s e r s >
Listing 3.2: userlist.xml after deleting users 10, 11, and adding a user, showing users 0, 12 and next available userId 13. 1 < ? xml v e r s i o n = ’ 1.0 ’ e n c o d i n g = ’ utf -8 ’ s t a n d a l o n e = ’ yes ’ ? > 2 < u s e r s n e x t S e r i a l N u m b e r = " 13 " v e r s i o n = " 4 " > 3 < u s e r id = " 0 " / > 4 < u s e r id = " 12 " / > 5 < / u s e r s >
Listing 3.3: userlist.xml after deleting users 10, 11, and adding a user, showing users 0, 12 and next available userId 13. 1 < ? xml v e r s i o n = ’ 1.0 ’ e n c o d i n g = ’ utf -8 ’ s t a n d a l o n e = ’ yes ’ ? > 2 < u s e r s n e x t S e r i a l N u m b e r = " 27 " v e r s i o n = " 4 " > 3 < u s e r id = " 0 " / > 4 < u s e r id = " 11 " / > 5 < / u s e r s >
As has always been the case in Android, each installed application is assigned an appId.3 android.os.Process class defines ranges of appIds that can be assigned to different types of apps. Normally, these IDs range from 10000 to 99999.
In the past, appIds were the same as the Linux uid, thus enabling process, memory and filesystem isolation among the different apps installed on a device. With the advent of the multi-user
framework, the most significant bits of the Linux uid take on the semantics corresponding to userId, while the remaining bits continue to correspond to appId. Specifically, the Linux uid is obtained by concatenating the userId and appId as follows:
3Before the introduction of multi-user, uid and userId were used interchangeably to refer to the unique identifier for
each app installed on the system. In versions with multi-user extensions, userId is used to denote the actual user, while appId is the designation for each app’s unique ID. However, there are still several instances of code and files that use userId to refer to apps. For example, the sharedUserId tag in AndroidManifest.xml actually refers to package names which will share the same appId.
uid = userId × PER_USER_RANGE + (appId mod PER_USER_RANGE ) , (3.1)
where the default PER_USER_RANGE is 100000.
Likewise, userId and appId can be recovered from uid using
userId = uid div PER_USER_RANGE (3.2)
and
appId = uid mod PER_USER_RANGE , (3.3)
where div denotes integer division and mod the modulo operation. The UserHandle class includes methods getUid, getUserId, and getAppId for performing these conversions.
Thus, the Linux uid is comprised of a two-digit Android userId (00, 10, 11, 12, ...) concatenated with a five-digit Android appId (10000, 10001, ...). For example, an app with appId 10056 will run with Linux uid 0010056 when started by the owner (userId 0), and Linux uid 1010056 when started by the first secondary user or restricted profile (userId 10).
System uids not directly associated with apps are still in the range 0-9999. For example, root is uid 0, system is uid 1000, radio is uid 1001, and shell is uid 2000.