diff options
19 files changed, 147 insertions, 72 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index 9bcbd720358a..f0c01eea9307 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -39578,7 +39578,7 @@ package android.security.keystore { method @Nullable public java.util.Date getKeyValidityStart(); method @NonNull public String getKeystoreAlias(); method public int getMaxUsageCount(); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public java.util.Set<java.lang.String> getMgf1Digests(); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public java.util.Set<java.lang.String> getMgf1Digests(); method public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationType(); @@ -39586,7 +39586,7 @@ package android.security.keystore { method public boolean isDevicePropertiesAttestationIncluded(); method @NonNull public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public boolean isMgf1DigestsSpecified(); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public boolean isMgf1DigestsSpecified(); method public boolean isRandomizedEncryptionRequired(); method public boolean isStrongBoxBacked(); method public boolean isUnlockedDeviceRequired(); @@ -39618,7 +39618,7 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityForOriginationEnd(java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setKeyValidityStart(java.util.Date); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMaxUsageCount(int); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMgf1Digests(@NonNull java.lang.String...); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setMgf1Digests(@NonNull java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setRandomizedEncryptionRequired(boolean); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setSignaturePaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyGenParameterSpec.Builder setUnlockedDeviceRequired(boolean); @@ -39723,14 +39723,14 @@ package android.security.keystore { method @Nullable public java.util.Date getKeyValidityForOriginationEnd(); method @Nullable public java.util.Date getKeyValidityStart(); method public int getMaxUsageCount(); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public java.util.Set<java.lang.String> getMgf1Digests(); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public java.util.Set<java.lang.String> getMgf1Digests(); method public int getPurposes(); method @NonNull public String[] getSignaturePaddings(); method public int getUserAuthenticationType(); method public int getUserAuthenticationValidityDurationSeconds(); method public boolean isDigestsSpecified(); method public boolean isInvalidatedByBiometricEnrollment(); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public boolean isMgf1DigestsSpecified(); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public boolean isMgf1DigestsSpecified(); method public boolean isRandomizedEncryptionRequired(); method public boolean isUnlockedDeviceRequired(); method public boolean isUserAuthenticationRequired(); @@ -39752,7 +39752,7 @@ package android.security.keystore { method @NonNull public android.security.keystore.KeyProtection.Builder setKeyValidityForOriginationEnd(java.util.Date); method @NonNull public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date); method @NonNull public android.security.keystore.KeyProtection.Builder setMaxUsageCount(int); - method @FlaggedApi("MGF1_DIGEST_SETTER") @NonNull public android.security.keystore.KeyProtection.Builder setMgf1Digests(@Nullable java.lang.String...); + method @FlaggedApi("android.security.mgf1_digest_setter") @NonNull public android.security.keystore.KeyProtection.Builder setMgf1Digests(@Nullable java.lang.String...); method @NonNull public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean); method @NonNull public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...); method @NonNull public android.security.keystore.KeyProtection.Builder setUnlockedDeviceRequired(boolean); diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 8e72e13051b0..fa42fed75e56 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -1729,23 +1729,6 @@ public class StorageManager { return RoSystemProperties.CRYPTO_FILE_ENCRYPTED; } - /** {@hide} - * @deprecated Use {@link #isFileEncrypted} instead, since emulated FBE is no longer supported. - */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @Deprecated - public static boolean isFileEncryptedNativeOnly() { - return isFileEncrypted(); - } - - /** {@hide} - * @deprecated Use {@link #isFileEncrypted} instead, since emulated FBE is no longer supported. - */ - @Deprecated - public static boolean isFileEncryptedNativeOrEmulated() { - return isFileEncrypted(); - } - /** {@hide} */ public static boolean hasAdoptable() { switch (SystemProperties.get(PROP_ADOPTABLE)) { diff --git a/core/java/android/security/OWNERS b/core/java/android/security/OWNERS index 33a67aed6023..533d459e532b 100644 --- a/core/java/android/security/OWNERS +++ b/core/java/android/security/OWNERS @@ -8,4 +8,4 @@ per-file *NetworkSecurityPolicy.java = file:net/OWNERS per-file Confirmation*.java = file:/keystore/OWNERS per-file FileIntegrityManager.java = file:platform/system/security:/fsverity/OWNERS per-file IFileIntegrityService.aidl = file:platform/system/security:/fsverity/OWNERS -per-file *.aconfig = victorhsieh@google.com +per-file *.aconfig = victorhsieh@google.com,eranm@google.com diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index 5aa309753cc4..13612f60bf4b 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -8,7 +8,14 @@ flag { } flag { - name: "fix_unlocked_device_required_keys" + name: "mgf1_digest_setter" + namespace: "hardware_backed_security" + description: "Feature flag for mgf1 digest setter in key generation and import parameters." + bug: "308378912" +} + +flag { + name: "fix_unlocked_device_required_keys_v2" namespace: "hardware_backed_security" description: "Fix bugs in behavior of UnlockedDeviceRequired keystore keys" bug: "296464083" diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java index 231fa4837441..4982f3732089 100644 --- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java +++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java @@ -618,7 +618,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * @see #isMgf1DigestsSpecified() */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public @KeyProperties.DigestEnum Set<String> getMgf1Digests() { if (mMgf1Digests.isEmpty()) { throw new IllegalStateException("Mask generation function (MGF) not specified"); @@ -633,7 +633,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * @see #getMgf1Digests() */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public boolean isMgf1DigestsSpecified() { return !mMgf1Digests.isEmpty(); } @@ -1292,7 +1292,7 @@ public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAu * <p>See {@link KeyProperties}.{@code DIGEST} constants. */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public Builder setMgf1Digests(@NonNull @KeyProperties.DigestEnum String... mgf1Digests) { mMgf1Digests = Set.of(mgf1Digests); return this; diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java index c1e3bab5d37c..7b6b2d142f95 100644 --- a/keystore/java/android/security/keystore/KeyProtection.java +++ b/keystore/java/android/security/keystore/KeyProtection.java @@ -401,7 +401,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { * @see #isMgf1DigestsSpecified() */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public @KeyProperties.DigestEnum Set<String> getMgf1Digests() { if (mMgf1Digests.isEmpty()) { throw new IllegalStateException("Mask generation function (MGF) not specified"); @@ -416,7 +416,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { * @see #getMgf1Digests() */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public boolean isMgf1DigestsSpecified() { return !mMgf1Digests.isEmpty(); } @@ -799,7 +799,7 @@ public final class KeyProtection implements ProtectionParameter, UserAuthArgs { * <p>See {@link KeyProperties}.{@code DIGEST} constants. */ @NonNull - @FlaggedApi("MGF1_DIGEST_SETTER") + @FlaggedApi(android.security.Flags.FLAG_MGF1_DIGEST_SETTER) public Builder setMgf1Digests(@Nullable @KeyProperties.DigestEnum String... mgf1Digests) { mMgf1Digests = Set.of(mgf1Digests); return this; diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java index ed4b485f3927..02efc2f3539d 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -28,6 +28,7 @@ import android.hardware.security.keymint.SecurityLevel; import android.hardware.security.keymint.Tag; import android.os.Build; import android.os.StrictMode; +import android.security.Flags; import android.security.KeyPairGeneratorSpec; import android.security.KeyStore2; import android.security.KeyStoreException; @@ -853,6 +854,22 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, mgf1Digest )); }); + + /* If the MGF1 Digest setter is not set, fall back to the previous behaviour: + * Add, as MGF1 Digest function, all the primary digests. + * Avoid adding the default MGF1 digest as it will have been included in the + * mKeymasterMgf1Digests field. + */ + if (!Flags.mgf1DigestSetter()) { + final int defaultMgf1Digest = KeyProperties.Digest.toKeymaster( + DEFAULT_MGF1_DIGEST); + ArrayUtils.forEach(mKeymasterDigests, (digest) -> { + if (digest != defaultMgf1Digest) { + params.add(KeyStore2ParameterUtils.makeEnum( + KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, digest)); + } + }); + } } }); ArrayUtils.forEach(mKeymasterSignaturePaddings, (padding) -> { diff --git a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java index ddbd93e458fd..4f65884138bd 100644 --- a/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java +++ b/keystore/java/android/security/keystore2/AndroidKeyStoreSpi.java @@ -25,6 +25,7 @@ import android.hardware.security.keymint.HardwareAuthenticatorType; import android.hardware.security.keymint.KeyParameter; import android.hardware.security.keymint.SecurityLevel; import android.os.StrictMode; +import android.security.Flags; import android.security.GateKeeper; import android.security.KeyStore2; import android.security.KeyStoreParameter; @@ -537,11 +538,31 @@ public class AndroidKeyStoreSpi extends KeyStoreSpi { /* Because of default MGF1 digest is SHA-1. It has to be added in Key * characteristics. Otherwise, crypto operations will fail with Incompatible * MGF1 digest. + * If the MGF1 Digest setter flag isn't set, then the condition in the + * if clause above must be false (cannot have MGF1 digests specified if the + * flag was off). In that case, in addition to adding the default MGF1 + * digest, we have to add all the other digests as MGF1 Digests. + * */ importArgs.add(KeyStore2ParameterUtils.makeEnum( KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, KeyProperties.Digest.toKeymaster(DEFAULT_MGF1_DIGEST) )); + if (!Flags.mgf1DigestSetter()) { + final int defaultMgf1Digest = KeyProperties.Digest.toKeymaster( + DEFAULT_MGF1_DIGEST); + for (String digest : spec.getDigests()) { + int digestToAddAsMgf1Digest = KeyProperties.Digest.toKeymaster( + digest); + // Do not add the default MGF1 digest as it has been added above. + if (digestToAddAsMgf1Digest != defaultMgf1Digest) { + importArgs.add(KeyStore2ParameterUtils.makeEnum( + KeymasterDefs.KM_TAG_RSA_OAEP_MGF_DIGEST, + digestToAddAsMgf1Digest + )); + } + } + } } } } diff --git a/libs/hwui/Mesh.cpp b/libs/hwui/Mesh.cpp index e59bc9565a59..37a7d74330e9 100644 --- a/libs/hwui/Mesh.cpp +++ b/libs/hwui/Mesh.cpp @@ -90,8 +90,8 @@ std::tuple<bool, SkString> Mesh::validate() { FAIL_MESH_VALIDATE("%s mode requires at least %zu vertices but vertex count is %zu.", modeToStr(meshMode), min_vcount_for_mode(meshMode), mVertexCount); } - SkASSERT(!fICount); - SkASSERT(!fIOffset); + LOG_ALWAYS_FATAL_IF(mIndexCount != 0); + LOG_ALWAYS_FATAL_IF(mIndexOffset != 0); } if (!sm.ok()) { diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 6794f750c82d..3280afdf6703 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -1797,8 +1797,13 @@ public class AdbDebuggingManager { mFingerprints); try { - dump.write("user_keys", AdbDebuggingManagerProto.USER_KEYS, - FileUtils.readTextFile(new File("/data/misc/adb/adb_keys"), 0, null)); + File userKeys = new File("/data/misc/adb/adb_keys"); + if (userKeys.exists()) { + dump.write("user_keys", AdbDebuggingManagerProto.USER_KEYS, + FileUtils.readTextFile(userKeys, 0, null)); + } else { + Slog.i(TAG, "No user keys on this device"); + } } catch (IOException e) { Slog.i(TAG, "Cannot read user keys", e); } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index ec7f561bd9da..b4c39972dcaa 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -246,7 +246,7 @@ public class LockSettingsService extends ILockSettings.Stub { private static final String MIGRATED_SP_FULL = "migrated_all_users_to_sp_and_bound_keys"; private static final boolean FIX_UNLOCKED_DEVICE_REQUIRED_KEYS = - android.security.Flags.fixUnlockedDeviceRequiredKeys(); + android.security.Flags.fixUnlockedDeviceRequiredKeysV2(); // Duration that LockSettingsService will store the gatekeeper password for. This allows // multiple biometric enrollments without prompting the user to enter their password via diff --git a/services/core/java/com/android/server/pm/DumpHelper.java b/services/core/java/com/android/server/pm/DumpHelper.java index fcaaa90dbc8a..c33af9b28b62 100644 --- a/services/core/java/com/android/server/pm/DumpHelper.java +++ b/services/core/java/com/android/server/pm/DumpHelper.java @@ -160,7 +160,7 @@ final class DumpHelper { pkg = snapshot.resolveInternalPackageName(pkg, PackageManager.VERSION_CODE_HIGHEST); - pw.println(mPermissionManager.checkPermission(perm, pkg, user)); + pw.println(mPermissionManager.checkPermission(pkg, perm, user)); return; } else if ("l".equals(cmd) || "libraries".equals(cmd)) { dumpState.setDump(DumpState.DUMP_LIBS); diff --git a/services/core/java/com/android/server/pm/UserDataPreparer.java b/services/core/java/com/android/server/pm/UserDataPreparer.java index 6d58d3401675..8adb5661ad1d 100644 --- a/services/core/java/com/android/server/pm/UserDataPreparer.java +++ b/services/core/java/com/android/server/pm/UserDataPreparer.java @@ -23,10 +23,10 @@ import android.content.pm.UserInfo; import android.os.Environment; import android.os.FileUtils; import android.os.RecoverySystem; -import android.os.storage.StorageManager; -import android.os.storage.VolumeInfo; import android.os.SystemProperties; import android.os.UserHandle; +import android.os.storage.StorageManager; +import android.os.storage.VolumeInfo; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; @@ -35,6 +35,7 @@ import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; +import com.android.server.utils.Slogf; import java.io.File; import java.io.IOException; @@ -43,7 +44,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Set; /** * Helper class for preparing and destroying user storage @@ -65,31 +65,37 @@ class UserDataPreparer { /** * Prepare storage areas for given user on all mounted devices. */ - void prepareUserData(int userId, int userSerial, int flags) { + void prepareUserData(UserInfo userInfo, int flags) { synchronized (mInstallLock) { final StorageManager storage = mContext.getSystemService(StorageManager.class); /* * Internal storage must be prepared before adoptable storage, since the user's volume * keys are stored in their internal storage. */ - prepareUserDataLI(null /* internal storage */, userId, userSerial, flags, true); + prepareUserDataLI(null /* internal storage */, userInfo, flags, true); for (VolumeInfo vol : storage.getWritablePrivateVolumes()) { final String volumeUuid = vol.getFsUuid(); if (volumeUuid != null) { - prepareUserDataLI(volumeUuid, userId, userSerial, flags, true); + prepareUserDataLI(volumeUuid, userInfo, flags, true); } } } } - private void prepareUserDataLI(String volumeUuid, int userId, int userSerial, int flags, + private void prepareUserDataLI(String volumeUuid, UserInfo userInfo, int flags, boolean allowRecover) { - // Prepare storage and verify that serial numbers are consistent; if - // there's a mismatch we need to destroy to avoid leaking data + final int userId = userInfo.id; + final int userSerial = userInfo.serialNumber; final StorageManager storage = mContext.getSystemService(StorageManager.class); + final boolean isNewUser = userInfo.lastLoggedInTime == 0; + Slogf.d(TAG, "Preparing user data; volumeUuid=%s, userId=%d, flags=0x%x, isNewUser=%s", + volumeUuid, userId, flags, isNewUser); try { + // Prepare CE and/or DE storage. storage.prepareUserStorage(volumeUuid, userId, userSerial, flags); + // Ensure that the data directories of a removed user with the same ID are not being + // reused. New users must get fresh data directories, to avoid leaking data. if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) { enforceSerialNumber(getDataUserDeDirectory(volumeUuid, userId), userSerial); if (Objects.equals(volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) { @@ -103,9 +109,10 @@ class UserDataPreparer { } } + // Prepare the app data directories. mInstaller.createUserData(volumeUuid, userId, userSerial, flags); - // CE storage is available after they are prepared. + // If applicable, record that the system user's CE storage has been prepared. if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && (userId == UserHandle.USER_SYSTEM)) { String propertyName = "sys.user." + userId + ".ce_available"; @@ -113,20 +120,31 @@ class UserDataPreparer { SystemProperties.set(propertyName, "true"); } } catch (Exception e) { - logCriticalInfo(Log.WARN, "Destroying user " + userId + " on volume " + volumeUuid - + " because we failed to prepare: " + e); - destroyUserDataLI(volumeUuid, userId, flags); - + // Failed to prepare user data. For new users, specifically users that haven't ever + // been unlocked, destroy the user data, and try again (if not already retried). This + // might be effective at resolving some errors, such as stale directories from a reused + // user ID. Don't auto-destroy data for existing users, since issues with existing + // users might be fixable via an OTA without having to wipe the user's data. + if (isNewUser) { + logCriticalInfo(Log.ERROR, "Destroying user " + userId + " on volume " + volumeUuid + + " because we failed to prepare: " + e); + destroyUserDataLI(volumeUuid, userId, flags); + } else { + logCriticalInfo(Log.ERROR, "Failed to prepare user " + userId + " on volume " + + volumeUuid + ": " + e); + } if (allowRecover) { // Try one last time; if we fail again we're really in trouble - prepareUserDataLI(volumeUuid, userId, userSerial, - flags | StorageManager.FLAG_STORAGE_DE, false); + prepareUserDataLI(volumeUuid, userInfo, flags | StorageManager.FLAG_STORAGE_DE, + false); } else { + // If internal storage of the system user fails to prepare on first boot, then + // things are *really* broken, so we might as well reboot to recovery right away. try { Log.wtf(TAG, "prepareUserData failed for user " + userId, e); - if (userId == UserHandle.USER_SYSTEM) { + if (isNewUser && userId == UserHandle.USER_SYSTEM && volumeUuid == null) { RecoverySystem.rebootPromptAndWipeUserData(mContext, - "prepareUserData failed for system user"); + "failed to prepare internal storage for system user"); } } catch (IOException e2) { throw new RuntimeException("error rebooting into recovery", e2); diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index e11e226054e3..68148482c68a 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -4914,8 +4914,7 @@ public class UserManagerService extends IUserManager.Stub { // unlocked. We do this to ensure that CE storage isn't prepared before the CE key is // saved to disk. This also matches what is done for user 0. t.traceBegin("prepareUserData"); - mUserDataPreparer.prepareUserData(userId, userInfo.serialNumber, - StorageManager.FLAG_STORAGE_DE); + mUserDataPreparer.prepareUserData(userInfo, StorageManager.FLAG_STORAGE_DE); t.traceEnd(); t.traceBegin("LSS.createNewUser"); @@ -6199,12 +6198,11 @@ public class UserManagerService extends IUserManager.Stub { } TimingsTraceAndSlog t = new TimingsTraceAndSlog(); t.traceBegin("onBeforeStartUser-" + userId); - final int userSerial = userInfo.serialNumber; // Migrate only if build fingerprints mismatch boolean migrateAppsData = !PackagePartitions.FINGERPRINT.equals( userInfo.lastLoggedInFingerprint); t.traceBegin("prepareUserData"); - mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_DE); + mUserDataPreparer.prepareUserData(userInfo, StorageManager.FLAG_STORAGE_DE); t.traceEnd(); t.traceBegin("reconcileAppsData"); getPackageManagerInternal().reconcileAppsData(userId, StorageManager.FLAG_STORAGE_DE, @@ -6230,14 +6228,13 @@ public class UserManagerService extends IUserManager.Stub { if (userInfo == null) { return; } - final int userSerial = userInfo.serialNumber; // Migrate only if build fingerprints mismatch boolean migrateAppsData = !PackagePartitions.FINGERPRINT.equals( userInfo.lastLoggedInFingerprint); final TimingsTraceAndSlog t = new TimingsTraceAndSlog(); t.traceBegin("prepareUserData-" + userId); - mUserDataPreparer.prepareUserData(userId, userSerial, StorageManager.FLAG_STORAGE_CE); + mUserDataPreparer.prepareUserData(userInfo, StorageManager.FLAG_STORAGE_CE); t.traceEnd(); StorageManagerInternal smInternal = LocalServices.getService(StorageManagerInternal.class); diff --git a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java index d0c346a63889..57f4a5ddb2bd 100644 --- a/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java +++ b/services/core/java/com/android/server/pm/dex/ArtStatsLogUtils.java @@ -337,7 +337,8 @@ public class ArtStatsLogUtils { 0, // deprecated, used to be durationIncludingSleepMs 0, // optimizedPackagesCount 0, // packagesDependingOnBootClasspathCount - 0); // totalPackagesCount + 0, // totalPackagesCount + ArtStatsLog.BACKGROUND_DEXOPT_JOB_ENDED__PASS__PASS_UNKNOWN); } } } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 635e11be3a16..a884458bc6c2 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -829,7 +829,7 @@ public class TrustManagerService extends SystemService { } final boolean trusted; - if (android.security.Flags.fixUnlockedDeviceRequiredKeys()) { + if (android.security.Flags.fixUnlockedDeviceRequiredKeysV2()) { trusted = getUserTrustStateInner(id) == TrustState.TRUSTED; } else { trusted = aggregateIsTrusted(id); diff --git a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java index afbe352ad676..e5be4d9aa755 100644 --- a/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java +++ b/services/tests/PackageManagerServiceTests/server/src/com/android/server/pm/UserDataPreparerTest.java @@ -21,6 +21,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isNull; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -56,6 +58,7 @@ public class UserDataPreparerTest { private static final int TEST_USER_SERIAL = 1000; private static final int TEST_USER_ID = 10; + private static final UserInfo TEST_USER = new UserInfo(); private TestUserDataPreparer mUserDataPreparer; @@ -72,6 +75,8 @@ public class UserDataPreparerTest { @Before public void setup() { + TEST_USER.id = TEST_USER_ID; + TEST_USER.serialNumber = TEST_USER_SERIAL; Context ctx = InstrumentationRegistry.getContext(); FileUtils.deleteContents(ctx.getCacheDir()); mInstallLock = new Object(); @@ -92,8 +97,7 @@ public class UserDataPreparerTest { userDeDir.mkdirs(); File systemDeDir = mUserDataPreparer.getDataSystemDeDirectory(TEST_USER_ID); systemDeDir.mkdirs(); - mUserDataPreparer - .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_DE); + mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_DE); verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_DE)); verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID), @@ -110,8 +114,7 @@ public class UserDataPreparerTest { userCeDir.mkdirs(); File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID); systemCeDir.mkdirs(); - mUserDataPreparer - .prepareUserData(TEST_USER_ID, TEST_USER_SERIAL, StorageManager.FLAG_STORAGE_CE); + mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_CE); verify(mStorageManagerMock).prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL), eq(StorageManager.FLAG_STORAGE_CE)); verify(mInstaller).createUserData(isNull(String.class), eq(TEST_USER_ID), @@ -123,6 +126,28 @@ public class UserDataPreparerTest { } @Test + public void testPrepareUserData_forNewUser_destroysOnFailure() throws Exception { + TEST_USER.lastLoggedInTime = 0; + doThrow(new IllegalStateException("expected exception for test")).when(mStorageManagerMock) + .prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL), + eq(StorageManager.FLAG_STORAGE_CE)); + mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_CE); + verify(mStorageManagerMock).destroyUserStorage(isNull(String.class), eq(TEST_USER_ID), + eq(StorageManager.FLAG_STORAGE_CE)); + } + + @Test + public void testPrepareUserData_forExistingUser_doesNotDestroyOnFailure() throws Exception { + TEST_USER.lastLoggedInTime = System.currentTimeMillis(); + doThrow(new IllegalStateException("expected exception for test")).when(mStorageManagerMock) + .prepareUserStorage(isNull(String.class), eq(TEST_USER_ID), eq(TEST_USER_SERIAL), + eq(StorageManager.FLAG_STORAGE_CE)); + mUserDataPreparer.prepareUserData(TEST_USER, StorageManager.FLAG_STORAGE_CE); + verify(mStorageManagerMock, never()).destroyUserStorage(isNull(String.class), + eq(TEST_USER_ID), eq(StorageManager.FLAG_STORAGE_CE)); + } + + @Test public void testDestroyUserData_De_DoesNotDestroyCe() throws Exception { // Add file in CE storage File systemCeDir = mUserDataPreparer.getDataSystemCeDirectory(TEST_USER_ID); diff --git a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt index 1dfd5c06167b..d0e56268a27d 100644 --- a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt +++ b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt @@ -93,7 +93,7 @@ class GrantAndRevokeTrustTest { } @Test - @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS) + @RequiresFlagsEnabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2) fun grantCannotActivelyUnlockDevice() { // On automotive, trust agents can actively unlock the device. assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) @@ -120,7 +120,7 @@ class GrantAndRevokeTrustTest { } @Test - @RequiresFlagsDisabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS) + @RequiresFlagsDisabled(android.security.Flags.FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2) fun grantCouldCauseWrongDeviceLockedStateDueToBug() { // On automotive, trust agents can actively unlock the device. assumeFalse(packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) diff --git a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt index 5a8f82827253..01218099f34c 100644 --- a/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt +++ b/tests/TrustTests/src/android/trust/test/lib/LockStateTrackingRule.kt @@ -36,7 +36,8 @@ import org.junit.runners.model.Statement class LockStateTrackingRule : TestRule { private val context: Context = getApplicationContext() private val windowManager = checkNotNull(WindowManagerGlobal.getWindowManagerService()) - private val keyguardManager = context.getSystemService(KeyguardManager::class.java) as KeyguardManager + private val keyguardManager = + context.getSystemService(KeyguardManager::class.java) as KeyguardManager @Volatile lateinit var trustState: TrustState private set @@ -63,7 +64,7 @@ class LockStateTrackingRule : TestRule { wait("not trusted") { trustState.trusted == false } } - // TODO(b/299298338) remove this when removing FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS + // TODO(b/299298338) remove this when removing FLAG_FIX_UNLOCKED_DEVICE_REQUIRED_KEYS_V2 fun assertUnlockedButNotReally() { wait("device unlocked") { !keyguardManager.isDeviceLocked } wait("not trusted") { trustState.trusted == false } @@ -87,7 +88,7 @@ class LockStateTrackingRule : TestRule { trustGrantedMessages: MutableList<String> ) { Log.d(TAG, "Device became trusted=$enabled") - trustState = trustState.copy(trusted=enabled) + trustState = trustState.copy(trusted = enabled) } } |