summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--data/etc/platform.xml4
-rw-r--r--services/core/java/com/android/server/SystemConfig.java18
-rw-r--r--services/core/java/com/android/server/pm/BasePermission.java35
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java2
-rw-r--r--services/core/java/com/android/server/pm/PermissionsState.java31
-rw-r--r--services/core/java/com/android/server/pm/Settings.java5
6 files changed, 67 insertions, 28 deletions
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 6659769..c517201 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -58,11 +58,11 @@
<group gid="log" />
</permission>
- <permission name="android.permission.READ_EXTERNAL_STORAGE" >
+ <permission name="android.permission.READ_EXTERNAL_STORAGE" perUser="true" >
<group gid="sdcard_r" />
</permission>
- <permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
+ <permission name="android.permission.WRITE_EXTERNAL_STORAGE" perUser="true" >
<group gid="sdcard_r" />
<group gid="sdcard_rw" />
</permission>
diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java
index 6ad128c..4c9d7d3 100644
--- a/services/core/java/com/android/server/SystemConfig.java
+++ b/services/core/java/com/android/server/SystemConfig.java
@@ -71,9 +71,11 @@ public class SystemConfig {
public static final class PermissionEntry {
public final String name;
public int[] gids;
+ public boolean perUser;
- PermissionEntry(String _name) {
- name = _name;
+ PermissionEntry(String name, boolean perUser) {
+ this.name = name;
+ this.perUser = perUser;
}
}
@@ -363,14 +365,14 @@ public class SystemConfig {
void readPermission(XmlPullParser parser, String name)
throws IOException, XmlPullParserException {
+ if (mPermissions.containsKey(name)) {
+ throw new IllegalStateException("Duplicate permission definition for " + name);
+ }
- name = name.intern();
+ final boolean perUser = XmlUtils.readBooleanAttribute(parser, "perUser", false);
+ final PermissionEntry perm = new PermissionEntry(name, perUser);
+ mPermissions.put(name, perm);
- PermissionEntry perm = mPermissions.get(name);
- if (perm == null) {
- perm = new PermissionEntry(name);
- mPermissions.put(name, perm);
- }
int outerDepth = parser.getDepth();
int type;
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
diff --git a/services/core/java/com/android/server/pm/BasePermission.java b/services/core/java/com/android/server/pm/BasePermission.java
index 138a146..ec290ef 100644
--- a/services/core/java/com/android/server/pm/BasePermission.java
+++ b/services/core/java/com/android/server/pm/BasePermission.java
@@ -18,6 +18,9 @@ package com.android.server.pm;
import android.content.pm.PackageParser;
import android.content.pm.PermissionInfo;
+import android.os.UserHandle;
+
+import com.android.internal.util.ArrayUtils;
final class BasePermission {
final static int TYPE_NORMAL = 0;
@@ -40,9 +43,17 @@ final class BasePermission {
PermissionInfo pendingInfo;
+ /** UID that owns the definition of this permission */
int uid;
- int[] gids;
+ /** Additional GIDs given to apps granted this permission */
+ private int[] gids;
+
+ /**
+ * Flag indicating that {@link #gids} should be adjusted based on the
+ * {@link UserHandle} the granted app is running as.
+ */
+ private boolean perUser;
BasePermission(String _name, String _sourcePackage, int _type) {
name = _name;
@@ -52,11 +63,33 @@ final class BasePermission {
protectionLevel = PermissionInfo.PROTECTION_SIGNATURE;
}
+ @Override
public String toString() {
return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " " + name
+ "}";
}
+ public void setGids(int[] gids, boolean perUser) {
+ this.gids = gids;
+ this.perUser = perUser;
+ }
+
+ public boolean hasGids() {
+ return ArrayUtils.isEmpty(gids);
+ }
+
+ public int[] computeGids(int userId) {
+ if (perUser) {
+ final int[] userGids = new int[gids.length];
+ for (int i = 0; i < gids.length; i++) {
+ userGids[i] = UserHandle.getUid(userId, gids[i]);
+ }
+ return userGids;
+ } else {
+ return gids;
+ }
+ }
+
public boolean isRuntime() {
return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_DANGEROUS;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 26b29a2..668dd1a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1429,7 +1429,7 @@ public class PackageManagerService extends IPackageManager.Stub {
mSettings.mPermissions.put(perm.name, bp);
}
if (perm.gids != null) {
- bp.gids = appendInts(bp.gids, perm.gids);
+ bp.setGids(perm.gids, perm.perUser);
}
}
diff --git a/services/core/java/com/android/server/pm/PermissionsState.java b/services/core/java/com/android/server/pm/PermissionsState.java
index f6417ce..3e0e342 100644
--- a/services/core/java/com/android/server/pm/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/PermissionsState.java
@@ -19,6 +19,7 @@ package com.android.server.pm;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
+
import com.android.internal.util.ArrayUtils;
import java.util.Arrays;
@@ -214,7 +215,7 @@ public final class PermissionsState {
int result = PERMISSION_OPERATION_SUCCESS;
PermissionData permissionData = mPermissions.get(permission.name);
- if (permissionData.getGids() != NO_GIDS) {
+ if (permissionData.hasGids()) {
for (int userId : permissionData.getUserIds()) {
if (revokePermission(permission, userId)
== PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED) {
@@ -226,7 +227,7 @@ public final class PermissionsState {
mPermissions.remove(permission.name);
- return result;
+ return result;
}
/**
@@ -333,7 +334,7 @@ public final class PermissionsState {
continue;
}
PermissionData permissionData = mPermissions.valueAt(i);
- final int[] permGids = permissionData.getGids();
+ final int[] permGids = permissionData.computeGids(userId);
if (permGids != NO_GIDS) {
gids = appendInts(gids, permGids);
}
@@ -373,7 +374,7 @@ public final class PermissionsState {
return PERMISSION_OPERATION_FAILURE;
}
- final boolean hasGids = permission.gids != NO_GIDS;
+ final boolean hasGids = permission.hasGids();
final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS;
if (mPermissions == null) {
@@ -382,7 +383,7 @@ public final class PermissionsState {
PermissionData permissionData = mPermissions.get(permission.name);
if (permissionData == null) {
- permissionData = new PermissionData(permission.gids);
+ permissionData = new PermissionData(permission);
mPermissions.put(permission.name, permissionData);
}
@@ -405,7 +406,7 @@ public final class PermissionsState {
return PERMISSION_OPERATION_FAILURE;
}
- final boolean hasGids = permission.gids != NO_GIDS;
+ final boolean hasGids = permission.hasGids();
final int[] oldGids = hasGids ? computeGids(userId) : NO_GIDS;
PermissionData permissionData = mPermissions.get(permission.name);
@@ -448,17 +449,15 @@ public final class PermissionsState {
}
private static final class PermissionData {
- private final int[] mGids;
+ private final BasePermission mPerm;
private int[] mUserIds = USERS_NONE;
- public PermissionData(int[] gids) {
- mGids = !ArrayUtils.isEmpty(gids)
- ? Arrays.copyOf(gids, gids.length)
- : NO_GIDS;
+ public PermissionData(BasePermission perm) {
+ mPerm = perm;
}
public PermissionData(PermissionData other) {
- this(other.mGids);
+ this(other.mPerm);
if (other.mUserIds == USERS_ALL || other.mUserIds == USERS_NONE) {
mUserIds = other.mUserIds;
@@ -467,8 +466,12 @@ public final class PermissionsState {
}
}
- public int[] getGids() {
- return mGids;
+ public boolean hasGids() {
+ return mPerm.hasGids();
+ }
+
+ public int[] computeGids(int userId) {
+ return mPerm.computeGids(userId);
}
public int[] getUserIds() {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 1e0a49e..82aa74a 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -485,7 +485,7 @@ final class Settings {
bp.pendingInfo.packageName = newPkg;
}
bp.uid = 0;
- bp.gids = null;
+ bp.setGids(null, false);
}
}
}
@@ -3700,7 +3700,8 @@ final class Settings {
pw.println("):");
pw.print(" sourcePackage="); pw.println(p.sourcePackage);
pw.print(" uid="); pw.print(p.uid);
- pw.print(" gids="); pw.print(PackageManagerService.arrayToString(p.gids));
+ pw.print(" gids="); pw.print(Arrays.toString(
+ p.computeGids(UserHandle.USER_OWNER)));
pw.print(" type="); pw.print(p.type);
pw.print(" prot=");
pw.println(PermissionInfo.protectionToString(p.protectionLevel));