diff options
author | Sudheer Shanka <sudheersai@google.com> | 2020-03-12 13:20:46 -0700 |
---|---|---|
committer | Sudheer Shanka <sudheersai@google.com> | 2020-03-12 22:32:49 -0700 |
commit | c6c7994c0f86d77c645cfa0be02b91ab961a487c (patch) | |
tree | 631f3b2370f2a885c054629107b1d69bc85a695f /apex/blobstore/service | |
parent | 03b8a41461b7cf7b4b65817259b7a9587041f7d6 (diff) |
Add @TestApis getLeasedBlobs() and getLeaseInfo().
+ Rename AccessorInfo to LeaseInfo.
Bug: 150619869
Test: atest --test-mapping apex/blobstore
Change-Id: I257b784350aa8bcf39847a3fd1a91977e4ff174a
Diffstat (limited to 'apex/blobstore/service')
3 files changed, 100 insertions, 4 deletions
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java index 970766d2c8a6..8b640ca75698 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java @@ -38,6 +38,7 @@ import static com.android.server.blob.BlobStoreUtils.getPackageResources; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.blob.BlobHandle; +import android.app.blob.LeaseInfo; import android.content.Context; import android.content.res.ResourceId; import android.content.res.Resources; @@ -281,6 +282,25 @@ class BlobMetadata { return false; } + @Nullable + LeaseInfo getLeaseInfo(@NonNull String packageName, int uid) { + synchronized (mMetadataLock) { + for (int i = 0, size = mLeasees.size(); i < size; ++i) { + final Leasee leasee = mLeasees.valueAt(i); + if (leasee.uid == uid && leasee.packageName.equals(packageName)) { + final int descriptionResId = leasee.descriptionResEntryName == null + ? Resources.ID_NULL + : BlobStoreUtils.getDescriptionResourceId( + mContext, leasee.descriptionResEntryName, leasee.packageName, + UserHandle.getUserId(leasee.uid)); + return new LeaseInfo(packageName, leasee.expiryTimeMillis, + descriptionResId, leasee.description); + } + } + } + return null; + } + void forEachLeasee(Consumer<Leasee> consumer) { mLeasees.forEach(consumer); } diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java index 53a97cefa59b..f4b8f0f39e85 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java @@ -45,11 +45,11 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; -import android.app.blob.AccessorInfo; import android.app.blob.BlobHandle; import android.app.blob.BlobInfo; import android.app.blob.IBlobStoreManager; import android.app.blob.IBlobStoreSession; +import android.app.blob.LeaseInfo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -454,17 +454,17 @@ public class BlobStoreManagerService extends SystemService { return packageResources; }; getUserBlobsLocked(userId).forEach((blobHandle, blobMetadata) -> { - final ArrayList<AccessorInfo> accessorInfos = new ArrayList<>(); + final ArrayList<LeaseInfo> leaseInfos = new ArrayList<>(); blobMetadata.forEachLeasee(leasee -> { final int descriptionResId = leasee.descriptionResEntryName == null ? Resources.ID_NULL : getDescriptionResourceId(resourcesGetter.apply(leasee.packageName), leasee.descriptionResEntryName, leasee.packageName); - accessorInfos.add(new AccessorInfo(leasee.packageName, leasee.expiryTimeMillis, + leaseInfos.add(new LeaseInfo(leasee.packageName, leasee.expiryTimeMillis, descriptionResId, leasee.description)); }); blobInfos.add(new BlobInfo(blobMetadata.getBlobId(), - blobHandle.getExpiryTimeMillis(), blobHandle.getLabel(), accessorInfos)); + blobHandle.getExpiryTimeMillis(), blobHandle.getLabel(), leaseInfos)); }); } return blobInfos; @@ -482,6 +482,31 @@ public class BlobStoreManagerService extends SystemService { } } + private List<BlobHandle> getLeasedBlobsInternal(int callingUid, + @NonNull String callingPackage) { + final ArrayList<BlobHandle> leasedBlobs = new ArrayList<>(); + forEachBlobInUser(blobMetadata -> { + if (blobMetadata.isALeasee(callingPackage, callingUid)) { + leasedBlobs.add(blobMetadata.getBlobHandle()); + } + }, UserHandle.getUserId(callingUid)); + return leasedBlobs; + } + + private LeaseInfo getLeaseInfoInternal(BlobHandle blobHandle, + int callingUid, @NonNull String callingPackage) { + synchronized (mBlobsLock) { + final BlobMetadata blobMetadata = getUserBlobsLocked(UserHandle.getUserId(callingUid)) + .get(blobHandle); + if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller( + callingPackage, callingUid)) { + throw new SecurityException("Caller not allowed to access " + blobHandle + + "; callingUid=" + callingUid + ", callingPackage=" + callingPackage); + } + return blobMetadata.getLeaseInfo(callingPackage, callingUid); + } + } + private void verifyCallingPackage(int callingUid, String callingPackage) { if (mPackageManagerInternal.getPackageUid( callingPackage, 0, UserHandle.getUserId(callingUid)) != callingUid) { @@ -1267,6 +1292,12 @@ public class BlobStoreManagerService extends SystemService { final int callingUid = Binder.getCallingUid(); verifyCallingPackage(callingUid, packageName); + if (Process.isIsolated(callingUid) || mPackageManagerInternal.isInstantApp( + packageName, UserHandle.getUserId(callingUid))) { + throw new SecurityException("Caller not allowed to open blob; " + + "callingUid=" + callingUid + ", callingPackage=" + packageName); + } + try { acquireLeaseInternal(blobHandle, descriptionResId, description, leaseExpiryTimeMillis, callingUid, packageName); @@ -1284,6 +1315,12 @@ public class BlobStoreManagerService extends SystemService { final int callingUid = Binder.getCallingUid(); verifyCallingPackage(callingUid, packageName); + if (Process.isIsolated(callingUid) || mPackageManagerInternal.isInstantApp( + packageName, UserHandle.getUserId(callingUid))) { + throw new SecurityException("Caller not allowed to open blob; " + + "callingUid=" + callingUid + ", callingPackage=" + packageName); + } + releaseLeaseInternal(blobHandle, callingUid, packageName); } @@ -1320,6 +1357,36 @@ public class BlobStoreManagerService extends SystemService { } @Override + @NonNull + public List<BlobHandle> getLeasedBlobs(@NonNull String packageName) { + Objects.requireNonNull(packageName, "packageName must not be null"); + + final int callingUid = Binder.getCallingUid(); + verifyCallingPackage(callingUid, packageName); + + return getLeasedBlobsInternal(callingUid, packageName); + } + + @Override + @Nullable + public LeaseInfo getLeaseInfo(@NonNull BlobHandle blobHandle, @NonNull String packageName) { + Objects.requireNonNull(blobHandle, "blobHandle must not be null"); + blobHandle.assertIsValid(); + Objects.requireNonNull(packageName, "packageName must not be null"); + + final int callingUid = Binder.getCallingUid(); + verifyCallingPackage(callingUid, packageName); + + if (Process.isIsolated(callingUid) || mPackageManagerInternal.isInstantApp( + packageName, UserHandle.getUserId(callingUid))) { + throw new SecurityException("Caller not allowed to open blob; " + + "callingUid=" + callingUid + ", callingPackage=" + packageName); + } + + return getLeaseInfoInternal(blobHandle, callingUid, packageName); + } + + @Override public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter writer, @Nullable String[] args) { // TODO: add proto-based version of this. diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreUtils.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreUtils.java index 6af540acd6a4..fabce766c237 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreUtils.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreUtils.java @@ -47,4 +47,13 @@ class BlobStoreUtils { @NonNull String resourceEntryName, @NonNull String packageName) { return resources.getIdentifier(resourceEntryName, DESC_RES_TYPE_STRING, packageName); } + + @IdRes + static int getDescriptionResourceId(@NonNull Context context, + @NonNull String resourceEntryName, @NonNull String packageName, int userId) { + final Resources resources = getPackageResources(context, packageName, userId); + return resources == null + ? Resources.ID_NULL + : getDescriptionResourceId(resources, resourceEntryName, packageName); + } } |