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

Commit 7c3472dc authored by Clark Scheff's avatar Clark Scheff Committed by Steve Kondik
Browse files

Allow granting permissions based on signature in <allow-permission/>

This patch allows us to either specify a sharedUserId or a package
signature to use when granting the specific permission.

Change-Id: I8aed78d40316e0e94ac1bfefc7c4a3016a2a9a6b
parent 2e68cb6c
Loading
Loading
Loading
Loading
+45 −0
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server;
package com.android.server;


import android.content.pm.FeatureInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.Signature;
import android.os.*;
import android.os.*;
import android.os.Process;
import android.os.Process;
import android.util.ArrayMap;
import android.util.ArrayMap;
@@ -81,6 +82,9 @@ public class SystemConfig {
    // These are the app package names that should not allow IME switching.
    // These are the app package names that should not allow IME switching.
    final ArraySet<String> mFixedImeApps = new ArraySet<>();
    final ArraySet<String> mFixedImeApps = new ArraySet<>();


    final HashMap<Signature, HashSet<String>> mSignatureAllowances
            = new HashMap<Signature, HashSet<String>>();

    public static SystemConfig getInstance() {
    public static SystemConfig getInstance() {
        synchronized (SystemConfig.class) {
        synchronized (SystemConfig.class) {
            if (sInstance == null) {
            if (sInstance == null) {
@@ -118,6 +122,10 @@ public class SystemConfig {
        return mFixedImeApps;
        return mFixedImeApps;
    }
    }


    public HashMap<Signature, HashSet<String>> getSignatureAllowances() {
        return mSignatureAllowances;
    }

    SystemConfig() {
    SystemConfig() {
        // Read configuration from system
        // Read configuration from system
        readPermissions(Environment.buildPath(
        readPermissions(Environment.buildPath(
@@ -260,6 +268,43 @@ public class SystemConfig {
                    perms.add(perm);
                    perms.add(perm);
                    XmlUtils.skipCurrentTag(parser);
                    XmlUtils.skipCurrentTag(parser);


                } else if ("allow-permission".equals(name)) {
                    String perm = parser.getAttributeValue(null, "name");
                    if (perm == null) {
                        Slog.w(TAG,
                                "<allow-permission> without name at "
                                        + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    String signature = parser.getAttributeValue(null, "signature");
                    if (signature == null) {
                        Slog.w(TAG,
                                "<allow-permission> without signature at "
                                        + parser.getPositionDescription());
                        XmlUtils.skipCurrentTag(parser);
                        continue;
                    }
                    Signature sig = null;
                    try {
                        sig = new Signature(signature);
                    } catch (IllegalArgumentException e) {
                        // sig will be null so we will log it below
                    }
                    if (sig != null) {
                        HashSet<String> perms = mSignatureAllowances.get(sig);
                        if (perms == null) {
                            perms = new HashSet<String>();
                            mSignatureAllowances.put(sig, perms);
                        }
                        perms.add(perm);
                    } else {
                        Slog.w(TAG,
                                "<allow-permission> with bad signature at "
                                        + parser.getPositionDescription());
                    }
                    XmlUtils.skipCurrentTag(parser);

                } else if ("library".equals(name) && !onlyFeatures) {
                } else if ("library".equals(name) && !onlyFeatures) {
                    String lname = parser.getAttributeValue(null, "name");
                    String lname = parser.getAttributeValue(null, "name");
                    String lfile = parser.getAttributeValue(null, "file");
                    String lfile = parser.getAttributeValue(null, "file");
+15 −2
Original line number Original line Diff line number Diff line
@@ -409,6 +409,7 @@ public class PackageManagerService extends IPackageManager.Stub {
    final int[] mGlobalGids;
    final int[] mGlobalGids;
    final SparseArray<HashSet<String>> mSystemPermissions;
    final SparseArray<HashSet<String>> mSystemPermissions;
    final HashMap<String, FeatureInfo> mAvailableFeatures;
    final HashMap<String, FeatureInfo> mAvailableFeatures;
    final HashMap<Signature, HashSet<String>> mSignatureAllowances;
    // If mac_permissions.xml was found for seinfo labeling.
    // If mac_permissions.xml was found for seinfo labeling.
    boolean mFoundPolicyFile;
    boolean mFoundPolicyFile;
@@ -1376,6 +1377,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        mGlobalGids = systemConfig.getGlobalGids();
        mGlobalGids = systemConfig.getGlobalGids();
        mSystemPermissions = systemConfig.getSystemPermissions();
        mSystemPermissions = systemConfig.getSystemPermissions();
        mAvailableFeatures = systemConfig.getAvailableFeatures();
        mAvailableFeatures = systemConfig.getAvailableFeatures();
        mSignatureAllowances = systemConfig.getSignatureAllowances();
        synchronized (mInstallLock) {
        synchronized (mInstallLock) {
        // writer
        // writer
@@ -2681,6 +2683,16 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
        }
    }
    }
    private boolean isAllowedSignature(PackageParser.Package pkg, String permissionName) {
        for (Signature pkgSig : pkg.mSignatures) {
            HashSet<String> perms = mSignatureAllowances.get(pkgSig);
            if (perms != null && perms.contains(permissionName)) {
                return true;
            }
        }
        return false;
    }
    @Override
    @Override
    public void grantPermission(String packageName, String permissionName) {
    public void grantPermission(String packageName, String permissionName) {
        mContext.enforceCallingOrSelfPermission(
        mContext.enforceCallingOrSelfPermission(
@@ -7256,7 +7268,8 @@ public class PackageManagerService extends IPackageManager.Stub {
                        == PackageManager.SIGNATURE_MATCH);
                        == PackageManager.SIGNATURE_MATCH);
        if (!allowed && (bp.protectionLevel
        if (!allowed && (bp.protectionLevel
                & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
                & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
            if (isSystemApp(pkg)) {
            boolean allowedSig = isAllowedSignature(pkg, perm);
            if (isSystemApp(pkg) || allowedSig) {
                // For updated system applications, a system permission
                // For updated system applications, a system permission
                // is granted only if it had been defined by the original application.
                // is granted only if it had been defined by the original application.
                if (isUpdatedSystemApp(pkg)) {
                if (isUpdatedSystemApp(pkg)) {
@@ -7291,7 +7304,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                        }
                        }
                    }
                    }
                } else {
                } else {
                    allowed = isPrivilegedApp(pkg);
                    allowed = isPrivilegedApp(pkg) || allowedSig;
                }
                }
            }
            }
        }
        }