Loading core/java/android/os/UserManagerInternal.java +8 −0 Original line number Diff line number Diff line Loading @@ -221,4 +221,12 @@ public abstract class UserManagerInternal { */ public abstract boolean isSettingRestrictedForUser(String setting, int userId, String value, int callingUid); /** * Returns {@code true} if the system should ignore errors when preparing * the storage directories for the user with ID {@code userId}. This will * return {@code false} for all new users; it will only return {@code true} * for users that already existed on-disk from an older version of Android. */ public abstract boolean shouldIgnorePrepareStorageErrors(int userId); } services/core/java/com/android/server/StorageManagerService.java +15 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.AtomicFile; import android.util.DataUnit; import android.util.EventLog; import android.util.Log; import android.util.Pair; import android.util.Slog; Loading Loading @@ -2894,7 +2895,21 @@ class StorageManagerService extends IStorageManager.Stub try { mVold.prepareUserStorage(volumeUuid, userId, serialNumber, flags); } catch (Exception e) { EventLog.writeEvent(0x534e4554, "224585613", -1, ""); Slog.wtf(TAG, e); // Make sure to re-throw this exception; we must not ignore failure // to prepare the user storage as it could indicate that encryption // wasn't successfully set up. // // Very unfortunately, these errors need to be ignored for broken // users that already existed on-disk from older Android versions. UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class); if (umInternal.shouldIgnorePrepareStorageErrors(userId)) { Slog.wtf(TAG, "ignoring error preparing storage for existing user " + userId + "; device may be insecure!"); return; } throw new RuntimeException(e); } } Loading services/core/java/com/android/server/notification/NotificationManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -4911,8 +4911,11 @@ public class NotificationManagerService extends SystemService { try { fixNotification(notification, pkg, userId); } catch (NameNotFoundException e) { Slog.e(TAG, "Cannot create a context for sending app", e); } catch (Exception e) { if (notification.isForegroundService()) { throw new SecurityException("Invalid FGS notification", e); } Slog.e(TAG, "Cannot fix notification", e); return; } Loading services/core/java/com/android/server/pm/UserDataPreparer.java +11 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.Context; 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; Loading Loading @@ -115,6 +116,16 @@ class UserDataPreparer { // Try one last time; if we fail again we're really in trouble prepareUserDataLI(volumeUuid, userId, userSerial, flags | StorageManager.FLAG_STORAGE_DE, false); } else { try { Log.wtf(TAG, "prepareUserData failed for user " + userId, e); if (userId == UserHandle.USER_SYSTEM) { RecoverySystem.rebootPromptAndWipeUserData(mContext, "prepareUserData failed for system user"); } } catch (IOException e2) { throw new RuntimeException("error rebooting into recovery", e2); } } } } Loading services/core/java/com/android/server/pm/UserManagerService.java +42 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,8 @@ public class UserManagerService extends IUserManager.Stub { private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions"; private static final String TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL = "lastRequestQuietModeEnabledCall"; private static final String TAG_IGNORE_PREPARE_STORAGE_ERRORS = "ignorePrepareStorageErrors"; private static final String ATTR_KEY = "key"; private static final String ATTR_VALUE_TYPE = "type"; private static final String ATTR_MULTIPLE = "m"; Loading Loading @@ -282,6 +284,14 @@ public class UserManagerService extends IUserManager.Stub { private long mLastRequestQuietModeEnabledMillis; /** * {@code true} if the system should ignore errors when preparing the * storage directories for this user. This is {@code false} for all new * users; it will only be {@code true} for users that already existed * on-disk from an older version of Android. */ private boolean mIgnorePrepareStorageErrors; void setLastRequestQuietModeEnabledMillis(long millis) { mLastRequestQuietModeEnabledMillis = millis; } Loading @@ -290,6 +300,14 @@ public class UserManagerService extends IUserManager.Stub { return mLastRequestQuietModeEnabledMillis; } boolean getIgnorePrepareStorageErrors() { return mIgnorePrepareStorageErrors; } void setIgnorePrepareStorageErrors() { mIgnorePrepareStorageErrors = true; } void clearSeedAccountData() { seedAccountName = null; seedAccountType = null; Loading Loading @@ -2438,6 +2456,10 @@ public class UserManagerService extends IUserManager.Stub { serializer.endTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL); } serializer.startTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS); serializer.text(String.valueOf(userData.getIgnorePrepareStorageErrors())); serializer.endTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS); serializer.endTag(null, TAG_USER); serializer.endDocument(); Loading Loading @@ -2547,6 +2569,7 @@ public class UserManagerService extends IUserManager.Stub { Bundle baseRestrictions = null; Bundle localRestrictions = null; Bundle globalRestrictions = null; boolean ignorePrepareStorageErrors = true; // default is true for old users XmlPullParser parser = Xml.newPullParser(); parser.setInput(is, StandardCharsets.UTF_8.name()); Loading Loading @@ -2629,6 +2652,11 @@ public class UserManagerService extends IUserManager.Stub { if (type == XmlPullParser.TEXT) { lastRequestQuietModeEnabledTimestamp = Long.parseLong(parser.getText()); } } else if (TAG_IGNORE_PREPARE_STORAGE_ERRORS.equals(tag)) { type = parser.next(); if (type == XmlPullParser.TEXT) { ignorePrepareStorageErrors = Boolean.parseBoolean(parser.getText()); } } } } Loading @@ -2655,6 +2683,9 @@ public class UserManagerService extends IUserManager.Stub { userData.persistSeedData = persistSeedData; userData.seedAccountOptions = seedAccountOptions; userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp); if (ignorePrepareStorageErrors) { userData.setIgnorePrepareStorageErrors(); } synchronized (mRestrictionsLock) { if (baseRestrictions != null) { Loading Loading @@ -4047,6 +4078,9 @@ public class UserManagerService extends IUserManager.Stub { pw.println(); } } pw.println(" Ignore errors preparing storage: " + userData.getIgnorePrepareStorageErrors()); } } pw.println(); Loading Loading @@ -4394,6 +4428,14 @@ public class UserManagerService extends IUserManager.Stub { return UserRestrictionsUtils.isSettingRestrictedForUser(mContext, setting, userId, value, callingUid); } @Override public boolean shouldIgnorePrepareStorageErrors(int userId) { synchronized (mUsersLock) { UserData userData = mUsers.get(userId); return userData != null && userData.getIgnorePrepareStorageErrors(); } } } /* Remove all the users except of the system one. */ Loading Loading
core/java/android/os/UserManagerInternal.java +8 −0 Original line number Diff line number Diff line Loading @@ -221,4 +221,12 @@ public abstract class UserManagerInternal { */ public abstract boolean isSettingRestrictedForUser(String setting, int userId, String value, int callingUid); /** * Returns {@code true} if the system should ignore errors when preparing * the storage directories for the user with ID {@code userId}. This will * return {@code false} for all new users; it will only return {@code true} * for users that already existed on-disk from an older version of Android. */ public abstract boolean shouldIgnorePrepareStorageErrors(int userId); }
services/core/java/com/android/server/StorageManagerService.java +15 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,7 @@ import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.AtomicFile; import android.util.DataUnit; import android.util.EventLog; import android.util.Log; import android.util.Pair; import android.util.Slog; Loading Loading @@ -2894,7 +2895,21 @@ class StorageManagerService extends IStorageManager.Stub try { mVold.prepareUserStorage(volumeUuid, userId, serialNumber, flags); } catch (Exception e) { EventLog.writeEvent(0x534e4554, "224585613", -1, ""); Slog.wtf(TAG, e); // Make sure to re-throw this exception; we must not ignore failure // to prepare the user storage as it could indicate that encryption // wasn't successfully set up. // // Very unfortunately, these errors need to be ignored for broken // users that already existed on-disk from older Android versions. UserManagerInternal umInternal = LocalServices.getService(UserManagerInternal.class); if (umInternal.shouldIgnorePrepareStorageErrors(userId)) { Slog.wtf(TAG, "ignoring error preparing storage for existing user " + userId + "; device may be insecure!"); return; } throw new RuntimeException(e); } } Loading
services/core/java/com/android/server/notification/NotificationManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -4911,8 +4911,11 @@ public class NotificationManagerService extends SystemService { try { fixNotification(notification, pkg, userId); } catch (NameNotFoundException e) { Slog.e(TAG, "Cannot create a context for sending app", e); } catch (Exception e) { if (notification.isForegroundService()) { throw new SecurityException("Invalid FGS notification", e); } Slog.e(TAG, "Cannot fix notification", e); return; } Loading
services/core/java/com/android/server/pm/UserDataPreparer.java +11 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.Context; 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; Loading Loading @@ -115,6 +116,16 @@ class UserDataPreparer { // Try one last time; if we fail again we're really in trouble prepareUserDataLI(volumeUuid, userId, userSerial, flags | StorageManager.FLAG_STORAGE_DE, false); } else { try { Log.wtf(TAG, "prepareUserData failed for user " + userId, e); if (userId == UserHandle.USER_SYSTEM) { RecoverySystem.rebootPromptAndWipeUserData(mContext, "prepareUserData failed for system user"); } } catch (IOException e2) { throw new RuntimeException("error rebooting into recovery", e2); } } } } Loading
services/core/java/com/android/server/pm/UserManagerService.java +42 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,8 @@ public class UserManagerService extends IUserManager.Stub { private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions"; private static final String TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL = "lastRequestQuietModeEnabledCall"; private static final String TAG_IGNORE_PREPARE_STORAGE_ERRORS = "ignorePrepareStorageErrors"; private static final String ATTR_KEY = "key"; private static final String ATTR_VALUE_TYPE = "type"; private static final String ATTR_MULTIPLE = "m"; Loading Loading @@ -282,6 +284,14 @@ public class UserManagerService extends IUserManager.Stub { private long mLastRequestQuietModeEnabledMillis; /** * {@code true} if the system should ignore errors when preparing the * storage directories for this user. This is {@code false} for all new * users; it will only be {@code true} for users that already existed * on-disk from an older version of Android. */ private boolean mIgnorePrepareStorageErrors; void setLastRequestQuietModeEnabledMillis(long millis) { mLastRequestQuietModeEnabledMillis = millis; } Loading @@ -290,6 +300,14 @@ public class UserManagerService extends IUserManager.Stub { return mLastRequestQuietModeEnabledMillis; } boolean getIgnorePrepareStorageErrors() { return mIgnorePrepareStorageErrors; } void setIgnorePrepareStorageErrors() { mIgnorePrepareStorageErrors = true; } void clearSeedAccountData() { seedAccountName = null; seedAccountType = null; Loading Loading @@ -2438,6 +2456,10 @@ public class UserManagerService extends IUserManager.Stub { serializer.endTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL); } serializer.startTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS); serializer.text(String.valueOf(userData.getIgnorePrepareStorageErrors())); serializer.endTag(/* namespace */ null, TAG_IGNORE_PREPARE_STORAGE_ERRORS); serializer.endTag(null, TAG_USER); serializer.endDocument(); Loading Loading @@ -2547,6 +2569,7 @@ public class UserManagerService extends IUserManager.Stub { Bundle baseRestrictions = null; Bundle localRestrictions = null; Bundle globalRestrictions = null; boolean ignorePrepareStorageErrors = true; // default is true for old users XmlPullParser parser = Xml.newPullParser(); parser.setInput(is, StandardCharsets.UTF_8.name()); Loading Loading @@ -2629,6 +2652,11 @@ public class UserManagerService extends IUserManager.Stub { if (type == XmlPullParser.TEXT) { lastRequestQuietModeEnabledTimestamp = Long.parseLong(parser.getText()); } } else if (TAG_IGNORE_PREPARE_STORAGE_ERRORS.equals(tag)) { type = parser.next(); if (type == XmlPullParser.TEXT) { ignorePrepareStorageErrors = Boolean.parseBoolean(parser.getText()); } } } } Loading @@ -2655,6 +2683,9 @@ public class UserManagerService extends IUserManager.Stub { userData.persistSeedData = persistSeedData; userData.seedAccountOptions = seedAccountOptions; userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp); if (ignorePrepareStorageErrors) { userData.setIgnorePrepareStorageErrors(); } synchronized (mRestrictionsLock) { if (baseRestrictions != null) { Loading Loading @@ -4047,6 +4078,9 @@ public class UserManagerService extends IUserManager.Stub { pw.println(); } } pw.println(" Ignore errors preparing storage: " + userData.getIgnorePrepareStorageErrors()); } } pw.println(); Loading Loading @@ -4394,6 +4428,14 @@ public class UserManagerService extends IUserManager.Stub { return UserRestrictionsUtils.isSettingRestrictedForUser(mContext, setting, userId, value, callingUid); } @Override public boolean shouldIgnorePrepareStorageErrors(int userId) { synchronized (mUsersLock) { UserData userData = mUsers.get(userId); return userData != null && userData.getIgnorePrepareStorageErrors(); } } } /* Remove all the users except of the system one. */ Loading