Introduce per-user GIDs for storage.
This will eventually allow us to have a single unified filesystem instead of requiring zygote to use bind mounts. Change-Id: I29b819ab51498b4bab874e0367b1ab4165f84025
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
name = name.intern();
|
||||
|
||||
PermissionEntry perm = mPermissions.get(name);
|
||||
if (perm == null) {
|
||||
perm = new PermissionEntry(name);
|
||||
mPermissions.put(name, perm);
|
||||
if (mPermissions.containsKey(name)) {
|
||||
throw new IllegalStateException("Duplicate permission definition for " + name);
|
||||
}
|
||||
|
||||
final boolean perUser = XmlUtils.readBooleanAttribute(parser, "perUser", false);
|
||||
final PermissionEntry perm = new PermissionEntry(name, perUser);
|
||||
mPermissions.put(name, perm);
|
||||
|
||||
int outerDepth = parser.getDepth();
|
||||
int type;
|
||||
while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user