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

Commit 3ed145f4 authored by dcashman's avatar dcashman Committed by Android (Google) Code Review
Browse files

Merge "Remove KeySetManagerService lock."

parents 2ecfcd9b d79fdf1c
Loading
Loading
Loading
Loading
+203 −243
Original line number Diff line number Diff line
@@ -52,13 +52,11 @@ public class KeySetManagerService {
    /** Sentinel value returned when public key is not found. */
    protected static final long PUBLIC_KEY_NOT_FOUND = -1;

    private final Object mLockObject = new Object();

    private final LongSparseArray<KeySet> mKeySets;

    private final LongSparseArray<PublicKey> mPublicKeys;

    protected final LongSparseArray<Set<Long>> mKeySetMapping;
    protected final LongSparseArray<ArraySet<Long>> mKeySetMapping;

    private final Map<String, PackageSetting> mPackages;

@@ -69,7 +67,7 @@ public class KeySetManagerService {
    public KeySetManagerService(Map<String, PackageSetting> packages) {
        mKeySets = new LongSparseArray<KeySet>();
        mPublicKeys = new LongSparseArray<PublicKey>();
        mKeySetMapping = new LongSparseArray<Set<Long>>();
        mKeySetMapping = new LongSparseArray<ArraySet<Long>>();
        mPackages = packages;
    }

@@ -84,8 +82,7 @@ public class KeySetManagerService {
     *
     * Note that this can return true for multiple KeySets.
     */
    public boolean packageIsSignedBy(String packageName, KeySet ks) {
        synchronized (mLockObject) {
    public boolean packageIsSignedByLPr(String packageName, KeySet ks) {
        PackageSetting pkg = mPackages.get(packageName);
        if (pkg == null) {
            throw new NullPointerException("Invalid package name");
@@ -93,67 +90,61 @@ public class KeySetManagerService {
        if (pkg.keySetData == null) {
            throw new NullPointerException("Package has no KeySet data");
        }
            long id = getIdByKeySetLocked(ks);
        long id = getIdByKeySetLPr(ks);
        return pkg.keySetData.packageIsSignedBy(id);
    }
    }

    /**
     * This informs the system that the given package has defined a KeySet
     * in its manifest that a) contains the given keys and b) is named
     * alias by that package.
     */
    public void addDefinedKeySetToPackage(String packageName,
    public void addDefinedKeySetToPackageLPw(String packageName,
            Set<PublicKey> keys, String alias) {
        if ((packageName == null) || (keys == null) || (alias == null)) {
            Slog.w(TAG, "Got null argument for a defined keyset, ignoring!");
            return;
        }
        synchronized (mLockObject) {
        PackageSetting pkg = mPackages.get(packageName);
        if (pkg == null) {
            throw new NullPointerException("Unknown package");
        }
        // Add to KeySets, then to package
            KeySet ks = addKeySetLocked(keys);
            long id = getIdByKeySetLocked(ks);
        KeySet ks = addKeySetLPw(keys);
        long id = getIdByKeySetLPr(ks);
        pkg.keySetData.addDefinedKeySet(id, alias);
    }
    }

    /**
     * This informs the system that the given package has defined a KeySet
     * alias in its manifest to be an upgradeKeySet.  This must be called
     * after all of the defined KeySets have been added.
     */
    public void addUpgradeKeySetToPackage(String packageName, String alias) {
    public void addUpgradeKeySetToPackageLPw(String packageName, String alias) {
        if ((packageName == null) || (alias == null)) {
            Slog.w(TAG, "Got null argument for a defined keyset, ignoring!");
            return;
        }
        synchronized (mLockObject) {
        PackageSetting pkg = mPackages.get(packageName);
        if (pkg == null) {
            throw new NullPointerException("Unknown package");
        }
        pkg.keySetData.addUpgradeKeySet(alias);
    }
    }

    /**
     * Similar to the above, this informs the system that the given package
     * was signed by the provided KeySet.
     */
    public void addSigningKeySetToPackage(String packageName,
    public void addSigningKeySetToPackageLPw(String packageName,
            Set<PublicKey> signingKeys) {
        if ((packageName == null) || (signingKeys == null)) {
            Slog.w(TAG, "Got null argument for a signing keyset, ignoring!");
            return;
        }
        synchronized (mLockObject) {
        // add the signing KeySet
            KeySet ks = addKeySetLocked(signingKeys);
            long id = getIdByKeySetLocked(ks);
        KeySet ks = addKeySetLPw(signingKeys);
        long id = getIdByKeySetLPr(ks);
        Set<Long> publicKeyIds = mKeySetMapping.get(id);
        if (publicKeyIds == null) {
            throw new NullPointerException("Got invalid KeySet id");
@@ -175,19 +166,12 @@ public class KeySetManagerService {
            }
        }
    }
    }

    /**
     * Fetches the stable identifier associated with the given KeySet. Returns
     * {@link #KEYSET_NOT_FOUND} if the KeySet... wasn't found.
     */
    public long getIdByKeySet(KeySet ks) {
        synchronized (mLockObject) {
            return getIdByKeySetLocked(ks);
        }
    }

    private long getIdByKeySetLocked(KeySet ks) {
    private long getIdByKeySetLPr(KeySet ks) {
        for (int keySetIndex = 0; keySetIndex < mKeySets.size(); keySetIndex++) {
            KeySet value = mKeySets.valueAt(keySetIndex);
            if (ks.equals(value)) {
@@ -203,11 +187,9 @@ public class KeySetManagerService {
     * Returns {@link #KEYSET_NOT_FOUND} if the identifier doesn't
     * identify a {@link KeySet}.
     */
    public KeySet getKeySetById(long id) {
        synchronized (mLockObject) {
    public KeySet getKeySetByIdLPr(long id) {
        return mKeySets.get(id);
    }
    }

    /**
     * Fetches the {@link KeySet} that a given package refers to by the provided alias.
@@ -215,8 +197,7 @@ public class KeySetManagerService {
     * @throws IllegalArgumentException if the package has no keyset data.
     * @throws NullPointerException if the package is unknown.
     */
    public KeySet getKeySetByAliasAndPackageName(String packageName, String alias) {
        synchronized (mLockObject) {
    public KeySet getKeySetByAliasAndPackageNameLPr(String packageName, String alias) {
        PackageSetting p = mPackages.get(packageName);
        if (p == null) {
            throw new NullPointerException("Unknown package");
@@ -227,7 +208,6 @@ public class KeySetManagerService {
        long keySetId = p.keySetData.getAliases().get(alias);
        return mKeySets.get(keySetId);
    }
    }

    /**
     * Fetches the {@link PublicKey public keys} which belong to the specified
@@ -236,8 +216,7 @@ public class KeySetManagerService {
     * Returns {@code null} if the identifier doesn't
     * identify a {@link KeySet}.
     */
    public ArraySet<PublicKey> getPublicKeysFromKeySet(long id) {
        synchronized (mLockObject) {
    public ArraySet<PublicKey> getPublicKeysFromKeySetLPr(long id) {
        if(mKeySetMapping.get(id) == null) {
            return null;
        }
@@ -247,7 +226,6 @@ public class KeySetManagerService {
        }
        return mPubKeys;
    }
    }

    /**
     * Fetches all the known {@link KeySet KeySets} that signed the given
@@ -256,8 +234,7 @@ public class KeySetManagerService {
     * @throws IllegalArgumentException if the package has no keyset data.
     * @throws NullPointerException if the package is unknown.
     */
    public Set<KeySet> getSigningKeySetsByPackageName(String packageName) {
        synchronized (mLockObject) {
    public Set<KeySet> getSigningKeySetsByPackageNameLPr(String packageName) {
        Set<KeySet> signingKeySets = new ArraySet<KeySet>();
        PackageSetting p = mPackages.get(packageName);
        if (p == null) {
@@ -271,7 +248,6 @@ public class KeySetManagerService {
        }
        return signingKeySets;
    }
    }

    /**
     * Fetches all the known {@link KeySet KeySets} that may upgrade the given
@@ -280,8 +256,7 @@ public class KeySetManagerService {
     * @throws IllegalArgumentException if the package has no keyset data.
     * @throws NullPointerException if the package is unknown.
     */
    public ArraySet<KeySet> getUpgradeKeySetsByPackageName(String packageName) {
        synchronized (mLockObject) {
    public ArraySet<KeySet> getUpgradeKeySetsByPackageNameLPr(String packageName) {
        ArraySet<KeySet> upgradeKeySets = new ArraySet<KeySet>();
        PackageSetting p = mPackages.get(packageName);
        if (p == null) {
@@ -297,7 +272,6 @@ public class KeySetManagerService {
        }
        return upgradeKeySets;
    }
    }

    /**
     * Creates a new KeySet corresponding to the given keys.
@@ -313,19 +287,19 @@ public class KeySetManagerService {
     *
     * Throws if the provided set is {@code null}.
     */
    private KeySet addKeySetLocked(Set<PublicKey> keys) {
    private KeySet addKeySetLPw(Set<PublicKey> keys) {
        if (keys == null) {
            throw new NullPointerException("Provided keys cannot be null");
        }
        // add each of the keys in the provided set
        Set<Long> addedKeyIds = new ArraySet<Long>(keys.size());
        ArraySet<Long> addedKeyIds = new ArraySet<Long>(keys.size());
        for (PublicKey k : keys) {
            long id = addPublicKeyLocked(k);
            long id = addPublicKeyLPw(k);
            addedKeyIds.add(id);
        }

        // check to see if the resulting keyset is new
        long existingKeySetId = getIdFromKeyIdsLocked(addedKeyIds);
        long existingKeySetId = getIdFromKeyIdsLPr(addedKeyIds);
        if (existingKeySetId != KEYSET_NOT_FOUND) {
            return mKeySets.get(existingKeySetId);
        }
@@ -333,7 +307,7 @@ public class KeySetManagerService {
        // create the KeySet object
        KeySet ks = new KeySet(new Binder());
        // get the first unoccupied slot in mKeySets
        long id = getFreeKeySetIDLocked();
        long id = getFreeKeySetIDLPw();
        // add the KeySet object to it
        mKeySets.put(id, ks);
        // add the stable key ids to the mapping
@@ -358,14 +332,14 @@ public class KeySetManagerService {
    /**
     * Adds the given PublicKey to the system, deduping as it goes.
     */
    private long addPublicKeyLocked(PublicKey key) {
    private long addPublicKeyLPw(PublicKey key) {
        // check if the public key is new
        long existingKeyId = getIdForPublicKeyLocked(key);
        long existingKeyId = getIdForPublicKeyLPr(key);
        if (existingKeyId != PUBLIC_KEY_NOT_FOUND) {
            return existingKeyId;
        }
        // if it's new find the first unoccupied slot in the public keys
        long id = getFreePublicKeyIdLocked();
        long id = getFreePublicKeyIdLPw();
        // add the public key to it
        mPublicKeys.put(id, key);
        // return the stable identifier
@@ -377,7 +351,7 @@ public class KeySetManagerService {
     *
     * Returns KEYSET_NOT_FOUND if there isn't one.
     */
    private long getIdFromKeyIdsLocked(Set<Long> publicKeyIds) {
    private long getIdFromKeyIdsLPr(Set<Long> publicKeyIds) {
        for (int keyMapIndex = 0; keyMapIndex < mKeySetMapping.size(); keyMapIndex++) {
            Set<Long> value = mKeySetMapping.valueAt(keyMapIndex);
            if (value.equals(publicKeyIds)) {
@@ -390,16 +364,7 @@ public class KeySetManagerService {
    /**
     * Finds the stable identifier for a PublicKey or PUBLIC_KEY_NOT_FOUND.
     */
    protected long getIdForPublicKey(PublicKey k) {
        synchronized (mLockObject) {
            return getIdForPublicKeyLocked(k);
        }
    }

    /**
     * Finds the stable identifier for a PublicKey or PUBLIC_KEY_NOT_FOUND.
     */
    private long getIdForPublicKeyLocked(PublicKey k) {
    private long getIdForPublicKeyLPr(PublicKey k) {
        String encodedPublicKey = new String(k.getEncoded());
        for (int publicKeyIndex = 0; publicKeyIndex < mPublicKeys.size(); publicKeyIndex++) {
            PublicKey value = mPublicKeys.valueAt(publicKeyIndex);
@@ -414,7 +379,7 @@ public class KeySetManagerService {
    /**
     * Gets an unused stable identifier for a KeySet.
     */
    private long getFreeKeySetIDLocked() {
    private long getFreeKeySetIDLPw() {
        lastIssuedKeySetId += 1;
        return lastIssuedKeySetId;
    }
@@ -422,17 +387,16 @@ public class KeySetManagerService {
    /**
     * Same as above, but for public keys.
     */
    private long getFreePublicKeyIdLocked() {
    private long getFreePublicKeyIdLPw() {
        lastIssuedKeyId += 1;
        return lastIssuedKeyId;
    }

    public void removeAppKeySetData(String packageName) {
        synchronized (mLockObject) {
    public void removeAppKeySetDataLPw(String packageName) {
        // Get the package's known keys and KeySets
            Set<Long> deletableKeySets = getOriginalKeySetsByPackageNameLocked(packageName);
            Set<Long> deletableKeys = new ArraySet<Long>();
            Set<Long> knownKeys = null;
        ArraySet<Long> deletableKeySets = getOriginalKeySetsByPackageNameLPr(packageName);
        ArraySet<Long> deletableKeys = new ArraySet<Long>();
        ArraySet<Long> knownKeys = null;
        for (Long ks : deletableKeySets) {
            knownKeys = mKeySetMapping.get(ks);
            if (knownKeys != null) {
@@ -445,7 +409,7 @@ public class KeySetManagerService {
            if (pkgName.equals(packageName)) {
                continue;
            }
                Set<Long> knownKeySets = getOriginalKeySetsByPackageNameLocked(pkgName);
            ArraySet<Long> knownKeySets = getOriginalKeySetsByPackageNameLPr(pkgName);
            deletableKeySets.removeAll(knownKeySets);
            knownKeys = new ArraySet<Long>();
            for (Long ks : knownKeySets) {
@@ -473,21 +437,19 @@ public class KeySetManagerService {
                p.keySetData.removeSigningKeySet(ks);
            }
        }

        // Finally, remove all KeySets from the original package
        PackageSetting p = mPackages.get(packageName);
            clearPackageKeySetDataLocked(p);
        }
        clearPackageKeySetDataLPw(p);
    }

    private void clearPackageKeySetDataLocked(PackageSetting p) {
    private void clearPackageKeySetDataLPw(PackageSetting p) {
        p.keySetData.removeAllSigningKeySets();
        p.keySetData.removeAllUpgradeKeySets();
        p.keySetData.removeAllDefinedKeySets();
        return;
    }

    private Set<Long> getOriginalKeySetsByPackageNameLocked(String packageName) {
    private ArraySet<Long> getOriginalKeySetsByPackageNameLPr(String packageName) {
        PackageSetting p = mPackages.get(packageName);
        if (p == null) {
            throw new NullPointerException("Unknown package");
@@ -495,7 +457,7 @@ public class KeySetManagerService {
        if (p.keySetData == null) {
            throw new IllegalArgumentException("Package has no keySet data");
        }
        Set<Long> knownKeySets = new ArraySet<Long>();
        ArraySet<Long> knownKeySets = new ArraySet<Long>();
        knownKeySets.add(p.keySetData.getProperSigningKeySet());
        if (p.keySetData.isUsingDefinedKeySets()) {
            for (long ks : p.keySetData.getDefinedKeySets()) {
@@ -509,9 +471,8 @@ public class KeySetManagerService {
        return new String(Base64.encode(k.getEncoded(), 0));
    }

    public void dump(PrintWriter pw, String packageName,
    public void dumpLPr(PrintWriter pw, String packageName,
                        PackageManagerService.DumpState dumpState) {
        synchronized (mLockObject) {
        boolean printedHeader = false;
        for (Map.Entry<String, PackageSetting> e : mPackages.entrySet()) {
            String keySetPackage = e.getKey();
@@ -588,7 +549,6 @@ public class KeySetManagerService {
            }
        }
    }
    }

    void writeKeySetManagerServiceLPr(XmlSerializer serializer) throws IOException {
        serializer.startTag(null, "keyset-settings");
@@ -651,7 +611,7 @@ public class KeySetManagerService {
            // The KeySet information read previously from packages.xml is invalid.
            // Destroy it all.
            for (PackageSetting p : mPackages.values()) {
                clearPackageKeySetDataLocked(p);
                clearPackageKeySetDataLPw(p);
            }
            return;
        }
+14 −15
Original line number Diff line number Diff line
@@ -2815,7 +2815,9 @@ public class PackageManagerService extends IPackageManager.Stub {
            // Migrate the old signatures to the new scheme.
            existingSigs.assignSignatures(scannedPkg.mSignatures);
            // The new KeySets will be re-added later in the scanning process.
            mSettings.mKeySetManagerService.removeAppKeySetData(scannedPkg.packageName);
            synchronized (mPackages) {
                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
            }
            return PackageManager.SIGNATURE_MATCH;
        }
        return PackageManager.SIGNATURE_NO_MATCH;
@@ -4145,7 +4147,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                // if the package appears to be unchanged.
                pkg.mSignatures = ps.signatures.mSignatures;
                KeySetManagerService ksms = mSettings.mKeySetManagerService;
                pkg.mSigningKeys = ksms.getPublicKeysFromKeySet(mSigningKeySetId);
                synchronized (mPackages) {
                    pkg.mSigningKeys = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
                }
                return true;
            }
@@ -5704,19 +5708,19 @@ public class PackageManagerService extends IPackageManager.Stub {
            KeySetManagerService ksms = mSettings.mKeySetManagerService;
            try {
                // Old KeySetData no longer valid.
                ksms.removeAppKeySetData(pkg.packageName);
                ksms.addSigningKeySetToPackage(pkg.packageName, pkg.mSigningKeys);
                ksms.removeAppKeySetDataLPw(pkg.packageName);
                ksms.addSigningKeySetToPackageLPw(pkg.packageName, pkg.mSigningKeys);
                if (pkg.mKeySetMapping != null) {
                    for (Map.Entry<String, ArraySet<PublicKey>> entry :
                            pkg.mKeySetMapping.entrySet()) {
                        if (entry.getValue() != null) {
                            ksms.addDefinedKeySetToPackage(pkg.packageName,
                            ksms.addDefinedKeySetToPackageLPw(pkg.packageName,
                                                          entry.getValue(), entry.getKey());
                        }
                    }
                    if (pkg.mUpgradeKeySets != null) {
                        for (String upgradeAlias : pkg.mUpgradeKeySets) {
                            ksms.addUpgradeKeySetToPackage(pkg.packageName, upgradeAlias);
                            ksms.addUpgradeKeySetToPackageLPw(pkg.packageName, upgradeAlias);
                        }
                    }
                }
@@ -9906,14 +9910,9 @@ public class PackageManagerService extends IPackageManager.Stub {
        // required keys.
        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
        KeySetManagerService ksms = mSettings.mKeySetManagerService;
        Set<Long> newSigningKeyIds = new ArraySet<Long>();
        for (PublicKey pk : newPkg.mSigningKeys) {
            newSigningKeyIds.add(ksms.getIdForPublicKey(pk));
        }
        //remove PUBLIC_KEY_NOT_FOUND, although not necessary
        newSigningKeyIds.remove(ksms.PUBLIC_KEY_NOT_FOUND);
        for (int i = 0; i < upgradeKeySets.length; i++) {
            if (newSigningKeyIds.containsAll(ksms.mKeySetMapping.get(upgradeKeySets[i]))) {
            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
            if (newPkg.mSigningKeys.containsAll(upgradeSet)) {
                return true;
            }
        }
@@ -10707,7 +10706,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            if (deletedPs != null) {
                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
                    if (outInfo != null) {
                        mSettings.mKeySetManagerService.removeAppKeySetData(packageName);
                        mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
                        outInfo.removedAppId = mSettings.removePackageLPw(packageName);
                    }
                    if (deletedPs != null) {
@@ -12383,7 +12382,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
                mSettings.mKeySetManagerService.dump(pw, packageName, dumpState);
                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
            }
            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {