summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles He <qiurui@google.com>2016-11-24 14:05:00 +0000
committerSean McCreary <mccreary@mcwest.org>2017-03-22 12:40:21 -0600
commit2ffca13ae484c15087ddd14f69d3e593b51fc904 (patch)
tree45a12b708c4996fa54c54936072f2901e58004d9
parent44b0bdc995fbc21b294e1cdca3a5aa63feeb4951 (diff)
downloadframeworks_base-2ffca13ae484c15087ddd14f69d3e593b51fc904.zip
frameworks_base-2ffca13ae484c15087ddd14f69d3e593b51fc904.tar.gz
frameworks_base-2ffca13ae484c15087ddd14f69d3e593b51fc904.tar.bz2
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 CVE-2017-0498 Change-Id: If3f024a1611366c0677a996705724458094fcfad (cherry picked from commit a629c772f4a7a5ddf7ff9f78fb19f7ab86c2a9c2) (cherry picked from commit a9437bd1caeeb38780d920a81bde8cc7ca280fe0) (cherry picked from commit 1c4d535d0806dbeb6d2fa5cea0373cbd9ab6d33b)
-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 0ffdf68..10ffe84 100644
--- a/core/java/android/service/persistentdata/PersistentDataBlockManager.java
+++ b/core/java/android/service/persistentdata/PersistentDataBlockManager.java
@@ -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 {
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index 94316fe..32b183b 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -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();
@@ -78,6 +77,7 @@ public class PersistentDataBlockService extends SystemService {
private int mAllowedUid = -1;
private long mBlockDeviceSize;
+ private boolean mIsWritable = true;
public PersistentDataBlockService(Context context) {
super(context);
@@ -349,6 +349,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);
@@ -423,6 +428,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");
}
}
}