OSDN Git Service

Apply cross-user restrictions to Shell
authorAmith Yamasani <yamasani@google.com>
Mon, 9 Jun 2014 00:54:27 +0000 (17:54 -0700)
committerAmith Yamasani <yamasani@google.com>
Thu, 11 Sep 2014 00:15:06 +0000 (17:15 -0700)
Even though Shell user is allowed to perform cross-user actions,
lock that path down if the target user has restrictions imposed by
the profile owner device admin that prevents access via adb.

If the profile owner has imposed DISALLOW_DEBUGGING_FEATURES, don't
allow the shell user to make the following types of calls:
start activities, make service calls, access content providers,
send broadcasts, block/unblock packages, clear user data, etc.

Bug: 15086577
Change-Id: I9669fc165953076f786ed51cbc17d20d6fa995c3

cmds/am/src/com/android/commands/am/Am.java
core/java/android/os/IUserManager.aidl
core/java/android/os/UserManager.java
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/pm/PackageInstallerService.java
services/core/java/com/android/server/pm/PackageManagerService.java
services/core/java/com/android/server/pm/Settings.java
services/core/java/com/android/server/pm/UserManagerService.java
services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
services/usage/java/com/android/server/usage/UsageStatsService.java

index c06ef0d..a0ba32e 100644 (file)
@@ -846,7 +846,7 @@ public class Am extends BaseCommand {
     }
 
     private void sendBroadcast() throws Exception {
-        Intent intent = makeIntent(UserHandle.USER_ALL);
+        Intent intent = makeIntent(UserHandle.USER_CURRENT);
         IntentReceiver receiver = new IntentReceiver();
         System.out.println("Broadcasting: " + intent);
         mAm.broadcastIntent(null, intent, null, receiver, 0, null, null, mReceiverPermission,
index 3286627..b5295fb 100644 (file)
@@ -41,6 +41,7 @@ interface IUserManager {
     int getUserSerialNumber(int userHandle);
     int getUserHandle(int userSerialNumber);
     Bundle getUserRestrictions(int userHandle);
+    boolean hasUserRestriction(in String restrictionKey, int userHandle);
     void setUserRestrictions(in Bundle restrictions, int userHandle);
     void setApplicationRestrictions(in String packageName, in Bundle restrictions,
             int userHandle);
index 33fda4a..c76ff11 100644 (file)
@@ -630,7 +630,13 @@ public class UserManager {
      * @param userHandle the UserHandle of the user for whom to retrieve the restrictions.
      */
     public boolean hasUserRestriction(String restrictionKey, UserHandle userHandle) {
-        return getUserRestrictions(userHandle).getBoolean(restrictionKey, false);
+        try {
+            return mService.hasUserRestriction(restrictionKey,
+                    userHandle.getIdentifier());
+        } catch (RemoteException re) {
+            Log.w(TAG, "Could not check user restrictions", re);
+            return false;
+        }
     }
 
     /**
index a9a4732..a97715a 100755 (executable)
@@ -180,6 +180,7 @@ import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.os.UpdateLock;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.provider.Settings;
 import android.text.format.DateUtils;
 import android.text.format.Time;
@@ -3364,6 +3365,16 @@ public final class ActivityManagerService extends ActivityManagerNative
         }
     }
 
+    void enforceShellRestriction(String restriction, int userHandle) {
+        if (Binder.getCallingUid() == Process.SHELL_UID) {
+            if (userHandle < 0
+                    || mUserManager.hasUserRestriction(restriction, userHandle)) {
+                throw new SecurityException("Shell does not have permission to access user "
+                        + userHandle);
+            }
+        }
+    }
+
     @Override
     public int getFrontActivityScreenCompatMode() {
         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
@@ -14548,6 +14559,14 @@ public final class ActivityManagerService extends ActivityManagerNative
             throw new IllegalArgumentException(
                     "Call does not support special user #" + targetUserId);
         }
+        // Check shell permission
+        if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
+            if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
+                    targetUserId)) {
+                throw new SecurityException("Shell does not have permission to access user "
+                        + targetUserId + "\n " + Debug.getCallers(3));
+            }
+        }
         return targetUserId;
     }
 
@@ -14606,6 +14625,7 @@ public final class ActivityManagerService extends ActivityManagerNative
             Intent service, String resolvedType,
             IServiceConnection connection, int flags, int userId) {
         enforceNotIsolatedCaller("bindService");
+
         // Refuse possible leaked file descriptors
         if (service != null && service.hasFileDescriptors() == true) {
             throw new IllegalArgumentException("File descriptors passed in Intent");
@@ -15040,12 +15060,18 @@ public final class ActivityManagerService extends ActivityManagerNative
     }
 
     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
-            int[] users) {
+            int callingUid, int[] users) {
         List<ResolveInfo> receivers = null;
         try {
             HashSet<ComponentName> singleUserReceivers = null;
             boolean scannedFirstReceivers = false;
             for (int user : users) {
+                // Skip users that have Shell restrictions
+                if (callingUid == Process.SHELL_UID
+                        && getUserManagerLocked().hasUserRestriction(
+                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
+                    continue;
+                }
                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
                         .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
                 if (user != 0 && newReceivers != null) {
@@ -15134,7 +15160,6 @@ public final class ActivityManagerService extends ActivityManagerNative
         // Make sure that the user who is receiving this broadcast is started.
         // If not, we will just skip it.
 
-
         if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
             if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
                     & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
@@ -15399,11 +15424,30 @@ public final class ActivityManagerService extends ActivityManagerNative
         // Need to resolve the intent to interested receivers...
         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                  == 0) {
-            receivers = collectReceiverComponents(intent, resolvedType, users);
+            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
         }
         if (intent.getComponent() == null) {
-            registeredReceivers = mReceiverResolver.queryIntent(intent,
-                    resolvedType, false, userId);
+            if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
+                // Query one target user at a time, excluding shell-restricted users
+                UserManagerService ums = getUserManagerLocked();
+                for (int i = 0; i < users.length; i++) {
+                    if (ums.hasUserRestriction(
+                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
+                        continue;
+                    }
+                    List<BroadcastFilter> registeredReceiversForUser =
+                            mReceiverResolver.queryIntent(intent,
+                                    resolvedType, false, users[i]);
+                    if (registeredReceivers == null) {
+                        registeredReceivers = registeredReceiversForUser;
+                    } else if (registeredReceiversForUser != null) {
+                        registeredReceivers.addAll(registeredReceiversForUser);
+                    }
+                }
+            } else {
+                registeredReceivers = mReceiverResolver.queryIntent(intent,
+                        resolvedType, false, userId);
+            }
         }
 
         final boolean replacePending =
@@ -15565,7 +15609,7 @@ public final class ActivityManagerService extends ActivityManagerNative
         enforceNotIsolatedCaller("broadcastIntent");
         synchronized(this) {
             intent = verifyBroadcastLocked(intent);
-            
+
             final ProcessRecord callerApp = getRecordForAppLocked(caller);
             final int callingPid = Binder.getCallingPid();
             final int callingUid = Binder.getCallingUid();
@@ -17973,6 +18017,7 @@ public final class ActivityManagerService extends ActivityManagerNative
 
     @Override
     public boolean switchUser(final int userId) {
+        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
         String userName;
         synchronized (this) {
             UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
@@ -18414,6 +18459,7 @@ public final class ActivityManagerService extends ActivityManagerNative
         if (userId <= 0) {
             throw new IllegalArgumentException("Can't stop primary user " + userId);
         }
+        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
         synchronized (this) {
             return stopUserLocked(userId, callback);
         }
index 496c136..ed678d2 100644 (file)
@@ -446,7 +446,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
     private int createSessionInternal(SessionParams params, String installerPackageName, int userId)
             throws IOException {
         final int callingUid = Binder.getCallingUid();
-        mPm.enforceCrossUserPermission(callingUid, userId, true, "createSession");
+        mPm.enforceCrossUserPermission(callingUid, userId, true, false, "createSession");
 
         if (mPm.isUserRestricted(UserHandle.getUserId(callingUid),
                 UserManager.DISALLOW_INSTALL_APPS)) {
@@ -654,7 +654,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
 
     @Override
     public List<SessionInfo> getAllSessions(int userId) {
-        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "getAllSessions");
+        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getAllSessions");
 
         final List<SessionInfo> result = new ArrayList<>();
         synchronized (mSessions) {
@@ -670,7 +670,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
 
     @Override
     public List<SessionInfo> getMySessions(String installerPackageName, int userId) {
-        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "getMySessions");
+        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "getMySessions");
         mAppOps.checkPackage(Binder.getCallingUid(), installerPackageName);
 
         final List<SessionInfo> result = new ArrayList<>();
@@ -688,7 +688,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
 
     @Override
     public void uninstall(String packageName, int flags, IntentSender statusReceiver, int userId) {
-        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "uninstall");
+        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "uninstall");
 
         final PackageDeleteObserverAdapter adapter = new PackageDeleteObserverAdapter(mContext,
                 statusReceiver, packageName);
@@ -717,7 +717,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
 
     @Override
     public void registerCallback(IPackageInstallerCallback callback, int userId) {
-        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "registerCallback");
+        mPm.enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "registerCallback");
         mCallbacks.register(callback, userId);
     }
 
index d1bc35b..c42cc76 100644 (file)
@@ -138,6 +138,7 @@ import android.os.Bundle;
 import android.os.Environment;
 import android.os.Environment.UserEnvironment;
 import android.os.storage.StorageManager;
+import android.os.Debug;
 import android.os.FileUtils;
 import android.os.Handler;
 import android.os.IBinder;
@@ -1845,7 +1846,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     @Override
     public boolean isPackageAvailable(String packageName, int userId) {
         if (!sUserManager.exists(userId)) return false;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "is package available");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "is package available");
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
             if (p != null) {
@@ -1864,7 +1865,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     @Override
     public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package info");
         // reader
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
@@ -1909,7 +1910,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     @Override
     public int getPackageUid(String packageName, int userId) {
         if (!sUserManager.exists(userId)) return -1;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get package uid");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get package uid");
         // reader
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
@@ -2059,7 +2060,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     @Override
     public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get application info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get application info");
         // writer
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
@@ -2150,7 +2151,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     @Override
     public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get activity info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get activity info");
         synchronized (mPackages) {
             PackageParser.Activity a = mActivities.mActivities.get(component);
 
@@ -2189,7 +2190,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     @Override
     public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get receiver info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get receiver info");
         synchronized (mPackages) {
             PackageParser.Activity a = mReceivers.mActivities.get(component);
             if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2207,7 +2208,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     @Override
     public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get service info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get service info");
         synchronized (mPackages) {
             PackageParser.Service s = mServices.mServices.get(component);
             if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2225,7 +2226,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     @Override
     public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "get provider info");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "get provider info");
         synchronized (mPackages) {
             PackageParser.Provider p = mProviders.mProviders.get(component);
             if (DEBUG_PACKAGE_INFO) Log.v(
@@ -2329,13 +2330,17 @@ public class PackageManagerService extends IPackageManager.Stub {
     /**
      * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
      * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
+     * @param checkShell TODO(yamasani):
      * @param message the message to log on security exception
      */
     void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
-            String message) {
+            boolean checkShell, String message) {
         if (userId < 0) {
             throw new IllegalArgumentException("Invalid userId " + userId);
         }
+        if (checkShell) {
+            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
+        }
         if (userId == UserHandle.getUserId(callingUid)) return;
         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
             if (requireFullPermission) {
@@ -2353,6 +2358,19 @@ public class PackageManagerService extends IPackageManager.Stub {
         }
     }
 
+    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
+        if (callingUid == Process.SHELL_UID) {
+            if (userHandle >= 0
+                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
+                throw new SecurityException("Shell does not have permission to access user "
+                        + userHandle);
+            } else if (userHandle < 0) {
+                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
+                        + Debug.getCallers(3));
+            }
+        }
+    }
+
     private BasePermission findPermissionTreeLP(String permName) {
         for(BasePermission bp : mSettings.mPermissionTrees.values()) {
             if (permName.startsWith(bp.name) &&
@@ -2876,7 +2894,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     public ResolveInfo resolveIntent(Intent intent, String resolvedType,
             int flags, int userId) {
         if (!sUserManager.exists(userId)) return null;
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "resolve intent");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "resolve intent");
         List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId);
         return chooseBestActivity(intent, resolvedType, flags, query, userId);
     }
@@ -3217,7 +3235,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     public List<ResolveInfo> queryIntentActivities(Intent intent,
             String resolvedType, int flags, int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, "query intent activities");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false, "query intent activities");
         ComponentName comp = intent.getComponent();
         if (comp == null) {
             if (intent.getSelector() != null) {
@@ -3431,7 +3449,7 @@ public class PackageManagerService extends IPackageManager.Stub {
             String resolvedType, int flags, int userId) {
         if (!sUserManager.exists(userId)) return Collections.emptyList();
         enforceCrossUserPermission(Binder.getCallingUid(), userId, false,
-                "query intent activity options");
+                false, "query intent activity options");
         final String resultsAction = intent.getAction();
 
         List<ResolveInfo> results = queryIntentActivities(intent, resolvedType, flags
@@ -3727,7 +3745,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
         final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0;
 
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "get installed packages");
 
         // writer
         synchronized (mPackages) {
@@ -7747,7 +7765,7 @@ public class PackageManagerService extends IPackageManager.Stub {
 
         final File originFile = new File(originPath);
         final int uid = Binder.getCallingUid();
-        if (isUserRestricted(UserHandle.getUserId(uid), UserManager.DISALLOW_INSTALL_APPS)) {
+        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
             try {
                 if (observer != null) {
                     observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
@@ -7835,11 +7853,8 @@ public class PackageManagerService extends IPackageManager.Stub {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
         PackageSetting pkgSetting;
         final int uid = Binder.getCallingUid();
-        if (UserHandle.getUserId(uid) != userId) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
-                    "setApplicationHiddenSetting for user " + userId);
-        }
+        enforceCrossUserPermission(uid, userId, true, true,
+                "setApplicationHiddenSetting for user " + userId);
 
         if (hidden && isPackageDeviceAdmin(packageName, userId)) {
             Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
@@ -7898,7 +7913,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
         enforceCrossUserPermission(Binder.getCallingUid(), userId, true,
-                "getApplicationHidden for user " + userId);
+                false, "getApplicationHidden for user " + userId);
         PackageSetting pkgSetting;
         long callingId = Binder.clearCallingIdentity();
         try {
@@ -7924,7 +7939,8 @@ public class PackageManagerService extends IPackageManager.Stub {
                 null);
         PackageSetting pkgSetting;
         final int uid = Binder.getCallingUid();
-        enforceCrossUserPermission(uid, userId, true, "installExistingPackage for user " + userId);
+        enforceCrossUserPermission(uid, userId, true, true, "installExistingPackage for user "
+                + userId);
         if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
             return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
         }
@@ -11048,7 +11064,7 @@ public class PackageManagerService extends IPackageManager.Stub {
             final IPackageDataObserver observer, final int userId) {
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.CLEAR_APP_USER_DATA, null);
-        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "clear application data");
+        enforceCrossUserPermission(Binder.getCallingUid(), userId, true, false, "clear application data");
         // Queue up an async operation since the package deletion may take a little while.
         mHandler.post(new Runnable() {
             public void run() {
@@ -11348,7 +11364,7 @@ public class PackageManagerService extends IPackageManager.Stub {
             String opname) {
         // writer
         int callingUid = Binder.getCallingUid();
-        enforceCrossUserPermission(callingUid, userId, true, "add preferred activity");
+        enforceCrossUserPermission(callingUid, userId, true, false, "add preferred activity");
         if (filter.countActions() == 0) {
             Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
             return;
@@ -11393,7 +11409,7 @@ public class PackageManagerService extends IPackageManager.Stub {
         }
 
         final int callingUid = Binder.getCallingUid();
-        enforceCrossUserPermission(callingUid, userId, true, "replace preferred activity");
+        enforceCrossUserPermission(callingUid, userId, true, false, "replace preferred activity");
         synchronized (mPackages) {
             if (mContext.checkCallingOrSelfPermission(
                     android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
@@ -11534,6 +11550,7 @@ public class PackageManagerService extends IPackageManager.Stub {
 
     @Override
     public void resetPreferredActivities(int userId) {
+        /* TODO: Actually use userId. Why is it being passed in? */
         mContext.enforceCallingOrSelfPermission(
                 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
         // writer
@@ -11648,6 +11665,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
         int callingUid = Binder.getCallingUid();
         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
+        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
         if (intentFilter.countActions() == 0) {
             Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
             return;
@@ -11685,6 +11703,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                         android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
         int callingUid = Binder.getCallingUid();
         enforceOwnerRights(ownerPackage, ownerUserId, callingUid);
+        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
         int callingUserId = UserHandle.getUserId(callingUid);
         synchronized (mPackages) {
             CrossProfileIntentResolver resolver =
@@ -11779,7 +11798,7 @@ public class PackageManagerService extends IPackageManager.Stub {
         final int uid = Binder.getCallingUid();
         final int permission = mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
-        enforceCrossUserPermission(uid, userId, false, "set enabled");
+        enforceCrossUserPermission(uid, userId, false, true, "set enabled");
         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
         boolean sendNow = false;
         boolean isApp = (className == null);
@@ -11913,7 +11932,7 @@ public class PackageManagerService extends IPackageManager.Stub {
         final int permission = mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
         final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
-        enforceCrossUserPermission(uid, userId, true, "stop package");
+        enforceCrossUserPermission(uid, userId, true, true, "stop package");
         // writer
         synchronized (mPackages) {
             if (mSettings.setPackageStoppedStateLPw(packageName, stopped, allowedByPermission,
@@ -11935,7 +11954,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     public int getApplicationEnabledSetting(String packageName, int userId) {
         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
         int uid = Binder.getCallingUid();
-        enforceCrossUserPermission(uid, userId, false, "get enabled");
+        enforceCrossUserPermission(uid, userId, false, false, "get enabled");
         // reader
         synchronized (mPackages) {
             return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
@@ -11946,7 +11965,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     public int getComponentEnabledSetting(ComponentName componentName, int userId) {
         if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
         int uid = Binder.getCallingUid();
-        enforceCrossUserPermission(uid, userId, false, "get component enabled");
+        enforceCrossUserPermission(uid, userId, false, false, "get component enabled");
         // reader
         synchronized (mPackages) {
             return mSettings.getComponentEnabledSettingLPr(componentName, userId);
index c1caeac..e600c43 100644 (file)
@@ -517,6 +517,7 @@ final class Settings {
             int vc, int pkgFlags, UserHandle installUser, boolean add,
             boolean allowInstall) {
         PackageSetting p = mPackages.get(name);
+        UserManagerService userManager = UserManagerService.getInstance();
         if (p != null) {
             p.primaryCpuAbiString = primaryCpuAbiString;
             p.secondaryCpuAbiString = secondaryCpuAbiString;
@@ -594,6 +595,7 @@ final class Settings {
                         Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
                     }
                     List<UserInfo> users = getAllUsers();
+                    final int installUserId = installUser != null ? installUser.getIdentifier() : 0;
                     if (users != null && allowInstall) {
                         for (UserInfo user : users) {
                             // By default we consider this app to be installed
@@ -603,8 +605,9 @@ final class Settings {
                             // asked to install for all users, or this is the
                             // user we are installing for.
                             final boolean installed = installUser == null
-                                    || installUser.getIdentifier() == UserHandle.USER_ALL
-                                    || installUser.getIdentifier() == user.id;
+                                    || (installUserId == UserHandle.USER_ALL
+                                        && !isAdbInstallDisallowed(userManager, user.id))
+                                    || installUserId == user.id;
                             p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT,
                                     installed,
                                     true, // stopped,
@@ -670,7 +673,8 @@ final class Settings {
                 List<UserInfo> users = getAllUsers();
                 if (users != null) {
                     for (UserInfo user : users) {
-                        if (installUser.getIdentifier() == UserHandle.USER_ALL
+                        if ((installUser.getIdentifier() == UserHandle.USER_ALL
+                                    && !isAdbInstallDisallowed(userManager, user.id))
                                 || installUser.getIdentifier() == user.id) {
                             boolean installed = p.getInstalled(user.id);
                             if (!installed) {
@@ -685,6 +689,11 @@ final class Settings {
         return p;
     }
 
+    boolean isAdbInstallDisallowed(UserManagerService userManager, int userId) {
+        return userManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
+                userId);
+    }
+
     void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
         p.pkg = pkg;
         // pkg.mSetEnabled = p.getEnabled(userId);
index 6dd6d2e..a06e041 100644 (file)
@@ -34,6 +34,7 @@ import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.Debug;
 import android.os.Environment;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -480,6 +481,14 @@ public class UserManagerService extends IUserManager.Stub {
     }
 
     @Override
+    public boolean hasUserRestriction(String restrictionKey, int userId) {
+        synchronized (mPackagesLock) {
+            Bundle restrictions = mUserRestrictions.get(userId);
+            return restrictions != null ? restrictions.getBoolean(restrictionKey) : false;
+        }
+    }
+
+    @Override
     public Bundle getUserRestrictions(int userId) {
         // checkManageUsersPermission("getUserRestrictions");
 
index 09584f4..0f4521b 100644 (file)
@@ -4608,7 +4608,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
 
     @Override
     public void setUserRestriction(ComponentName who, String key, boolean enabled) {
-        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
+        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
+        final int userHandle = user.getIdentifier();
         synchronized (this) {
             if (who == null) {
                 throw new NullPointerException("ComponentName is null");
@@ -4619,7 +4620,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
             if (!isDeviceOwner && DEVICE_OWNER_USER_RESTRICTIONS.contains(key)) {
                 throw new SecurityException("Profile owners cannot set user restriction " + key);
             }
-            boolean alreadyRestricted = mUserManager.hasUserRestriction(key, userHandle);
+            boolean alreadyRestricted = mUserManager.hasUserRestriction(key, user);
 
             IAudioService iAudioService = null;
             if (UserManager.DISALLOW_UNMUTE_MICROPHONE.equals(key)
@@ -4645,7 +4646,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                     if (UserManager.DISALLOW_CONFIG_WIFI.equals(key)) {
                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                                 Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0,
-                                userHandle.getIdentifier());
+                                userHandle);
                     } else if (UserManager.DISALLOW_USB_FILE_TRANSFER.equals(key)) {
                         UsbManager manager =
                                 (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
@@ -4653,27 +4654,30 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
                     } else if (UserManager.DISALLOW_SHARE_LOCATION.equals(key)) {
                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                                 Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF,
-                                userHandle.getIdentifier());
+                                userHandle);
                         Settings.Secure.putStringForUser(mContext.getContentResolver(),
                                 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "",
-                                userHandle.getIdentifier());
+                                userHandle);
                     } else if (UserManager.DISALLOW_DEBUGGING_FEATURES.equals(key)) {
-                        Settings.Global.putStringForUser(mContext.getContentResolver(),
-                                Settings.Global.ADB_ENABLED, "0", userHandle.getIdentifier());
+                        // Only disable adb if changing for primary user, since it is global
+                        if (userHandle == UserHandle.USER_OWNER) {
+                            Settings.Global.putStringForUser(mContext.getContentResolver(),
+                                    Settings.Global.ADB_ENABLED, "0", userHandle);
+                        }
                     } else if (UserManager.ENSURE_VERIFY_APPS.equals(key)) {
                         Settings.Global.putStringForUser(mContext.getContentResolver(),
                                 Settings.Global.PACKAGE_VERIFIER_ENABLE, "1",
-                                userHandle.getIdentifier());
+                                userHandle);
                         Settings.Global.putStringForUser(mContext.getContentResolver(),
                                 Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, "1",
-                                userHandle.getIdentifier());
+                                userHandle);
                     } else if (UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES.equals(key)) {
                         Settings.Secure.putIntForUser(mContext.getContentResolver(),
                                 Settings.Secure.INSTALL_NON_MARKET_APPS, 0,
-                                userHandle.getIdentifier());
+                                userHandle);
                     }
                 }
-                mUserManager.setUserRestriction(key, enabled, userHandle);
+                mUserManager.setUserRestriction(key, enabled, user);
             } finally {
                 restoreCallingIdentity(id);
             }
index 2dcdcc4..92117c3 100644 (file)
@@ -33,6 +33,7 @@ import android.content.pm.ParceledListSlice;
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.os.Binder;
+import android.os.Debug;
 import android.os.Environment;
 import android.os.Handler;
 import android.os.Looper;