[RESTRICT AUTOMERGE] Ignore errors preparing user storage for existing users am: e03e987337

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17416250

Change-Id: I9f47d7a36a6d3d6c1ba5b82d17f21c15dd9f7235
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Eric Biggers
2022-04-20 21:39:31 +00:00
committed by Automerger Merge Worker
3 changed files with 60 additions and 1 deletions

View File

@@ -279,4 +279,12 @@ public abstract class UserManagerInternal {
* Gets all {@link UserInfo UserInfos}. * Gets all {@link UserInfo UserInfos}.
*/ */
public abstract @NonNull UserInfo[] getUserInfos(); public abstract @NonNull UserInfo[] getUserInfos();
/**
* 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);
} }

View File

@@ -3389,11 +3389,20 @@ class StorageManagerService extends IStorageManager.Stub
mInstaller.tryMountDataMirror(volumeUuid); mInstaller.tryMountDataMirror(volumeUuid);
} }
} }
} catch (RemoteException | Installer.InstallerException e) { } catch (Exception e) {
Slog.wtf(TAG, e); Slog.wtf(TAG, e);
// Make sure to re-throw this exception; we must not ignore failure // Make sure to re-throw this exception; we must not ignore failure
// to prepare the user storage as it could indicate that encryption // to prepare the user storage as it could indicate that encryption
// wasn't successfully set up. // 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); throw new RuntimeException(e);
} }
} }

View File

@@ -198,6 +198,8 @@ public class UserManagerService extends IUserManager.Stub {
private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions"; private static final String TAG_SEED_ACCOUNT_OPTIONS = "seedAccountOptions";
private static final String TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL = private static final String TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL =
"lastRequestQuietModeEnabledCall"; "lastRequestQuietModeEnabledCall";
private static final String TAG_IGNORE_PREPARE_STORAGE_ERRORS =
"ignorePrepareStorageErrors";
private static final String ATTR_KEY = "key"; private static final String ATTR_KEY = "key";
private static final String ATTR_VALUE_TYPE = "type"; private static final String ATTR_VALUE_TYPE = "type";
private static final String ATTR_MULTIPLE = "m"; private static final String ATTR_MULTIPLE = "m";
@@ -298,6 +300,14 @@ public class UserManagerService extends IUserManager.Stub {
private long mLastRequestQuietModeEnabledMillis; 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) { void setLastRequestQuietModeEnabledMillis(long millis) {
mLastRequestQuietModeEnabledMillis = millis; mLastRequestQuietModeEnabledMillis = millis;
} }
@@ -306,6 +316,14 @@ public class UserManagerService extends IUserManager.Stub {
return mLastRequestQuietModeEnabledMillis; return mLastRequestQuietModeEnabledMillis;
} }
boolean getIgnorePrepareStorageErrors() {
return mIgnorePrepareStorageErrors;
}
void setIgnorePrepareStorageErrors() {
mIgnorePrepareStorageErrors = true;
}
void clearSeedAccountData() { void clearSeedAccountData() {
seedAccountName = null; seedAccountName = null;
seedAccountType = null; seedAccountType = null;
@@ -2955,6 +2973,10 @@ public class UserManagerService extends IUserManager.Stub {
serializer.endTag(/* namespace */ null, TAG_LAST_REQUEST_QUIET_MODE_ENABLED_CALL); 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.endTag(null, TAG_USER);
serializer.endDocument(); serializer.endDocument();
@@ -3067,6 +3089,7 @@ public class UserManagerService extends IUserManager.Stub {
Bundle legacyLocalRestrictions = null; Bundle legacyLocalRestrictions = null;
RestrictionsSet localRestrictions = null; RestrictionsSet localRestrictions = null;
Bundle globalRestrictions = null; Bundle globalRestrictions = null;
boolean ignorePrepareStorageErrors = true; // default is true for old users
XmlPullParser parser = Xml.newPullParser(); XmlPullParser parser = Xml.newPullParser();
parser.setInput(is, StandardCharsets.UTF_8.name()); parser.setInput(is, StandardCharsets.UTF_8.name());
@@ -3158,6 +3181,11 @@ public class UserManagerService extends IUserManager.Stub {
if (type == XmlPullParser.TEXT) { if (type == XmlPullParser.TEXT) {
lastRequestQuietModeEnabledTimestamp = Long.parseLong(parser.getText()); 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());
}
} }
} }
} }
@@ -3185,6 +3213,9 @@ public class UserManagerService extends IUserManager.Stub {
userData.persistSeedData = persistSeedData; userData.persistSeedData = persistSeedData;
userData.seedAccountOptions = seedAccountOptions; userData.seedAccountOptions = seedAccountOptions;
userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp); userData.setLastRequestQuietModeEnabledMillis(lastRequestQuietModeEnabledTimestamp);
if (ignorePrepareStorageErrors) {
userData.setIgnorePrepareStorageErrors();
}
synchronized (mRestrictionsLock) { synchronized (mRestrictionsLock) {
if (baseRestrictions != null) { if (baseRestrictions != null) {
@@ -4829,6 +4860,9 @@ public class UserManagerService extends IUserManager.Stub {
pw.println(); pw.println();
} }
} }
pw.println(" Ignore errors preparing storage: "
+ userData.getIgnorePrepareStorageErrors());
} }
} }
pw.println(); pw.println();
@@ -5254,6 +5288,14 @@ public class UserManagerService extends IUserManager.Stub {
return allInfos; return allInfos;
} }
} }
@Override
public boolean shouldIgnorePrepareStorageErrors(int userId) {
synchronized (mUsersLock) {
UserData userData = mUsers.get(userId);
return userData != null && userData.getIgnorePrepareStorageErrors();
}
}
} }
/** /**