Skip to content

Commit 01875b0

Browse files
Sudheer ShankaThe Android Automerger
authored andcommitted
Reduce shell power over user management.
Remove MANAGE_USERS permission from shell and whitelist it for some specific functionality. Bug: 29189712 Change-Id: Ifb37448c091af91991964511e3efb1bb4dea1ff3
1 parent 468651c commit 01875b0

3 files changed

Lines changed: 84 additions & 6 deletions

File tree

core/res/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,14 @@
13921392
<permission android:name="android.permission.MANAGE_USERS"
13931393
android:protectionLevel="signature|privileged" />
13941394

1395+
<!-- @hide Allows an application to create, remove users and get the list of
1396+
users on the device. Applications holding this permission can only create restricted,
1397+
guest, and managed users. For creating other kind of users,
1398+
{@link android.Manifest.permission#MANAGE_USERS} is needed.
1399+
This permission is not available to third party applications. -->
1400+
<permission android:name="android.permission.CREATE_USERS"
1401+
android:protectionLevel="signature" />
1402+
13951403
<!-- @hide Allows an application to set the profile owners and the device owner.
13961404
This permission is not available to third party applications.-->
13971405
<permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS"

packages/Shell/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@
8989
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
9090
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
9191
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
92-
<uses-permission android:name="android.permission.MANAGE_USERS" />
92+
<uses-permission android:name="android.permission.CREATE_USERS" />
9393
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
9494
<uses-permission android:name="android.permission.BLUETOOTH_STACK" />
9595
<uses-permission android:name="android.permission.GET_ACCOUNTS" />

services/core/java/com/android/server/pm/UserManagerService.java

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ public class UserManagerService extends IUserManager.Stub {
125125
private static final String RESTRICTIONS_FILE_PREFIX = "res_";
126126
private static final String XML_SUFFIX = ".xml";
127127

128+
private static final int ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION =
129+
UserInfo.FLAG_MANAGED_PROFILE
130+
| UserInfo.FLAG_RESTRICTED
131+
| UserInfo.FLAG_GUEST;
132+
128133
private static final int MIN_USER_ID = 10;
129134

130135
private static final int USER_VERSION = 5;
@@ -277,7 +282,7 @@ void systemReady() {
277282

278283
@Override
279284
public List<UserInfo> getUsers(boolean excludeDying) {
280-
checkManageUsersPermission("query users");
285+
checkManageOrCreateUsersPermission("query users");
281286
synchronized (mPackagesLock) {
282287
ArrayList<UserInfo> users = new ArrayList<UserInfo>(mUsers.size());
283288
for (int i = 0; i < mUsers.size(); i++) {
@@ -388,7 +393,7 @@ public void setUserEnabled(int userId) {
388393

389394
@Override
390395
public UserInfo getUserInfo(int userId) {
391-
checkManageUsersPermission("query user");
396+
checkManageOrCreateUsersPermission("query user");
392397
synchronized (mPackagesLock) {
393398
return getUserInfoLocked(userId);
394399
}
@@ -676,6 +681,71 @@ private static final void checkManageUsersPermission(String message) {
676681
}
677682
}
678683

684+
/**
685+
* Enforces that only the system UID or root's UID or apps that have the
686+
* {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or
687+
* {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}
688+
* can make certain calls to the UserManager.
689+
*
690+
* @param message used as message if SecurityException is thrown
691+
* @throws SecurityException if the caller is not system or root
692+
* @see #hasManageOrCreateUsersPermission()
693+
*/
694+
private static final void checkManageOrCreateUsersPermission(String message) {
695+
if (!hasManageOrCreateUsersPermission()) {
696+
throw new SecurityException(
697+
"You either need MANAGE_USERS or CREATE_USERS permission to: " + message);
698+
}
699+
}
700+
701+
/**
702+
* Similar to {@link #checkManageOrCreateUsersPermission(String)} but when the caller is tries
703+
* to create user/profiles other than what is allowed for
704+
* {@link android.Manifest.permission#CREATE_USERS CREATE_USERS} permission, then it will only
705+
* allow callers with {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} permission.
706+
*/
707+
private static final void checkManageOrCreateUsersPermission(int creationFlags) {
708+
if ((creationFlags & ~ALLOWED_FLAGS_FOR_CREATE_USERS_PERMISSION) == 0) {
709+
if (!hasManageOrCreateUsersPermission()) {
710+
throw new SecurityException("You either need MANAGE_USERS or CREATE_USERS "
711+
+ "permission to create an user with flags: " + creationFlags);
712+
}
713+
} else if (!hasManageUsersPermission()) {
714+
throw new SecurityException("You need MANAGE_USERS permission to create an user "
715+
+ " with flags: " + creationFlags);
716+
}
717+
}
718+
719+
/**
720+
* @return whether the calling UID is system UID or root's UID or the calling app has the
721+
* {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS}.
722+
*/
723+
private static final boolean hasManageUsersPermission() {
724+
final int callingUid = Binder.getCallingUid();
725+
return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
726+
|| callingUid == Process.ROOT_UID
727+
|| ActivityManager.checkComponentPermission(
728+
android.Manifest.permission.MANAGE_USERS,
729+
callingUid, -1, true) == PackageManager.PERMISSION_GRANTED;
730+
}
731+
732+
/**
733+
* @return whether the calling UID is system UID or root's UID or the calling app has the
734+
* {@link android.Manifest.permission#MANAGE_USERS MANAGE_USERS} or
735+
* {@link android.Manifest.permission#CREATE_USERS CREATE_USERS}.
736+
*/
737+
private static final boolean hasManageOrCreateUsersPermission() {
738+
final int callingUid = Binder.getCallingUid();
739+
return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)
740+
|| callingUid == Process.ROOT_UID
741+
|| ActivityManager.checkComponentPermission(
742+
android.Manifest.permission.MANAGE_USERS,
743+
callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
744+
|| ActivityManager.checkComponentPermission(
745+
android.Manifest.permission.CREATE_USERS,
746+
callingUid, -1, true) == PackageManager.PERMISSION_GRANTED;
747+
}
748+
679749
private static void checkSystemOrRoot(String message) {
680750
final int uid = Binder.getCallingUid();
681751
if (uid != Process.SYSTEM_UID && uid != 0) {
@@ -1227,7 +1297,7 @@ private void cleanAppRestrictionsForPackage(String pkg, int userId) {
12271297

12281298
@Override
12291299
public UserInfo createProfileForUser(String name, int flags, int userId) {
1230-
checkManageUsersPermission("Only the system can create users");
1300+
checkManageOrCreateUsersPermission(flags);
12311301
if (userId != UserHandle.USER_OWNER) {
12321302
Slog.w(LOG_TAG, "Only user owner can have profiles");
12331303
return null;
@@ -1237,7 +1307,7 @@ public UserInfo createProfileForUser(String name, int flags, int userId) {
12371307

12381308
@Override
12391309
public UserInfo createUser(String name, int flags) {
1240-
checkManageUsersPermission("Only the system can create users");
1310+
checkManageOrCreateUsersPermission(flags);
12411311
return createUserInternal(name, flags, UserHandle.USER_NULL);
12421312
}
12431313

@@ -1402,7 +1472,7 @@ public boolean markGuestForDeletion(int userHandle) {
14021472
* @param userHandle the user's id
14031473
*/
14041474
public boolean removeUser(int userHandle) {
1405-
checkManageUsersPermission("Only the system can remove users");
1475+
checkManageOrCreateUsersPermission("Only the system can remove users");
14061476
if (getUserRestrictions(UserHandle.getCallingUserId()).getBoolean(
14071477
UserManager.DISALLOW_REMOVE_USER, false)) {
14081478
Log.w(LOG_TAG, "Cannot remove user. DISALLOW_REMOVE_USER is enabled.");

0 commit comments

Comments
 (0)