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

Commit aa32d153 authored by Rubin Xu's avatar Rubin Xu
Browse files

Invoke BLKSECDISCARD to securely delete sensitive data

Bug: 34600579
Test: manual - change device lock under synthetic password, verify
      old data on disk is erased.

Change-Id: I247bd1f095dd27335e671981f9e2d77e149af84f
parent 74fa79e6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -295,4 +295,5 @@ interface IStorageManager {
    long getCacheSizeBytes(String volumeUuid, int uid) = 76;
    long getAllocatableBytes(String volumeUuid, int flags) = 77;
    void allocateBytes(String volumeUuid, long bytes, int flags) = 78;
    void secdiscard(in String path) = 79;
}
+9 −0
Original line number Diff line number Diff line
@@ -1251,6 +1251,15 @@ public class StorageManager {
        }
    }

    /** {@hide} */
    public void secdiscard(String path) {
        try {
            mStorageManager.secdiscard(path);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /** {@hide} */
    public static boolean isUserKeyUnlocked(int userId) {
        if (sStorageManager == null) {
+12 −0
Original line number Diff line number Diff line
@@ -3009,6 +3009,18 @@ class StorageManagerService extends IStorageManager.Stub
        }
    }

    @Override
    public void secdiscard(String path) {
        enforcePermission(android.Manifest.permission.STORAGE_INTERNAL);
        waitForReady();

        try {
            mCryptConnector.execute("cryptfs", "secdiscard", escapeNull(path));
        } catch (NativeDaemonConnectorException e) {
            throw e.rethrowAsParcelableException();
        }
    }

    class AppFuseMountScope extends AppFuseBridge.MountScope {
        boolean opened = false;

+14 −5
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.os.UserManager;
import android.os.storage.StorageManager;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
@@ -339,8 +340,11 @@ class LockSettingsStorage {
        synchronized (mFileWriteLock) {
            RandomAccessFile raf = null;
            try {
                // Write the hash to file
                raf = new RandomAccessFile(name, "rw");
                // Write the hash to file, requiring each write to be synchronized to the
                // underlying storage device immediately to avoid data loss in case of power loss.
                // This also ensures future secdiscard operation on the file succeeds since the
                // file would have been allocated on flash.
                raf = new RandomAccessFile(name, "rws");
                // Truncate the file if pattern is null, to clear the lock
                if (hash == null || hash.length == 0) {
                    raf.setLength(0);
@@ -435,12 +439,17 @@ class LockSettingsStorage {
        return readFile(getSynthenticPasswordStateFilePathForUser(userId, handle, name));
    }

    public void deleteSyntheticPasswordState(int userId, long handle, String name, boolean secure) {
    public void deleteSyntheticPasswordState(int userId, long handle, String name) {
        String path = getSynthenticPasswordStateFilePathForUser(userId, handle, name);
        File file = new File(path);
        if (file.exists()) {
            //TODO: (b/34600579) invoke secdiscardable
            try {
                mContext.getSystemService(StorageManager.class).secdiscard(file.getAbsolutePath());
            } catch (Exception e) {
                Slog.w(TAG, "Failed to secdiscard " + path, e);
            } finally {
                file.delete();
            }
            mCache.putFile(path, null);
        }
    }
+10 −10
Original line number Diff line number Diff line
@@ -452,7 +452,7 @@ public class SyntheticPasswordManager {

    // Nuke the SP handle (and as a result, its SID) for the given user.
    public void clearSidForUser(int userId) {
        destroyState(SP_HANDLE_NAME, true, DEFAULT_HANDLE, userId);
        destroyState(SP_HANDLE_NAME, DEFAULT_HANDLE, userId);
    }

    public boolean hasSidForUser(int userId) {
@@ -487,8 +487,8 @@ public class SyntheticPasswordManager {
    }

    public void destroyEscrowData(int userId) {
        destroyState(SP_E0_NAME, true, DEFAULT_HANDLE, userId);
        destroyState(SP_P1_NAME, true, DEFAULT_HANDLE, userId);
        destroyState(SP_E0_NAME, DEFAULT_HANDLE, userId);
        destroyState(SP_P1_NAME, DEFAULT_HANDLE, userId);
    }

    private int loadWeaverSlot(long handle, int userId) {
@@ -523,7 +523,7 @@ public class SyntheticPasswordManager {
                Log.w(TAG, "Failed to destroy slot", e);
            }
        }
        destroyState(WEAVER_SLOT_NAME, true, handle, userId);
        destroyState(WEAVER_SLOT_NAME, handle, userId);
    }

    private int getNextAvailableWeaverSlot() {
@@ -877,17 +877,17 @@ public class SyntheticPasswordManager {

    public void destroyTokenBasedSyntheticPassword(long handle, int userId) {
        destroySyntheticPassword(handle, userId);
        destroyState(SECDISCARDABLE_NAME, true, handle, userId);
        destroyState(SECDISCARDABLE_NAME, handle, userId);
    }

    public void destroyPasswordBasedSyntheticPassword(long handle, int userId) {
        destroySyntheticPassword(handle, userId);
        destroyState(SECDISCARDABLE_NAME, true, handle, userId);
        destroyState(PASSWORD_DATA_NAME, true, handle, userId);
        destroyState(SECDISCARDABLE_NAME, handle, userId);
        destroyState(PASSWORD_DATA_NAME, handle, userId);
    }

    private void destroySyntheticPassword(long handle, int userId) {
        destroyState(SP_BLOB_NAME, true, handle, userId);
        destroyState(SP_BLOB_NAME, handle, userId);
        destroySPBlobKey(getHandleName(handle));
        if (hasState(WEAVER_SLOT_NAME, handle, userId)) {
            destroyWeaverSlot(handle, userId);
@@ -938,8 +938,8 @@ public class SyntheticPasswordManager {
        mStorage.writeSyntheticPasswordState(userId, handle, stateName, data);
    }

    private void destroyState(String stateName, boolean secure, long handle, int userId) {
        mStorage.deleteSyntheticPasswordState(userId, handle, stateName, secure);
    private void destroyState(String stateName, long handle, int userId) {
        mStorage.deleteSyntheticPasswordState(userId, handle, stateName);
    }

    protected byte[] decryptSPBlob(String blobKeyName, byte[] blob, byte[] applicationId) {
Loading