Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00f39046 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

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
parent 95c1adea
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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>
+10 −8
Original line number Diff line number Diff line
@@ -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();

        PermissionEntry perm = mPermissions.get(name);
        if (perm == null) {
            perm = new PermissionEntry(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
+34 −1
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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);
                }
            }
+17 −14
Original line number Diff line number Diff line
@@ -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) {
@@ -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() {
Loading