diff options
author | Dianne Hackborn <hackbod@google.com> | 2014-11-21 00:43:51 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-11-21 00:43:51 +0000 |
commit | 377d6f00dc2ab42df501fd12b23e1dab54cea6b7 (patch) | |
tree | 68ca3dd6db17c060f07f573362c1a9d66019bfc5 | |
parent | 0d4a4e6e59267ed58d9fe44303e400877aa1caab (diff) | |
parent | 42fec57f3addfb1958f814b5d6772ff81341ba20 (diff) | |
download | frameworks_base-377d6f00dc2ab42df501fd12b23e1dab54cea6b7.zip frameworks_base-377d6f00dc2ab42df501fd12b23e1dab54cea6b7.tar.gz frameworks_base-377d6f00dc2ab42df501fd12b23e1dab54cea6b7.tar.bz2 |
am 42fec57f: am d9968438: Merge "Fix issue with call backs from media process." into lmp-mr1-dev
* commit '42fec57f3addfb1958f814b5d6772ff81341ba20':
Fix issue with call backs from media process.
17 files changed, 221 insertions, 81 deletions
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java index 948c9a2..bd34a9c 100644 --- a/cmds/content/src/com/android/commands/content/Content.java +++ b/cmds/content/src/com/android/commands/content/Content.java @@ -501,7 +501,7 @@ public class Content { @Override public void onExecute(IContentProvider provider) throws Exception { - final ParcelFileDescriptor fd = provider.openFile(null, mUri, "r", null); + final ParcelFileDescriptor fd = provider.openFile(null, mUri, "r", null, null); copy(new FileInputStream(fd.getFileDescriptor()), System.out); } diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index c3028b7..6ec48e5 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -1186,6 +1186,18 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM return true; } + case CHECK_PERMISSION_WITH_TOKEN_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + String perm = data.readString(); + int pid = data.readInt(); + int uid = data.readInt(); + IBinder token = data.readStrongBinder(); + int res = checkPermissionWithToken(perm, pid, uid, token); + reply.writeNoException(); + reply.writeInt(res); + return true; + } + case CHECK_URI_PERMISSION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Uri uri = Uri.CREATOR.createFromParcel(data); @@ -1193,7 +1205,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM int uid = data.readInt(); int mode = data.readInt(); int userId = data.readInt(); - int res = checkUriPermission(uri, pid, uid, mode, userId); + IBinder callerToken = data.readStrongBinder(); + int res = checkUriPermission(uri, pid, uid, mode, userId, callerToken); reply.writeNoException(); reply.writeInt(res); return true; @@ -3742,7 +3755,7 @@ class ActivityManagerProxy implements IActivityManager mRemote.transact(GET_INTENT_SENDER_TRANSACTION, data, reply, 0); reply.readException(); IIntentSender res = IIntentSender.Stub.asInterface( - reply.readStrongBinder()); + reply.readStrongBinder()); data.recycle(); reply.recycle(); return res; @@ -3851,6 +3864,22 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); return res; } + public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) + throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeString(permission); + data.writeInt(pid); + data.writeInt(uid); + data.writeStrongBinder(callerToken); + mRemote.transact(CHECK_PERMISSION_WITH_TOKEN_TRANSACTION, data, reply, 0); + reply.readException(); + int res = reply.readInt(); + data.recycle(); + reply.recycle(); + return res; + } public boolean clearApplicationUserData(final String packageName, final IPackageDataObserver observer, final int userId) throws RemoteException { Parcel data = Parcel.obtain(); @@ -3866,8 +3895,8 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); return res; } - public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId) - throws RemoteException { + public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId, + IBinder callerToken) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IActivityManager.descriptor); @@ -3876,6 +3905,7 @@ class ActivityManagerProxy implements IActivityManager data.writeInt(uid); data.writeInt(mode); data.writeInt(userId); + data.writeStrongBinder(callerToken); mRemote.transact(CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0); reply.readException(); int res = reply.readInt(); diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 7fafc38..1de9b47 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1863,6 +1863,21 @@ class ContextImpl extends Context { } } + /** @hide */ + @Override + public int checkPermission(String permission, int pid, int uid, IBinder callerToken) { + if (permission == null) { + throw new IllegalArgumentException("permission is null"); + } + + try { + return ActivityManagerNative.getDefault().checkPermissionWithToken( + permission, pid, uid, callerToken); + } catch (RemoteException e) { + return PackageManager.PERMISSION_DENIED; + } + } + @Override public int checkCallingPermission(String permission) { if (permission == null) { @@ -1951,7 +1966,19 @@ class ContextImpl extends Context { try { return ActivityManagerNative.getDefault().checkUriPermission( ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags, - resolveUserId(uri)); + resolveUserId(uri), null); + } catch (RemoteException e) { + return PackageManager.PERMISSION_DENIED; + } + } + + /** @hide */ + @Override + public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) { + try { + return ActivityManagerNative.getDefault().checkUriPermission( + ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags, + resolveUserId(uri), callerToken); } catch (RemoteException e) { return PackageManager.PERMISSION_DENIED; } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 6433f3f..5362303 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -219,9 +219,11 @@ public interface IActivityManager extends IInterface { public int checkPermission(String permission, int pid, int uid) throws RemoteException; - - public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId) + public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) throws RemoteException; + + public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId, + IBinder callerToken) throws RemoteException; public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, int mode, int userId) throws RemoteException; public void revokeUriPermission(IApplicationThread caller, Uri uri, int mode, int userId) @@ -785,4 +787,5 @@ public interface IActivityManager extends IInterface { int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238; int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239; int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240; + int CHECK_PERMISSION_WITH_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+241; } diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 4c82efd..360f308 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -31,6 +31,7 @@ import android.os.AsyncTask; import android.os.Binder; import android.os.Bundle; import android.os.CancellationSignal; +import android.os.IBinder; import android.os.ICancellationSignal; import android.os.OperationCanceledException; import android.os.ParcelFileDescriptor; @@ -201,7 +202,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { ICancellationSignal cancellationSignal) { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); - if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { + if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return rejectQuery(uri, projection, selection, selectionArgs, sortOrder, CancellationSignal.fromTransport(cancellationSignal)); } @@ -227,7 +228,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = getUriWithoutUserId(uri); - if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { + if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return rejectInsert(uri, initialValues); } final String original = setCallingPackage(callingPkg); @@ -242,7 +243,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); - if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { + if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; } final String original = setCallingPackage(callingPkg); @@ -270,13 +271,13 @@ public abstract class ContentProvider implements ComponentCallbacks2 { operations.set(i, operation); } if (operation.isReadOperation()) { - if (enforceReadPermission(callingPkg, uri) + if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { throw new OperationApplicationException("App op not allowed", 0); } } if (operation.isWriteOperation()) { - if (enforceWritePermission(callingPkg, uri) + if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { throw new OperationApplicationException("App op not allowed", 0); } @@ -301,7 +302,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); - if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { + if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; } final String original = setCallingPackage(callingPkg); @@ -317,7 +318,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { String[] selectionArgs) { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); - if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { + if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; } final String original = setCallingPackage(callingPkg); @@ -330,11 +331,11 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public ParcelFileDescriptor openFile( - String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal) - throws FileNotFoundException { + String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal, + IBinder callerToken) throws FileNotFoundException { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); - enforceFilePermission(callingPkg, uri, mode); + enforceFilePermission(callingPkg, uri, mode, callerToken); final String original = setCallingPackage(callingPkg); try { return ContentProvider.this.openFile( @@ -350,7 +351,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { throws FileNotFoundException { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); - enforceFilePermission(callingPkg, uri, mode); + enforceFilePermission(callingPkg, uri, mode, null); final String original = setCallingPackage(callingPkg); try { return ContentProvider.this.openAssetFile( @@ -382,7 +383,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException { validateIncomingUri(uri); uri = getUriWithoutUserId(uri); - enforceFilePermission(callingPkg, uri, "r"); + enforceFilePermission(callingPkg, uri, "r", null); final String original = setCallingPackage(callingPkg); try { return ContentProvider.this.openTypedAssetFile( @@ -402,7 +403,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = getUriWithoutUserId(uri); - if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { + if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return null; } final String original = setCallingPackage(callingPkg); @@ -418,7 +419,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = getUriWithoutUserId(uri); - if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { + if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return null; } final String original = setCallingPackage(callingPkg); @@ -429,29 +430,33 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } } - private void enforceFilePermission(String callingPkg, Uri uri, String mode) - throws FileNotFoundException, SecurityException { + private void enforceFilePermission(String callingPkg, Uri uri, String mode, + IBinder callerToken) throws FileNotFoundException, SecurityException { if (mode != null && mode.indexOf('w') != -1) { - if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { + if (enforceWritePermission(callingPkg, uri, callerToken) + != AppOpsManager.MODE_ALLOWED) { throw new FileNotFoundException("App op not allowed"); } } else { - if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { + if (enforceReadPermission(callingPkg, uri, callerToken) + != AppOpsManager.MODE_ALLOWED) { throw new FileNotFoundException("App op not allowed"); } } } - private int enforceReadPermission(String callingPkg, Uri uri) throws SecurityException { - enforceReadPermissionInner(uri); + private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken) + throws SecurityException { + enforceReadPermissionInner(uri, callerToken); if (mReadOp != AppOpsManager.OP_NONE) { return mAppOpsManager.noteOp(mReadOp, Binder.getCallingUid(), callingPkg); } return AppOpsManager.MODE_ALLOWED; } - private int enforceWritePermission(String callingPkg, Uri uri) throws SecurityException { - enforceWritePermissionInner(uri); + private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken) + throws SecurityException { + enforceWritePermissionInner(uri, callerToken); if (mWriteOp != AppOpsManager.OP_NONE) { return mAppOpsManager.noteOp(mWriteOp, Binder.getCallingUid(), callingPkg); } @@ -467,7 +472,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } /** {@hide} */ - protected void enforceReadPermissionInner(Uri uri) throws SecurityException { + protected void enforceReadPermissionInner(Uri uri, IBinder callerToken) + throws SecurityException { final Context context = getContext(); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); @@ -480,7 +486,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 { if (mExported && checkUser(pid, uid, context)) { final String componentPerm = getReadPermission(); if (componentPerm != null) { - if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) { + if (context.checkPermission(componentPerm, pid, uid, callerToken) + == PERMISSION_GRANTED) { return; } else { missingPerm = componentPerm; @@ -497,7 +504,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 { for (PathPermission pp : pps) { final String pathPerm = pp.getReadPermission(); if (pathPerm != null && pp.match(path)) { - if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) { + if (context.checkPermission(pathPerm, pid, uid, callerToken) + == PERMISSION_GRANTED) { return; } else { // any denied <path-permission> means we lose @@ -518,8 +526,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 { final int callingUserId = UserHandle.getUserId(uid); final Uri userUri = (mSingleUser && !UserHandle.isSameUser(mMyUid, uid)) ? maybeAddUserId(uri, callingUserId) : uri; - if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION) - == PERMISSION_GRANTED) { + if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION, + callerToken) == PERMISSION_GRANTED) { return; } @@ -532,7 +540,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } /** {@hide} */ - protected void enforceWritePermissionInner(Uri uri) throws SecurityException { + protected void enforceWritePermissionInner(Uri uri, IBinder callerToken) + throws SecurityException { final Context context = getContext(); final int pid = Binder.getCallingPid(); final int uid = Binder.getCallingUid(); @@ -545,7 +554,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 { if (mExported && checkUser(pid, uid, context)) { final String componentPerm = getWritePermission(); if (componentPerm != null) { - if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) { + if (context.checkPermission(componentPerm, pid, uid, callerToken) + == PERMISSION_GRANTED) { return; } else { missingPerm = componentPerm; @@ -562,7 +572,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 { for (PathPermission pp : pps) { final String pathPerm = pp.getWritePermission(); if (pathPerm != null && pp.match(path)) { - if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) { + if (context.checkPermission(pathPerm, pid, uid, callerToken) + == PERMISSION_GRANTED) { return; } else { // any denied <path-permission> means we lose @@ -580,8 +591,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } // last chance, check against any uri grants - if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION) - == PERMISSION_GRANTED) { + if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, + callerToken) == PERMISSION_GRANTED) { return; } diff --git a/core/java/android/content/ContentProviderClient.java b/core/java/android/content/ContentProviderClient.java index cefc27f..e15ac94 100644 --- a/core/java/android/content/ContentProviderClient.java +++ b/core/java/android/content/ContentProviderClient.java @@ -288,7 +288,7 @@ public class ContentProviderClient { remoteSignal = mContentProvider.createCancellationSignal(); signal.setRemote(remoteSignal); } - return mContentProvider.openFile(mPackageName, url, mode, remoteSignal); + return mContentProvider.openFile(mPackageName, url, mode, remoteSignal, null); } catch (DeadObjectException e) { if (!mStable) { mContentResolver.unstableProviderDied(mContentProvider); diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java index 39286d6..f2e7fc4 100644 --- a/core/java/android/content/ContentProviderNative.java +++ b/core/java/android/content/ContentProviderNative.java @@ -234,9 +234,10 @@ abstract public class ContentProviderNative extends Binder implements IContentPr String mode = data.readString(); ICancellationSignal signal = ICancellationSignal.Stub.asInterface( data.readStrongBinder()); + IBinder callerToken = data.readStrongBinder(); ParcelFileDescriptor fd; - fd = openFile(callingPkg, url, mode, signal); + fd = openFile(callingPkg, url, mode, signal, callerToken); reply.writeNoException(); if (fd != null) { reply.writeInt(1); @@ -575,7 +576,7 @@ final class ContentProviderProxy implements IContentProvider @Override public ParcelFileDescriptor openFile( - String callingPkg, Uri url, String mode, ICancellationSignal signal) + String callingPkg, Uri url, String mode, ICancellationSignal signal, IBinder token) throws RemoteException, FileNotFoundException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); @@ -586,6 +587,7 @@ final class ContentProviderProxy implements IContentProvider url.writeToParcel(data, 0); data.writeString(mode); data.writeStrongBinder(signal != null ? signal.asBinder() : null); + data.writeStrongBinder(token); mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index c9b7d0a..a73ba74 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -37,6 +37,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.StatFs; import android.os.UserHandle; @@ -2864,10 +2865,10 @@ public abstract class Context { /** * Use with {@link #getSystemService} to retrieve a {@link - * android.app.UsageStatsManager} for interacting with the status bar. + * android.app.usage.UsageStatsManager} for interacting with the status bar. * * @see #getSystemService - * @see android.app.UsageStatsManager + * @see android.app.usage.UsageStatsManager * @hide */ public static final String USAGE_STATS_SERVICE = "usagestats"; @@ -2921,6 +2922,11 @@ public abstract class Context { @PackageManager.PermissionResult public abstract int checkPermission(@NonNull String permission, int pid, int uid); + /** @hide */ + @PackageManager.PermissionResult + public abstract int checkPermission(@NonNull String permission, int pid, int uid, + IBinder callerToken); + /** * Determine whether the calling process of an IPC you are handling has been * granted a particular permission. This is basically the same as calling @@ -3108,6 +3114,10 @@ public abstract class Context { public abstract int checkUriPermission(Uri uri, int pid, int uid, @Intent.AccessUriMode int modeFlags); + /** @hide */ + public abstract int checkUriPermission(Uri uri, int pid, int uid, + @Intent.AccessUriMode int modeFlags, IBinder callerToken); + /** * Determine whether the calling process and user ID has been * granted permission to access a specific URI. This is basically diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index ad7c350..cfae1cf 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -29,6 +29,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.UserHandle; import android.view.DisplayAdjustments; @@ -566,6 +567,12 @@ public class ContextWrapper extends Context { return mBase.checkPermission(permission, pid, uid); } + /** @hide */ + @Override + public int checkPermission(String permission, int pid, int uid, IBinder callerToken) { + return mBase.checkPermission(permission, pid, uid, callerToken); + } + @Override public int checkCallingPermission(String permission) { return mBase.checkCallingPermission(permission); @@ -608,6 +615,12 @@ public class ContextWrapper extends Context { return mBase.checkUriPermission(uri, pid, uid, modeFlags); } + /** @hide */ + @Override + public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) { + return mBase.checkUriPermission(uri, pid, uid, modeFlags, callerToken); + } + @Override public int checkCallingUriPermission(Uri uri, int modeFlags) { return mBase.checkCallingUriPermission(uri, modeFlags); diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java index f92a404..f858406 100644 --- a/core/java/android/content/IContentProvider.java +++ b/core/java/android/content/IContentProvider.java @@ -47,7 +47,8 @@ public interface IContentProvider extends IInterface { public int update(String callingPkg, Uri url, ContentValues values, String selection, String[] selectionArgs) throws RemoteException; public ParcelFileDescriptor openFile( - String callingPkg, Uri url, String mode, ICancellationSignal signal) + String callingPkg, Uri url, String mode, ICancellationSignal signal, + IBinder callerToken) throws RemoteException, FileNotFoundException; public AssetFileDescriptor openAssetFile( String callingPkg, Uri url, String mode, ICancellationSignal signal) diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java index 932e873..1316471 100644 --- a/core/java/android/provider/DocumentsProvider.java +++ b/core/java/android/provider/DocumentsProvider.java @@ -637,7 +637,7 @@ public abstract class DocumentsProvider extends ContentProvider { final Bundle out = new Bundle(); try { if (METHOD_CREATE_DOCUMENT.equals(method)) { - enforceWritePermissionInner(documentUri); + enforceWritePermissionInner(documentUri, null); final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE); final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME); @@ -651,7 +651,7 @@ public abstract class DocumentsProvider extends ContentProvider { out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri); } else if (METHOD_RENAME_DOCUMENT.equals(method)) { - enforceWritePermissionInner(documentUri); + enforceWritePermissionInner(documentUri, null); final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME); final String newDocumentId = renameDocument(documentId, displayName); @@ -675,7 +675,7 @@ public abstract class DocumentsProvider extends ContentProvider { } } else if (METHOD_DELETE_DOCUMENT.equals(method)) { - enforceWritePermissionInner(documentUri); + enforceWritePermissionInner(documentUri, null); deleteDocument(documentId); // Document no longer exists, clean up any grants diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index fd54892..f0fb9e6 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -838,10 +838,12 @@ public final class ActivityManagerService extends ActivityManagerNative * indirect content-provider access. */ private class Identity { - public int pid; - public int uid; + public final IBinder token; + public final int pid; + public final int uid; - Identity(int _pid, int _uid) { + Identity(IBinder _token, int _pid, int _uid) { + token = _token; pid = _pid; uid = _uid; } @@ -2275,15 +2277,19 @@ public final class ActivityManagerService extends ActivityManagerNative * process when the bindApplication() IPC is sent to the process. They're * lazily setup to make sure the services are running when they're asked for. */ - private HashMap<String, IBinder> getCommonServicesLocked() { + private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) { if (mAppBindArgs == null) { - mAppBindArgs = new HashMap<String, IBinder>(); + mAppBindArgs = new HashMap<>(); - // Setup the application init args - mAppBindArgs.put("package", ServiceManager.getService("package")); - mAppBindArgs.put("window", ServiceManager.getService("window")); - mAppBindArgs.put(Context.ALARM_SERVICE, - ServiceManager.getService(Context.ALARM_SERVICE)); + // Isolated processes won't get this optimization, so that we don't + // violate the rules about which services they have access to. + if (!isolated) { + // Setup the application init args + mAppBindArgs.put("package", ServiceManager.getService("package")); + mAppBindArgs.put("window", ServiceManager.getService("window")); + mAppBindArgs.put(Context.ALARM_SERVICE, + ServiceManager.getService(Context.ALARM_SERVICE)); + } } return mAppBindArgs; } @@ -5906,7 +5912,8 @@ public final class ActivityManagerService extends ActivityManagerNative profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, - new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), + new Configuration(mConfiguration), app.compat, + getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked()); updateLruProcessLocked(app, false, null); app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); @@ -6726,21 +6733,9 @@ public final class ActivityManagerService extends ActivityManagerNative */ int checkComponentPermission(String permission, int pid, int uid, int owningUid, boolean exported) { - // We might be performing an operation on behalf of an indirect binder - // invocation, e.g. via {@link #openContentUri}. Check and adjust the - // client identity accordingly before proceeding. - Identity tlsIdentity = sCallerIdentity.get(); - if (tlsIdentity != null) { - Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" - + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); - uid = tlsIdentity.uid; - pid = tlsIdentity.pid; - } - if (pid == MY_PID) { return PackageManager.PERMISSION_GRANTED; } - return ActivityManager.checkComponentPermission(permission, uid, owningUid, exported); } @@ -6762,6 +6757,26 @@ public final class ActivityManagerService extends ActivityManagerNative return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); } + @Override + public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) { + if (permission == null) { + return PackageManager.PERMISSION_DENIED; + } + + // We might be performing an operation on behalf of an indirect binder + // invocation, e.g. via {@link #openContentUri}. Check and adjust the + // client identity accordingly before proceeding. + Identity tlsIdentity = sCallerIdentity.get(); + if (tlsIdentity != null && tlsIdentity.token == callerToken) { + Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" + + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); + uid = tlsIdentity.uid; + pid = tlsIdentity.pid; + } + + return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); + } + /** * Binder IPC calls go through the public entry point. * This can be called with or without the global lock held. @@ -6967,13 +6982,13 @@ public final class ActivityManagerService extends ActivityManagerNative */ @Override public int checkUriPermission(Uri uri, int pid, int uid, - final int modeFlags, int userId) { + final int modeFlags, int userId, IBinder callerToken) { enforceNotIsolatedCaller("checkUriPermission"); // Another redirected-binder-call permissions check as in - // {@link checkComponentPermission}. + // {@link checkPermissionWithToken}. Identity tlsIdentity = sCallerIdentity.get(); - if (tlsIdentity != null) { + if (tlsIdentity != null && tlsIdentity.token == callerToken) { uid = tlsIdentity.uid; pid = tlsIdentity.pid; } @@ -9880,10 +9895,11 @@ public final class ActivityManagerService extends ActivityManagerNative // we do the check against the caller's permissions even though it looks // to the content provider like the Activity Manager itself is making // the request. + Binder token = new Binder(); sCallerIdentity.set(new Identity( - Binder.getCallingPid(), Binder.getCallingUid())); + token, Binder.getCallingPid(), Binder.getCallingUid())); try { - pfd = cph.provider.openFile(null, uri, "r", null); + pfd = cph.provider.openFile(null, uri, "r", null, token); } catch (FileNotFoundException e) { // do nothing; pfd will be returned null } finally { diff --git a/test-runner/src/android/test/mock/MockContentProvider.java b/test-runner/src/android/test/mock/MockContentProvider.java index 28d52b0..5ef71df 100644 --- a/test-runner/src/android/test/mock/MockContentProvider.java +++ b/test-runner/src/android/test/mock/MockContentProvider.java @@ -91,8 +91,8 @@ public class MockContentProvider extends ContentProvider { @Override public ParcelFileDescriptor openFile( - String callingPackage, Uri url, String mode, ICancellationSignal signal) - throws RemoteException, FileNotFoundException { + String callingPackage, Uri url, String mode, ICancellationSignal signal, + IBinder callerToken) throws RemoteException, FileNotFoundException { return MockContentProvider.this.openFile(url, mode); } diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java index 46c81b6..3378872 100644 --- a/test-runner/src/android/test/mock/MockContext.java +++ b/test-runner/src/android/test/mock/MockContext.java @@ -37,6 +37,7 @@ import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.os.IBinder; import android.os.Looper; import android.os.UserHandle; import android.view.DisplayAdjustments; @@ -483,6 +484,12 @@ public class MockContext extends Context { throw new UnsupportedOperationException(); } + /** @hide */ + @Override + public int checkPermission(String permission, int pid, int uid, IBinder callerToken) { + return checkPermission(permission, pid, uid); + } + @Override public int checkCallingPermission(String permission) { throw new UnsupportedOperationException(); @@ -524,6 +531,12 @@ public class MockContext extends Context { throw new UnsupportedOperationException(); } + /** @hide */ + @Override + public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) { + return checkUriPermission(uri, pid, uid, modeFlags); + } + @Override public int checkCallingUriPermission(Uri uri, int modeFlags) { throw new UnsupportedOperationException(); diff --git a/test-runner/src/android/test/mock/MockIContentProvider.java b/test-runner/src/android/test/mock/MockIContentProvider.java index c0dc7c3..ee8c376 100644 --- a/test-runner/src/android/test/mock/MockIContentProvider.java +++ b/test-runner/src/android/test/mock/MockIContentProvider.java @@ -62,7 +62,8 @@ public class MockIContentProvider implements IContentProvider { } public ParcelFileDescriptor openFile( - String callingPackage, Uri url, String mode, ICancellationSignal signal) { + String callingPackage, Uri url, String mode, ICancellationSignal signal, + IBinder callerToken) { throw new UnsupportedOperationException("unimplemented mock method"); } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java index 89288bf..e4cbb2f 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContentProvider.java @@ -90,7 +90,7 @@ public final class BridgeContentProvider implements IContentProvider { @Override public ParcelFileDescriptor openFile( - String callingPackage, Uri arg0, String arg1, ICancellationSignal signal) + String callingPackage, Uri arg0, String arg1, ICancellationSignal signal, IBinder token) throws RemoteException, FileNotFoundException { // TODO Auto-generated method stub return null; diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index aeb70e9..2c3736f 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -16,6 +16,7 @@ package com.android.layoutlib.bridge.android; +import android.os.IBinder; import com.android.annotations.Nullable; import com.android.ide.common.rendering.api.ILayoutPullParser; import com.android.ide.common.rendering.api.IProjectCallback; @@ -938,12 +939,24 @@ public final class BridgeContext extends Context { } @Override + public int checkPermission(String arg0, int arg1, int arg2, IBinder arg3) { + // pass + return 0; + } + + @Override public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) { // pass return 0; } @Override + public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3, IBinder arg4) { + // pass + return 0; + } + + @Override public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3, int arg4, int arg5) { // pass |