diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/UserManagerService.java | 41 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java | 7 | 
2 files changed, 48 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 15fdc5e09195..22900bf2c594 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -78,6 +78,7 @@ import android.security.GateKeeper;  import android.service.gatekeeper.IGateKeeperService;  import android.stats.devicepolicy.DevicePolicyEnums;  import android.util.AtomicFile; +import android.util.EventLog;  import android.util.IntArray;  import android.util.Log;  import android.util.Slog; @@ -3206,6 +3207,13 @@ public class UserManagerService extends IUserManager.Stub {      public void setApplicationRestrictions(String packageName, Bundle restrictions,              int userId) {          checkSystemOrRoot("set application restrictions"); +        String validationResult = validateName(packageName); +        if (validationResult != null) { +            if (packageName.contains("../")) { +                EventLog.writeEvent(0x534e4554, "239701237", -1, ""); +            } +            throw new IllegalArgumentException("Invalid package name: " + validationResult); +        }          if (restrictions != null) {              restrictions.setDefusable(true);          } @@ -3225,6 +3233,39 @@ public class UserManagerService extends IUserManager.Stub {          mContext.sendBroadcastAsUser(changeIntent, UserHandle.of(userId));      } +    /** +     * Check if the given name is valid. +     * +     * Note: the logic is taken from FrameworkParsingPackageUtils in master, edited to remove +     * unnecessary parts. Copied here for a security fix. +     * +     * @param name The name to check. +     * @return null if it's valid, error message if not +     */ +    @VisibleForTesting +    static String validateName(String name) { +        final int n = name.length(); +        boolean front = true; +        for (int i = 0; i < n; i++) { +            final char c = name.charAt(i); +            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { +                front = false; +                continue; +            } +            if (!front) { +                if ((c >= '0' && c <= '9') || c == '_') { +                    continue; +                } +                if (c == '.') { +                    front = true; +                    continue; +                } +            } +            return "bad character '" + c + "'"; +        } +        return null; +    } +      private int getUidForPackage(String packageName) {          long ident = Binder.clearCallingIdentity();          try { diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java index d1366144d33b..8da7a76f18ce 100644 --- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceTest.java @@ -74,6 +74,13 @@ public class UserManagerServiceTest extends AndroidTestCase {          assertEquals(accountName, um.getUserAccount(tempUserId));      } +    public void testValidateName() { +        assertNull(UserManagerService.validateName("android")); +        assertNull(UserManagerService.validateName("com.company.myapp")); +        assertNotNull(UserManagerService.validateName("/../../data")); +        assertNotNull(UserManagerService.validateName("/dir")); +    } +      private Bundle createBundle() {          Bundle result = new Bundle();          // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[]  |