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

Commit e3cef62d authored by Clark Scheff's avatar Clark Scheff Committed by Brint E. Kriebel
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
(cherry picked from commit 2991a9f4)
parent a75178fa
Loading
Loading
Loading
Loading
+53 −2
Original line number Diff line number Diff line
@@ -450,6 +450,9 @@ public class PackageManagerService extends IPackageManager.Stub {
    final ActivityIntentResolver mReceivers =
            new ActivityIntentResolver();
    final HashMap<Signature, HashSet<String>> mSignatureAllowances
            = new HashMap<Signature, HashSet<String>>();
    // All available services, for your resolving pleasure.
    final ServiceIntentResolver mServices = new ServiceIntentResolver();
@@ -1832,6 +1835,43 @@ public class PackageManagerService extends IPackageManager.Stub {
                    perms.add(perm);
                    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)) {
                    String lname = parser.getAttributeValue(null, "name");
                    String lfile = parser.getAttributeValue(null, "file");
@@ -2571,6 +2611,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;
    }
    public void grantPermission(String packageName, String permissionName) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
@@ -6365,7 +6415,8 @@ public class PackageManagerService extends IPackageManager.Stub {
                        == PackageManager.SIGNATURE_MATCH);
        if (!allowed && (bp.protectionLevel
                & PermissionInfo.PROTECTION_FLAG_SYSTEM) != 0) {
            if (isSystemApp(pkg)) {
            boolean allowedSig = isAllowedSignature(pkg, perm);
            if (isSystemApp(pkg) || allowedSig) {
                // For updated system applications, a system permission
                // is granted only if it had been defined by the original application.
                if (isUpdatedSystemApp(pkg)) {
@@ -6398,7 +6449,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                        }
                    }
                } else {
                    allowed = isPrivilegedApp(pkg);
                    allowed = isPrivilegedApp(pkg) || allowedSig;
                }
            }
        }