summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Charles He <qiurui@google.com> 2016-12-29 10:34:04 +0000
committer android-build-merger <android-build-merger@google.com> 2016-12-29 10:34:04 +0000
commit8bcdab7e6f334a653d8a04a7c0c411a3c3860904 (patch)
tree0cd337f952d9832bbccb4cf2c5caab128f6f4cf5
parent7cec76de0fed67bff9feace9ff44e337744cb64b (diff)
parent9a47fa7fc00c73ccc84416ea57bb58a0c9189c18 (diff)
Prevent writing to FRP partition during factory reset. am: a9437bd1ca am: 2ce5c4320d am: 133ff4d611 am: 00a581f882 am: e5156ec1e9
am: 9a47fa7fc0 Change-Id: Ifb9f5b177f7c031352e6e9cf308e6295f7c60074
-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 cfeed51da86f..08316590e2d1 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 680547ab9365..13a2103ba55d 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -52,15 +52,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();
@@ -83,6 +82,7 @@ public class PersistentDataBlockService extends SystemService {
private int mAllowedUid = -1;
private long mBlockDeviceSize;
+ private boolean mIsWritable = true;
public PersistentDataBlockService(Context context) {
super(context);
@@ -368,6 +368,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);
@@ -442,6 +447,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");
}
}
}