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

Commit bf42e62c authored by Eric Biggers's avatar Eric Biggers Committed by Automerger Merge Worker
Browse files

Merge changes from topic "user-key-rename" into main am: 7490fc59

parents 98cbec1d 7490fc59
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -2372,14 +2372,14 @@ public final class StrictMode {
    }

    /** Assume locked until we hear otherwise */
    private static volatile boolean sUserKeyUnlocked = false;
    private static volatile boolean sCeStorageUnlocked = false;

    private static boolean isUserKeyUnlocked(int userId) {
    private static boolean isCeStorageUnlocked(int userId) {
        final IStorageManager storage = IStorageManager.Stub
                .asInterface(ServiceManager.getService("mount"));
        if (storage != null) {
            try {
                return storage.isUserKeyUnlocked(userId);
                return storage.isCeStorageUnlocked(userId);
            } catch (RemoteException ignored) {
            }
        }
@@ -2392,13 +2392,13 @@ public final class StrictMode {
        // since any relocking of that user will always result in our
        // process being killed to release any CE FDs we're holding onto.
        if (userId == UserHandle.myUserId()) {
            if (sUserKeyUnlocked) {
            if (sCeStorageUnlocked) {
                return;
            } else if (isUserKeyUnlocked(userId)) {
                sUserKeyUnlocked = true;
            } else if (isCeStorageUnlocked(userId)) {
                sCeStorageUnlocked = true;
                return;
            }
        } else if (isUserKeyUnlocked(userId)) {
        } else if (isCeStorageUnlocked(userId)) {
            return;
        }

+6 −6
Original line number Diff line number Diff line
@@ -134,20 +134,20 @@ interface IStorageManager {
    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
    void setDebugFlags(int flags, int mask) = 60;
    @EnforcePermission("STORAGE_INTERNAL")
    void createUserKey(int userId, int serialNumber, boolean ephemeral) = 61;
    void createUserStorageKeys(int userId, int serialNumber, boolean ephemeral) = 61;
    @EnforcePermission("STORAGE_INTERNAL")
    void destroyUserKey(int userId) = 62;
    void destroyUserStorageKeys(int userId) = 62;
    @EnforcePermission("STORAGE_INTERNAL")
    void unlockUserKey(int userId, int serialNumber, in byte[] secret) = 63;
    void unlockCeStorage(int userId, int serialNumber, in byte[] secret) = 63;
    @EnforcePermission("STORAGE_INTERNAL")
    void lockUserKey(int userId) = 64;
    boolean isUserKeyUnlocked(int userId) = 65;
    void lockCeStorage(int userId) = 64;
    boolean isCeStorageUnlocked(int userId) = 65;
    @EnforcePermission("STORAGE_INTERNAL")
    void prepareUserStorage(in String volumeUuid, int userId, int serialNumber, int flags) = 66;
    @EnforcePermission("STORAGE_INTERNAL")
    void destroyUserStorage(in String volumeUuid, int userId, int flags) = 67;
    @EnforcePermission("STORAGE_INTERNAL")
    void setUserKeyProtection(int userId, in byte[] secret) = 70;
    void setCeStorageProtection(int userId, in byte[] secret) = 70;
    @EnforcePermission("MOUNT_FORMAT_FILESYSTEMS")
    void fstrim(int flags, IVoldTaskListener listener) = 72;
    AppFuseMount mountProxyFileDescriptorBridge() = 73;
+56 −11
Original line number Diff line number Diff line
@@ -1589,28 +1589,64 @@ public class StorageManager {
                DEFAULT_FULL_THRESHOLD_BYTES);
    }

    /** {@hide} */
    public void createUserKey(int userId, int serialNumber, boolean ephemeral) {
    /**
     * Creates the keys for a user's credential-encrypted (CE) and device-encrypted (DE) storage.
     * <p>
     * This creates the user's CE key and DE key for internal storage, then adds them to the kernel.
     * Then, if the user is not ephemeral, this stores the DE key (encrypted) on flash.  (The CE key
     * is not stored until {@link IStorageManager#setCeStorageProtection()}.)
     * <p>
     * This does not create the CE and DE directories themselves.  For that, see {@link
     * #prepareUserStorage()}.
     * <p>
     * This is only intended to be called by UserManagerService, as part of creating a user.
     *
     * @param userId ID of the user
     * @param serialNumber serial number of the user
     * @param ephemeral whether the user is ephemeral
     * @throws RuntimeException on error.  The user's keys already existing is considered an error.
     * @hide
     */
    public void createUserStorageKeys(int userId, int serialNumber, boolean ephemeral) {
        try {
            mStorageManager.createUserKey(userId, serialNumber, ephemeral);
            mStorageManager.createUserStorageKeys(userId, serialNumber, ephemeral);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** {@hide} */
    public void destroyUserKey(int userId) {
    /**
     * Destroys the keys for a user's credential-encrypted (CE) and device-encrypted (DE) storage.
     * <p>
     * This evicts the keys from the kernel (if present), which "locks" the corresponding
     * directories.  Then, this deletes the encrypted keys from flash.  This operates on all the
     * user's CE and DE keys, for both internal and adoptable storage.
     * <p>
     * This does not destroy the CE and DE directories themselves.  For that, see {@link
     * #destroyUserStorage()}.
     * <p>
     * This is only intended to be called by UserManagerService, as part of removing a user.
     *
     * @param userId ID of the user
     * @throws RuntimeException on error.  On error, as many things as possible are still destroyed.
     * @hide
     */
    public void destroyUserStorageKeys(int userId) {
        try {
            mStorageManager.destroyUserKey(userId);
            mStorageManager.destroyUserStorageKeys(userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** {@hide} */
    public void lockUserKey(int userId) {
    /**
     * Locks the user's credential-encrypted (CE) storage.
     *
     * @hide
     */
    public void lockCeStorage(int userId) {
        try {
            mStorageManager.lockUserKey(userId);
            mStorageManager.lockCeStorage(userId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -1637,17 +1673,26 @@ public class StorageManager {
    /** {@hide} */
    @TestApi
    public static boolean isUserKeyUnlocked(int userId) {
        return isCeStorageUnlocked(userId);
    }

    /**
     * Returns true if the user's credential-encrypted (CE) storage is unlocked.
     *
     * @hide
     */
    public static boolean isCeStorageUnlocked(int userId) {
        if (sStorageManager == null) {
            sStorageManager = IStorageManager.Stub
                    .asInterface(ServiceManager.getService("mount"));
        }
        if (sStorageManager == null) {
            Slog.w(TAG, "Early during boot, assuming locked");
            Slog.w(TAG, "Early during boot, assuming CE storage is locked");
            return false;
        }
        final long token = Binder.clearCallingIdentity();
        try {
            return sStorageManager.isUserKeyUnlocked(userId);
            return sStorageManager.isCeStorageUnlocked(userId);
        } catch (RemoteException e) {
            throw e.rethrowAsRuntimeException();
        } finally {
+26 −26
Original line number Diff line number Diff line
@@ -2986,7 +2986,7 @@ class StorageManagerService extends IStorageManager.Stub
            // We need all the users unlocked to move their primary storage
            users = mContext.getSystemService(UserManager.class).getUsers();
            for (UserInfo user : users) {
                if (StorageManager.isFileEncrypted() && !isUserKeyUnlocked(user.id)) {
                if (StorageManager.isFileEncrypted() && !isCeStorageUnlocked(user.id)) {
                    Slog.w(TAG, "Failing move due to locked user " + user.id);
                    onMoveStatusLocked(PackageManager.MOVE_FAILED_LOCKED_USER);
                    return;
@@ -3210,12 +3210,12 @@ class StorageManagerService extends IStorageManager.Stub

    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
    @Override
    public void createUserKey(int userId, int serialNumber, boolean ephemeral) {
    public void createUserStorageKeys(int userId, int serialNumber, boolean ephemeral) {

        super.createUserKey_enforcePermission();
        super.createUserStorageKeys_enforcePermission();

        try {
            mVold.createUserKey(userId, serialNumber, ephemeral);
            mVold.createUserStorageKeys(userId, serialNumber, ephemeral);
            // Since the user's CE key was just created, the user's CE storage is now unlocked.
            synchronized (mLock) {
                mCeUnlockedUsers.append(userId);
@@ -3227,12 +3227,12 @@ class StorageManagerService extends IStorageManager.Stub

    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
    @Override
    public void destroyUserKey(int userId) {
    public void destroyUserStorageKeys(int userId) {

        super.destroyUserKey_enforcePermission();
        super.destroyUserStorageKeys_enforcePermission();

        try {
            mVold.destroyUserKey(userId);
            mVold.destroyUserStorageKeys(userId);
            // Since the user's CE key was just destroyed, the user's CE storage is now locked.
            synchronized (mLock) {
                mCeUnlockedUsers.remove(userId);
@@ -3245,21 +3245,22 @@ class StorageManagerService extends IStorageManager.Stub
    /* Only for use by LockSettingsService */
    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
    @Override
    public void setUserKeyProtection(@UserIdInt int userId, byte[] secret) throws RemoteException {
        super.setUserKeyProtection_enforcePermission();
    public void setCeStorageProtection(@UserIdInt int userId, byte[] secret)
            throws RemoteException {
        super.setCeStorageProtection_enforcePermission();

        mVold.setUserKeyProtection(userId, HexDump.toHexString(secret));
        mVold.setCeStorageProtection(userId, HexDump.toHexString(secret));
    }

    /* Only for use by LockSettingsService */
    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
    @Override
    public void unlockUserKey(@UserIdInt int userId, int serialNumber, byte[] secret)
    public void unlockCeStorage(@UserIdInt int userId, int serialNumber, byte[] secret)
            throws RemoteException {
        super.unlockUserKey_enforcePermission();
        super.unlockCeStorage_enforcePermission();

        if (StorageManager.isFileEncrypted()) {
            mVold.unlockUserKey(userId, serialNumber, HexDump.toHexString(secret));
            mVold.unlockCeStorage(userId, serialNumber, HexDump.toHexString(secret));
        }
        synchronized (mLock) {
            mCeUnlockedUsers.append(userId);
@@ -3268,23 +3269,22 @@ class StorageManagerService extends IStorageManager.Stub

    @android.annotation.EnforcePermission(android.Manifest.permission.STORAGE_INTERNAL)
    @Override
    public void lockUserKey(int userId) {
        //  Do not lock user 0 data for headless system user
        super.lockUserKey_enforcePermission();
    public void lockCeStorage(int userId) {
        super.lockCeStorage_enforcePermission();

        // Never lock the CE storage of a headless system user.
        if (userId == UserHandle.USER_SYSTEM
                && UserManager.isHeadlessSystemUserMode()) {
            throw new IllegalArgumentException("Headless system user data cannot be locked..");
        }


        if (!isUserKeyUnlocked(userId)) {
        if (!isCeStorageUnlocked(userId)) {
            Slog.d(TAG, "User " + userId + "'s CE storage is already locked");
            return;
        }

        try {
            mVold.lockUserKey(userId);
            mVold.lockCeStorage(userId);
        } catch (Exception e) {
            Slog.wtf(TAG, e);
            return;
@@ -3296,7 +3296,7 @@ class StorageManagerService extends IStorageManager.Stub
    }

    @Override
    public boolean isUserKeyUnlocked(int userId) {
    public boolean isCeStorageUnlocked(int userId) {
        synchronized (mLock) {
            return mCeUnlockedUsers.contains(userId);
        }
@@ -3692,8 +3692,8 @@ class StorageManagerService extends IStorageManager.Stub
        final int userId = UserHandle.getUserId(callingUid);
        final String propertyName = "sys.user." + userId + ".ce_available";

        // Ignore requests to create directories while storage is locked
        if (!isUserKeyUnlocked(userId)) {
        // Ignore requests to create directories while CE storage is locked
        if (!isCeStorageUnlocked(userId)) {
            throw new IllegalStateException("Failed to prepare " + appPath);
        }

@@ -3819,15 +3819,15 @@ class StorageManagerService extends IStorageManager.Stub
        final boolean systemUserUnlocked = isSystemUnlocked(UserHandle.USER_SYSTEM);

        final boolean userIsDemo;
        final boolean userKeyUnlocked;
        final boolean storagePermission;
        final boolean ceStorageUnlocked;
        final long token = Binder.clearCallingIdentity();
        try {
            userIsDemo = LocalServices.getService(UserManagerInternal.class)
                    .getUserInfo(userId).isDemo();
            storagePermission = mStorageManagerInternal.hasExternalStorage(callingUid,
                    callingPackage);
            userKeyUnlocked = isUserKeyUnlocked(userId);
            ceStorageUnlocked = isCeStorageUnlocked(userId);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
@@ -3887,7 +3887,7 @@ class StorageManagerService extends IStorageManager.Stub
                } else if (!systemUserUnlocked) {
                    reportUnmounted = true;
                    Slog.w(TAG, "Reporting " + volId + " unmounted due to system locked");
                } else if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
                } else if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !ceStorageUnlocked) {
                    reportUnmounted = true;
                    Slog.w(TAG, "Reporting " + volId + "unmounted due to " + userId + " locked");
                } else if (!storagePermission && !realState) {
+2 −2
Original line number Diff line number Diff line
@@ -2292,7 +2292,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            return;
        }
        // TODO(b/148767783): should we check all profiles under user0?
        UserspaceRebootLogger.logEventAsync(StorageManager.isUserKeyUnlocked(userId),
        UserspaceRebootLogger.logEventAsync(StorageManager.isCeStorageUnlocked(userId),
                BackgroundThread.getExecutor());
    }
@@ -4626,7 +4626,7 @@ public class ActivityManagerService extends IActivityManager.Stub
            // We carefully use the same state that PackageManager uses for
            // filtering, since we use this flag to decide if we need to install
            // providers when user is unlocked later
            app.setUnlocked(StorageManager.isUserKeyUnlocked(app.userId));
            app.setUnlocked(StorageManager.isCeStorageUnlocked(app.userId));
        }
        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Loading