summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles He <qiurui@google.com>2016-11-24 14:05:00 +0000
committergitbuildkicker <android-build@google.com>2017-01-20 10:27:32 -0800
commit215a820b8a2214d727cdb81ed0116034f09b3ef3 (patch)
treeea3b7a4c10395f164874565607cb469c2f65aebb
parentc639cb67b4310b80aeddb4184dc191a24b23e9ca (diff)
downloadbase-215a820b8a2214d727cdb81ed0116034f09b3ef3.tar.gz
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 a629c772f4a7a5ddf7ff9f78fb19f7ab86c2a9c2) (cherry picked from commit a9437bd1caeeb38780d920a81bde8cc7ca280fe0)
-rw-r--r--core/java/android/service/persistentdata/PersistentDataBlockManager.java5
-rw-r--r--services/core/java/com/android/server/PersistentDataBlockService.java20
2 files changed, 19 insertions, 6 deletions
diff --git a/core/java/android/service/persistentdata/PersistentDataBlockManager.java b/core/java/android/service/persistentdata/PersistentDataBlockManager.java
index 0f92ed04a457..8e8c019e6398 100644
--- a/core/java/android/service/persistentdata/PersistentDataBlockManager.java
+++ b/core/java/android/service/persistentdata/PersistentDataBlockManager.java
@@ -79,6 +79,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) {
@@ -129,6 +132,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 {
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index 080b46c24a2f..a989a1703bea 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -53,15 +53,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();
@@ -84,6 +83,7 @@ public class PersistentDataBlockService extends SystemService {
private int mAllowedUid = -1;
private long mBlockDeviceSize;
+ private boolean mIsWritable = true;
public PersistentDataBlockService(Context context) {
super(context);
@@ -377,6 +377,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);
@@ -451,6 +456,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");
}
}
}