Merge "Don't allow expired blobs to be accessed." into rvc-dev

This commit is contained in:
Sudheer Shanka
2020-05-27 20:10:04 +00:00
committed by Android (Google) Code Review
6 changed files with 55 additions and 9 deletions

View File

@@ -212,7 +212,10 @@ class BlobMetadata {
} }
boolean isAccessAllowedForCaller(@NonNull String callingPackage, int callingUid) { boolean isAccessAllowedForCaller(@NonNull String callingPackage, int callingUid) {
// TODO: verify blob is still valid (expiryTime is not elapsed) // Don't allow the blob to be accessed after it's expiry time has passed.
if (getBlobHandle().isExpired()) {
return false;
}
synchronized (mMetadataLock) { synchronized (mMetadataLock) {
// Check if packageName already holds a lease on the blob. // Check if packageName already holds a lease on the blob.
for (int i = 0, size = mLeasees.size(); i < size; ++i) { for (int i = 0, size = mLeasees.size(); i < size; ++i) {

View File

@@ -1059,6 +1059,18 @@ public class BlobStoreManagerService extends SystemService {
} }
} }
boolean isBlobAvailable(long blobId, int userId) {
synchronized (mBlobsLock) {
final ArrayMap<BlobHandle, BlobMetadata> userBlobs = getUserBlobsLocked(userId);
for (BlobMetadata blobMetadata : userBlobs.values()) {
if (blobMetadata.getBlobId() == blobId) {
return true;
}
}
return false;
}
}
@GuardedBy("mBlobsLock") @GuardedBy("mBlobsLock")
private void dumpSessionsLocked(IndentingPrintWriter fout, DumpArgs dumpArgs) { private void dumpSessionsLocked(IndentingPrintWriter fout, DumpArgs dumpArgs) {
for (int i = 0, userCount = mSessions.size(); i < userCount; ++i) { for (int i = 0, userCount = mSessions.size(); i < userCount; ++i) {

View File

@@ -46,6 +46,8 @@ class BlobStoreManagerShellCommand extends ShellCommand {
return runDeleteBlob(pw); return runDeleteBlob(pw);
case "idle-maintenance": case "idle-maintenance":
return runIdleMaintenance(pw); return runIdleMaintenance(pw);
case "query-blob-existence":
return runQueryBlobExistence(pw);
default: default:
return handleDefaultCommands(cmd); return handleDefaultCommands(cmd);
} }
@@ -91,6 +93,16 @@ class BlobStoreManagerShellCommand extends ShellCommand {
return 0; return 0;
} }
private int runQueryBlobExistence(PrintWriter pw) {
final ParsedArgs args = new ParsedArgs();
if (parseOptions(pw, args) < 0) {
return -1;
}
pw.println(mService.isBlobAvailable(args.blobId, args.userId) ? 1 : 0);
return 0;
}
@Override @Override
public void onHelp() { public void onHelp() {
final PrintWriter pw = getOutPrintWriter(); final PrintWriter pw = getOutPrintWriter();
@@ -121,6 +133,8 @@ class BlobStoreManagerShellCommand extends ShellCommand {
pw.println(" --tag: Tag of the blob to delete."); pw.println(" --tag: Tag of the blob to delete.");
pw.println("idle-maintenance"); pw.println("idle-maintenance");
pw.println(" Run idle maintenance which takes care of removing stale data."); pw.println(" Run idle maintenance which takes care of removing stale data.");
pw.println("query-blob-existence [-b BLOB_ID]");
pw.println(" Prints 1 if blob exists, otherwise 0.");
pw.println(); pw.println();
} }
@@ -147,6 +161,9 @@ class BlobStoreManagerShellCommand extends ShellCommand {
case "--tag": case "--tag":
args.tag = getNextArgRequired(); args.tag = getNextArgRequired();
break; break;
case "-b":
args.blobId = Long.parseLong(getNextArgRequired());
break;
default: default:
pw.println("Error: unknown option '" + opt + "'"); pw.println("Error: unknown option '" + opt + "'");
return -1; return -1;
@@ -166,6 +183,7 @@ class BlobStoreManagerShellCommand extends ShellCommand {
public long expiryTimeMillis; public long expiryTimeMillis;
public CharSequence label; public CharSequence label;
public String tag; public String tag;
public long blobId;
public BlobHandle getBlobHandle() { public BlobHandle getBlobHandle() {
return BlobHandle.create(algorithm, digest, label, expiryTimeMillis, tag); return BlobHandle.create(algorithm, digest, label, expiryTimeMillis, tag);

View File

@@ -18,6 +18,7 @@ java_library {
static_libs: [ static_libs: [
"truth-prebuilt", "truth-prebuilt",
"androidx.test.uiautomator_uiautomator", "androidx.test.uiautomator_uiautomator",
"androidx.test.ext.junit",
], ],
sdk_version: "test_current", sdk_version: "test_current",
} }

View File

@@ -42,6 +42,7 @@ public class DummyBlobData {
private final File mFile; private final File mFile;
private final long mFileSize; private final long mFileSize;
private final CharSequence mLabel; private final CharSequence mLabel;
private final long mExpiryDurationMs;
byte[] mFileDigest; byte[] mFileDigest;
long mExpiryTimeMs; long mExpiryTimeMs;
@@ -51,6 +52,7 @@ public class DummyBlobData {
mFile = new File(builder.getContext().getFilesDir(), builder.getFileName()); mFile = new File(builder.getContext().getFilesDir(), builder.getFileName());
mFileSize = builder.getFileSize(); mFileSize = builder.getFileSize();
mLabel = builder.getLabel(); mLabel = builder.getLabel();
mExpiryDurationMs = builder.getExpiryDurationMs();
} }
public static class Builder { public static class Builder {
@@ -59,6 +61,7 @@ public class DummyBlobData {
private long mFileSize = DEFAULT_SIZE_BYTES; private long mFileSize = DEFAULT_SIZE_BYTES;
private CharSequence mLabel = "Test label"; private CharSequence mLabel = "Test label";
private String mFileName = "blob_" + System.nanoTime(); private String mFileName = "blob_" + System.nanoTime();
private long mExpiryDurationMs = TimeUnit.DAYS.toMillis(1);
public Builder(Context context) { public Builder(Context context) {
mContext = context; mContext = context;
@@ -104,6 +107,15 @@ public class DummyBlobData {
return mFileName; return mFileName;
} }
public Builder setExpiryDurationMs(long durationMs) {
mExpiryDurationMs = durationMs;
return this;
}
public long getExpiryDurationMs() {
return mExpiryDurationMs;
}
public DummyBlobData build() { public DummyBlobData build() {
return new DummyBlobData(this); return new DummyBlobData(this);
} }
@@ -114,7 +126,7 @@ public class DummyBlobData {
writeRandomData(file, mFileSize); writeRandomData(file, mFileSize);
} }
mFileDigest = FileUtils.digest(mFile, "SHA-256"); mFileDigest = FileUtils.digest(mFile, "SHA-256");
mExpiryTimeMs = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1); mExpiryTimeMs = System.currentTimeMillis() + mExpiryDurationMs;
} }
public BlobHandle getBlobHandle() throws Exception { public BlobHandle getBlobHandle() throws Exception {

View File

@@ -18,7 +18,6 @@ package com.android.utils.blob;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.app.blob.BlobHandle; import android.app.blob.BlobHandle;
import android.app.blob.BlobStoreManager; import android.app.blob.BlobStoreManager;
import android.app.blob.LeaseInfo; import android.app.blob.LeaseInfo;
@@ -27,6 +26,7 @@ import android.content.res.Resources;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.util.Log; import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiDevice;
import java.io.FileInputStream; import java.io.FileInputStream;
@@ -149,14 +149,14 @@ public class Utils {
assertThat(leaseInfo.getDescription()).isEqualTo(description); assertThat(leaseInfo.getDescription()).isEqualTo(description);
} }
public static void triggerIdleMaintenance(Instrumentation instrumentation) throws IOException { public static void triggerIdleMaintenance() throws IOException {
runShellCmd(instrumentation, "cmd blob_store idle-maintenance"); runShellCmd("cmd blob_store idle-maintenance");
} }
private static String runShellCmd(Instrumentation instrumentation, public static String runShellCmd(String cmd) throws IOException {
String cmd) throws IOException { final UiDevice uiDevice = UiDevice.getInstance(
final UiDevice uiDevice = UiDevice.getInstance(instrumentation); InstrumentationRegistry.getInstrumentation());
final String result = uiDevice.executeShellCommand(cmd); final String result = uiDevice.executeShellCommand(cmd).trim();
Log.i(TAG, "Output of '" + cmd + "': '" + result + "'"); Log.i(TAG, "Output of '" + cmd + "': '" + result + "'");
return result; return result;
} }