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

Commit a9437bd1 authored by Charles He's avatar Charles He
Browse files

Prevent writing to FRP partition during factory reset.

Avoid potential race condition between FRP wipe and write operations
during factory reset by making the FRP partition unwritable after
wipe.

Bug: 30352311
Test: manual
Change-Id: If3f024a1611366c0677a996705724458094fcfad
(cherry picked from commit a629c772)
parent ce477912
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -54,6 +54,9 @@ public class PersistentDataBlockManager {
     * Returns the number of bytes written or -1 on error. If the block is too big
     * to fit on the partition, returns -MAX_BLOCK_SIZE.
     *
     * {@link #wipe} will block any further {@link #write} operation until reboot,
     * in which case -1 will be returned.
     *
     * @param data the data to write
     */
    public int write(byte[] data) {
@@ -108,6 +111,8 @@ public class PersistentDataBlockManager {
    /**
     * Zeroes the previously written block in its entirety. Calling this method
     * will erase all data written to the persistent data partition.
     * It will also prevent any further {@link #write} operation until reboot,
     * in order to prevent a potential race condition. See b/30352311.
     */
    public void wipe() {
        try {
+14 −6
Original line number Diff line number Diff line
@@ -50,15 +50,14 @@ import java.util.Arrays;
 * This data will live across factory resets not initiated via the Settings UI.
 * When a device is factory reset through Settings this data is wiped.
 *
 * Allows writing one block at a time. Namely, each time
 * {@link android.service.persistentdata.IPersistentDataBlockService}.write(byte[] data)
 * is called, it will overwite the data that was previously written on the block.
 * Allows writing one block at a time. Namely, each time {@link IPersistentDataBlockService#write}
 * is called, it will overwrite the data that was previously written on the block.
 *
 * Clients can query the size of the currently written block via
 * {@link android.service.persistentdata.IPersistentDataBlockService}.getTotalDataSize().
 * {@link IPersistentDataBlockService#getDataBlockSize}
 *
 * Clients can any number of bytes from the currently written block up to its total size by invoking
 * {@link android.service.persistentdata.IPersistentDataBlockService}.read(byte[] data)
 * Clients can read any number of bytes from the currently written block up to its total size by
 * invoking {@link IPersistentDataBlockService#read}
 */
public class PersistentDataBlockService extends SystemService {
    private static final String TAG = PersistentDataBlockService.class.getSimpleName();
@@ -77,6 +76,7 @@ public class PersistentDataBlockService extends SystemService {

    private int mAllowedUid = -1;
    private long mBlockDeviceSize;
    private boolean mIsWritable = true;

    public PersistentDataBlockService(Context context) {
        super(context);
@@ -345,6 +345,11 @@ public class PersistentDataBlockService extends SystemService {
            headerAndData.put(data);

            synchronized (mLock) {
                if (!mIsWritable) {
                    IoUtils.closeQuietly(outputStream);
                    return -1;
                }

                try {
                    byte[] checksum = new byte[DIGEST_SIZE_BYTES];
                    outputStream.write(checksum, 0, DIGEST_SIZE_BYTES);
@@ -419,6 +424,9 @@ public class PersistentDataBlockService extends SystemService {

                if (ret < 0) {
                    Slog.e(TAG, "failed to wipe persistent partition");
                } else {
                    mIsWritable = false;
                    Slog.i(TAG, "persistent partition now wiped and unwritable");
                }
            }
        }