am d9968438: Merge "Fix issue with call backs from media process." into lmp-mr1-dev

* commit 'd9968438bcf439e7a8c6058a95b85286a632dc1c':
  Fix issue with call backs from media process.
This commit is contained in:
Dianne Hackborn
2014-11-20 18:33:34 +00:00
committed by Android Git Automerger
17 changed files with 221 additions and 81 deletions

View File

@ -501,7 +501,7 @@ public class Content {
@Override @Override
public void onExecute(IContentProvider provider) throws Exception { 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); copy(new FileInputStream(fd.getFileDescriptor()), System.out);
} }

View File

@ -1186,6 +1186,18 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true; 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: { case CHECK_URI_PERMISSION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor); data.enforceInterface(IActivityManager.descriptor);
Uri uri = Uri.CREATOR.createFromParcel(data); Uri uri = Uri.CREATOR.createFromParcel(data);
@ -1193,7 +1205,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
int uid = data.readInt(); int uid = data.readInt();
int mode = data.readInt(); int mode = data.readInt();
int userId = 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.writeNoException();
reply.writeInt(res); reply.writeInt(res);
return true; return true;
@ -3851,6 +3864,22 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle(); reply.recycle();
return res; 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, public boolean clearApplicationUserData(final String packageName,
final IPackageDataObserver observer, final int userId) throws RemoteException { final IPackageDataObserver observer, final int userId) throws RemoteException {
Parcel data = Parcel.obtain(); Parcel data = Parcel.obtain();
@ -3866,8 +3895,8 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle(); reply.recycle();
return res; return res;
} }
public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId) public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId,
throws RemoteException { IBinder callerToken) throws RemoteException {
Parcel data = Parcel.obtain(); Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain(); Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor); data.writeInterfaceToken(IActivityManager.descriptor);
@ -3876,6 +3905,7 @@ class ActivityManagerProxy implements IActivityManager
data.writeInt(uid); data.writeInt(uid);
data.writeInt(mode); data.writeInt(mode);
data.writeInt(userId); data.writeInt(userId);
data.writeStrongBinder(callerToken);
mRemote.transact(CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0); mRemote.transact(CHECK_URI_PERMISSION_TRANSACTION, data, reply, 0);
reply.readException(); reply.readException();
int res = reply.readInt(); int res = reply.readInt();

View File

@ -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 @Override
public int checkCallingPermission(String permission) { public int checkCallingPermission(String permission) {
if (permission == null) { if (permission == null) {
@ -1951,7 +1966,19 @@ class ContextImpl extends Context {
try { try {
return ActivityManagerNative.getDefault().checkUriPermission( return ActivityManagerNative.getDefault().checkUriPermission(
ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags, 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) { } catch (RemoteException e) {
return PackageManager.PERMISSION_DENIED; return PackageManager.PERMISSION_DENIED;
} }

View File

@ -219,9 +219,11 @@ public interface IActivityManager extends IInterface {
public int checkPermission(String permission, int pid, int uid) public int checkPermission(String permission, int pid, int uid)
throws RemoteException; throws RemoteException;
public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken)
public int checkUriPermission(Uri uri, int pid, int uid, int mode, int userId)
throws RemoteException; 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, public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
int mode, int userId) throws RemoteException; int mode, int userId) throws RemoteException;
public void revokeUriPermission(IApplicationThread caller, Uri uri, int mode, int userId) 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 GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239; int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240; int START_IN_PLACE_ANIMATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+240;
int CHECK_PERMISSION_WITH_TOKEN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+241;
} }

View File

@ -31,6 +31,7 @@ import android.os.AsyncTask;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.CancellationSignal; import android.os.CancellationSignal;
import android.os.IBinder;
import android.os.ICancellationSignal; import android.os.ICancellationSignal;
import android.os.OperationCanceledException; import android.os.OperationCanceledException;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
@ -201,7 +202,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
ICancellationSignal cancellationSignal) { ICancellationSignal cancellationSignal) {
validateIncomingUri(uri); validateIncomingUri(uri);
uri = getUriWithoutUserId(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, return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
CancellationSignal.fromTransport(cancellationSignal)); CancellationSignal.fromTransport(cancellationSignal));
} }
@ -227,7 +228,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
validateIncomingUri(uri); validateIncomingUri(uri);
int userId = getUserIdFromUri(uri); int userId = getUserIdFromUri(uri);
uri = getUriWithoutUserId(uri); uri = getUriWithoutUserId(uri);
if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
return rejectInsert(uri, initialValues); return rejectInsert(uri, initialValues);
} }
final String original = setCallingPackage(callingPkg); final String original = setCallingPackage(callingPkg);
@ -242,7 +243,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) { public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) {
validateIncomingUri(uri); validateIncomingUri(uri);
uri = getUriWithoutUserId(uri); uri = getUriWithoutUserId(uri);
if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
return 0; return 0;
} }
final String original = setCallingPackage(callingPkg); final String original = setCallingPackage(callingPkg);
@ -270,13 +271,13 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
operations.set(i, operation); operations.set(i, operation);
} }
if (operation.isReadOperation()) { if (operation.isReadOperation()) {
if (enforceReadPermission(callingPkg, uri) if (enforceReadPermission(callingPkg, uri, null)
!= AppOpsManager.MODE_ALLOWED) { != AppOpsManager.MODE_ALLOWED) {
throw new OperationApplicationException("App op not allowed", 0); throw new OperationApplicationException("App op not allowed", 0);
} }
} }
if (operation.isWriteOperation()) { if (operation.isWriteOperation()) {
if (enforceWritePermission(callingPkg, uri) if (enforceWritePermission(callingPkg, uri, null)
!= AppOpsManager.MODE_ALLOWED) { != AppOpsManager.MODE_ALLOWED) {
throw new OperationApplicationException("App op not allowed", 0); 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) { public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) {
validateIncomingUri(uri); validateIncomingUri(uri);
uri = getUriWithoutUserId(uri); uri = getUriWithoutUserId(uri);
if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
return 0; return 0;
} }
final String original = setCallingPackage(callingPkg); final String original = setCallingPackage(callingPkg);
@ -317,7 +318,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
String[] selectionArgs) { String[] selectionArgs) {
validateIncomingUri(uri); validateIncomingUri(uri);
uri = getUriWithoutUserId(uri); uri = getUriWithoutUserId(uri);
if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
return 0; return 0;
} }
final String original = setCallingPackage(callingPkg); final String original = setCallingPackage(callingPkg);
@ -330,11 +331,11 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
@Override @Override
public ParcelFileDescriptor openFile( public ParcelFileDescriptor openFile(
String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal) String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal,
throws FileNotFoundException { IBinder callerToken) throws FileNotFoundException {
validateIncomingUri(uri); validateIncomingUri(uri);
uri = getUriWithoutUserId(uri); uri = getUriWithoutUserId(uri);
enforceFilePermission(callingPkg, uri, mode); enforceFilePermission(callingPkg, uri, mode, callerToken);
final String original = setCallingPackage(callingPkg); final String original = setCallingPackage(callingPkg);
try { try {
return ContentProvider.this.openFile( return ContentProvider.this.openFile(
@ -350,7 +351,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
throws FileNotFoundException { throws FileNotFoundException {
validateIncomingUri(uri); validateIncomingUri(uri);
uri = getUriWithoutUserId(uri); uri = getUriWithoutUserId(uri);
enforceFilePermission(callingPkg, uri, mode); enforceFilePermission(callingPkg, uri, mode, null);
final String original = setCallingPackage(callingPkg); final String original = setCallingPackage(callingPkg);
try { try {
return ContentProvider.this.openAssetFile( return ContentProvider.this.openAssetFile(
@ -382,7 +383,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException { Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
validateIncomingUri(uri); validateIncomingUri(uri);
uri = getUriWithoutUserId(uri); uri = getUriWithoutUserId(uri);
enforceFilePermission(callingPkg, uri, "r"); enforceFilePermission(callingPkg, uri, "r", null);
final String original = setCallingPackage(callingPkg); final String original = setCallingPackage(callingPkg);
try { try {
return ContentProvider.this.openTypedAssetFile( return ContentProvider.this.openTypedAssetFile(
@ -402,7 +403,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
validateIncomingUri(uri); validateIncomingUri(uri);
int userId = getUserIdFromUri(uri); int userId = getUserIdFromUri(uri);
uri = getUriWithoutUserId(uri); uri = getUriWithoutUserId(uri);
if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
return null; return null;
} }
final String original = setCallingPackage(callingPkg); final String original = setCallingPackage(callingPkg);
@ -418,7 +419,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
validateIncomingUri(uri); validateIncomingUri(uri);
int userId = getUserIdFromUri(uri); int userId = getUserIdFromUri(uri);
uri = getUriWithoutUserId(uri); uri = getUriWithoutUserId(uri);
if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) {
return null; return null;
} }
final String original = setCallingPackage(callingPkg); final String original = setCallingPackage(callingPkg);
@ -429,29 +430,33 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
} }
} }
private void enforceFilePermission(String callingPkg, Uri uri, String mode) private void enforceFilePermission(String callingPkg, Uri uri, String mode,
throws FileNotFoundException, SecurityException { IBinder callerToken) throws FileNotFoundException, SecurityException {
if (mode != null && mode.indexOf('w') != -1) { 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"); throw new FileNotFoundException("App op not allowed");
} }
} else { } else {
if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) { if (enforceReadPermission(callingPkg, uri, callerToken)
!= AppOpsManager.MODE_ALLOWED) {
throw new FileNotFoundException("App op not allowed"); throw new FileNotFoundException("App op not allowed");
} }
} }
} }
private int enforceReadPermission(String callingPkg, Uri uri) throws SecurityException { private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken)
enforceReadPermissionInner(uri); throws SecurityException {
enforceReadPermissionInner(uri, callerToken);
if (mReadOp != AppOpsManager.OP_NONE) { if (mReadOp != AppOpsManager.OP_NONE) {
return mAppOpsManager.noteOp(mReadOp, Binder.getCallingUid(), callingPkg); return mAppOpsManager.noteOp(mReadOp, Binder.getCallingUid(), callingPkg);
} }
return AppOpsManager.MODE_ALLOWED; return AppOpsManager.MODE_ALLOWED;
} }
private int enforceWritePermission(String callingPkg, Uri uri) throws SecurityException { private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken)
enforceWritePermissionInner(uri); throws SecurityException {
enforceWritePermissionInner(uri, callerToken);
if (mWriteOp != AppOpsManager.OP_NONE) { if (mWriteOp != AppOpsManager.OP_NONE) {
return mAppOpsManager.noteOp(mWriteOp, Binder.getCallingUid(), callingPkg); return mAppOpsManager.noteOp(mWriteOp, Binder.getCallingUid(), callingPkg);
} }
@ -467,7 +472,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
} }
/** {@hide} */ /** {@hide} */
protected void enforceReadPermissionInner(Uri uri) throws SecurityException { protected void enforceReadPermissionInner(Uri uri, IBinder callerToken)
throws SecurityException {
final Context context = getContext(); final Context context = getContext();
final int pid = Binder.getCallingPid(); final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid();
@ -480,7 +486,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
if (mExported && checkUser(pid, uid, context)) { if (mExported && checkUser(pid, uid, context)) {
final String componentPerm = getReadPermission(); final String componentPerm = getReadPermission();
if (componentPerm != null) { if (componentPerm != null) {
if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) { if (context.checkPermission(componentPerm, pid, uid, callerToken)
== PERMISSION_GRANTED) {
return; return;
} else { } else {
missingPerm = componentPerm; missingPerm = componentPerm;
@ -497,7 +504,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
for (PathPermission pp : pps) { for (PathPermission pp : pps) {
final String pathPerm = pp.getReadPermission(); final String pathPerm = pp.getReadPermission();
if (pathPerm != null && pp.match(path)) { if (pathPerm != null && pp.match(path)) {
if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) { if (context.checkPermission(pathPerm, pid, uid, callerToken)
== PERMISSION_GRANTED) {
return; return;
} else { } else {
// any denied <path-permission> means we lose // any denied <path-permission> means we lose
@ -518,8 +526,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
final int callingUserId = UserHandle.getUserId(uid); final int callingUserId = UserHandle.getUserId(uid);
final Uri userUri = (mSingleUser && !UserHandle.isSameUser(mMyUid, uid)) final Uri userUri = (mSingleUser && !UserHandle.isSameUser(mMyUid, uid))
? maybeAddUserId(uri, callingUserId) : uri; ? maybeAddUserId(uri, callingUserId) : uri;
if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION) if (context.checkUriPermission(userUri, pid, uid, Intent.FLAG_GRANT_READ_URI_PERMISSION,
== PERMISSION_GRANTED) { callerToken) == PERMISSION_GRANTED) {
return; return;
} }
@ -532,7 +540,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
} }
/** {@hide} */ /** {@hide} */
protected void enforceWritePermissionInner(Uri uri) throws SecurityException { protected void enforceWritePermissionInner(Uri uri, IBinder callerToken)
throws SecurityException {
final Context context = getContext(); final Context context = getContext();
final int pid = Binder.getCallingPid(); final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid();
@ -545,7 +554,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
if (mExported && checkUser(pid, uid, context)) { if (mExported && checkUser(pid, uid, context)) {
final String componentPerm = getWritePermission(); final String componentPerm = getWritePermission();
if (componentPerm != null) { if (componentPerm != null) {
if (context.checkPermission(componentPerm, pid, uid) == PERMISSION_GRANTED) { if (context.checkPermission(componentPerm, pid, uid, callerToken)
== PERMISSION_GRANTED) {
return; return;
} else { } else {
missingPerm = componentPerm; missingPerm = componentPerm;
@ -562,7 +572,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
for (PathPermission pp : pps) { for (PathPermission pp : pps) {
final String pathPerm = pp.getWritePermission(); final String pathPerm = pp.getWritePermission();
if (pathPerm != null && pp.match(path)) { if (pathPerm != null && pp.match(path)) {
if (context.checkPermission(pathPerm, pid, uid) == PERMISSION_GRANTED) { if (context.checkPermission(pathPerm, pid, uid, callerToken)
== PERMISSION_GRANTED) {
return; return;
} else { } else {
// any denied <path-permission> means we lose // any denied <path-permission> means we lose
@ -580,8 +591,8 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
} }
// last chance, check against any uri grants // last chance, check against any uri grants
if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION) if (context.checkUriPermission(uri, pid, uid, Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
== PERMISSION_GRANTED) { callerToken) == PERMISSION_GRANTED) {
return; return;
} }

View File

@ -288,7 +288,7 @@ public class ContentProviderClient {
remoteSignal = mContentProvider.createCancellationSignal(); remoteSignal = mContentProvider.createCancellationSignal();
signal.setRemote(remoteSignal); signal.setRemote(remoteSignal);
} }
return mContentProvider.openFile(mPackageName, url, mode, remoteSignal); return mContentProvider.openFile(mPackageName, url, mode, remoteSignal, null);
} catch (DeadObjectException e) { } catch (DeadObjectException e) {
if (!mStable) { if (!mStable) {
mContentResolver.unstableProviderDied(mContentProvider); mContentResolver.unstableProviderDied(mContentProvider);

View File

@ -234,9 +234,10 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
String mode = data.readString(); String mode = data.readString();
ICancellationSignal signal = ICancellationSignal.Stub.asInterface( ICancellationSignal signal = ICancellationSignal.Stub.asInterface(
data.readStrongBinder()); data.readStrongBinder());
IBinder callerToken = data.readStrongBinder();
ParcelFileDescriptor fd; ParcelFileDescriptor fd;
fd = openFile(callingPkg, url, mode, signal); fd = openFile(callingPkg, url, mode, signal, callerToken);
reply.writeNoException(); reply.writeNoException();
if (fd != null) { if (fd != null) {
reply.writeInt(1); reply.writeInt(1);
@ -575,7 +576,7 @@ final class ContentProviderProxy implements IContentProvider
@Override @Override
public ParcelFileDescriptor openFile( public ParcelFileDescriptor openFile(
String callingPkg, Uri url, String mode, ICancellationSignal signal) String callingPkg, Uri url, String mode, ICancellationSignal signal, IBinder token)
throws RemoteException, FileNotFoundException { throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain(); Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain(); Parcel reply = Parcel.obtain();
@ -586,6 +587,7 @@ final class ContentProviderProxy implements IContentProvider
url.writeToParcel(data, 0); url.writeToParcel(data, 0);
data.writeString(mode); data.writeString(mode);
data.writeStrongBinder(signal != null ? signal.asBinder() : null); data.writeStrongBinder(signal != null ? signal.asBinder() : null);
data.writeStrongBinder(token);
mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0); mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);

View File

@ -37,6 +37,7 @@ import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.StatFs; import android.os.StatFs;
import android.os.UserHandle; import android.os.UserHandle;
@ -2864,10 +2865,10 @@ public abstract class Context {
/** /**
* Use with {@link #getSystemService} to retrieve a {@link * 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 #getSystemService
* @see android.app.UsageStatsManager * @see android.app.usage.UsageStatsManager
* @hide * @hide
*/ */
public static final String USAGE_STATS_SERVICE = "usagestats"; public static final String USAGE_STATS_SERVICE = "usagestats";
@ -2921,6 +2922,11 @@ public abstract class Context {
@PackageManager.PermissionResult @PackageManager.PermissionResult
public abstract int checkPermission(@NonNull String permission, int pid, int uid); 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 * Determine whether the calling process of an IPC you are handling has been
* granted a particular permission. This is basically the same as calling * 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, public abstract int checkUriPermission(Uri uri, int pid, int uid,
@Intent.AccessUriMode int modeFlags); @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 * Determine whether the calling process and user ID has been
* granted permission to access a specific URI. This is basically * granted permission to access a specific URI. This is basically

View File

@ -29,6 +29,7 @@ import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.UserHandle; import android.os.UserHandle;
import android.view.DisplayAdjustments; import android.view.DisplayAdjustments;
@ -566,6 +567,12 @@ public class ContextWrapper extends Context {
return mBase.checkPermission(permission, pid, uid); 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 @Override
public int checkCallingPermission(String permission) { public int checkCallingPermission(String permission) {
return mBase.checkCallingPermission(permission); return mBase.checkCallingPermission(permission);
@ -608,6 +615,12 @@ public class ContextWrapper extends Context {
return mBase.checkUriPermission(uri, pid, uid, modeFlags); 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 @Override
public int checkCallingUriPermission(Uri uri, int modeFlags) { public int checkCallingUriPermission(Uri uri, int modeFlags) {
return mBase.checkCallingUriPermission(uri, modeFlags); return mBase.checkCallingUriPermission(uri, modeFlags);

View File

@ -47,7 +47,8 @@ public interface IContentProvider extends IInterface {
public int update(String callingPkg, Uri url, ContentValues values, String selection, public int update(String callingPkg, Uri url, ContentValues values, String selection,
String[] selectionArgs) throws RemoteException; String[] selectionArgs) throws RemoteException;
public ParcelFileDescriptor openFile( public ParcelFileDescriptor openFile(
String callingPkg, Uri url, String mode, ICancellationSignal signal) String callingPkg, Uri url, String mode, ICancellationSignal signal,
IBinder callerToken)
throws RemoteException, FileNotFoundException; throws RemoteException, FileNotFoundException;
public AssetFileDescriptor openAssetFile( public AssetFileDescriptor openAssetFile(
String callingPkg, Uri url, String mode, ICancellationSignal signal) String callingPkg, Uri url, String mode, ICancellationSignal signal)

View File

@ -637,7 +637,7 @@ public abstract class DocumentsProvider extends ContentProvider {
final Bundle out = new Bundle(); final Bundle out = new Bundle();
try { try {
if (METHOD_CREATE_DOCUMENT.equals(method)) { if (METHOD_CREATE_DOCUMENT.equals(method)) {
enforceWritePermissionInner(documentUri); enforceWritePermissionInner(documentUri, null);
final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE); final String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME); 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); out.putParcelable(DocumentsContract.EXTRA_URI, newDocumentUri);
} else if (METHOD_RENAME_DOCUMENT.equals(method)) { } else if (METHOD_RENAME_DOCUMENT.equals(method)) {
enforceWritePermissionInner(documentUri); enforceWritePermissionInner(documentUri, null);
final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME); final String displayName = extras.getString(Document.COLUMN_DISPLAY_NAME);
final String newDocumentId = renameDocument(documentId, displayName); final String newDocumentId = renameDocument(documentId, displayName);
@ -675,7 +675,7 @@ public abstract class DocumentsProvider extends ContentProvider {
} }
} else if (METHOD_DELETE_DOCUMENT.equals(method)) { } else if (METHOD_DELETE_DOCUMENT.equals(method)) {
enforceWritePermissionInner(documentUri); enforceWritePermissionInner(documentUri, null);
deleteDocument(documentId); deleteDocument(documentId);
// Document no longer exists, clean up any grants // Document no longer exists, clean up any grants

View File

@ -838,10 +838,12 @@ public final class ActivityManagerService extends ActivityManagerNative
* indirect content-provider access. * indirect content-provider access.
*/ */
private class Identity { private class Identity {
public int pid; public final IBinder token;
public int uid; public final int pid;
public final int uid;
Identity(int _pid, int _uid) { Identity(IBinder _token, int _pid, int _uid) {
token = _token;
pid = _pid; pid = _pid;
uid = _uid; uid = _uid;
} }
@ -2275,16 +2277,20 @@ public final class ActivityManagerService extends ActivityManagerNative
* process when the bindApplication() IPC is sent to the process. They're * 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. * 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) { if (mAppBindArgs == null) {
mAppBindArgs = new HashMap<String, IBinder>(); mAppBindArgs = new HashMap<>();
// 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 // Setup the application init args
mAppBindArgs.put("package", ServiceManager.getService("package")); mAppBindArgs.put("package", ServiceManager.getService("package"));
mAppBindArgs.put("window", ServiceManager.getService("window")); mAppBindArgs.put("window", ServiceManager.getService("window"));
mAppBindArgs.put(Context.ALARM_SERVICE, mAppBindArgs.put(Context.ALARM_SERVICE,
ServiceManager.getService(Context.ALARM_SERVICE)); ServiceManager.getService(Context.ALARM_SERVICE));
} }
}
return mAppBindArgs; return mAppBindArgs;
} }
@ -5906,7 +5912,8 @@ public final class ActivityManagerService extends ActivityManagerNative
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
isRestrictedBackupMode || !normalMode, app.persistent, isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked()); mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false, null); updateLruProcessLocked(app, false, null);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 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 checkComponentPermission(String permission, int pid, int uid,
int owningUid, boolean exported) { 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) { if (pid == MY_PID) {
return PackageManager.PERMISSION_GRANTED; return PackageManager.PERMISSION_GRANTED;
} }
return ActivityManager.checkComponentPermission(permission, uid, return ActivityManager.checkComponentPermission(permission, uid,
owningUid, exported); owningUid, exported);
} }
@ -6762,6 +6757,26 @@ public final class ActivityManagerService extends ActivityManagerNative
return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 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. * Binder IPC calls go through the public entry point.
* This can be called with or without the global lock held. * This can be called with or without the global lock held.
@ -6967,13 +6982,13 @@ public final class ActivityManagerService extends ActivityManagerNative
*/ */
@Override @Override
public int checkUriPermission(Uri uri, int pid, int uid, public int checkUriPermission(Uri uri, int pid, int uid,
final int modeFlags, int userId) { final int modeFlags, int userId, IBinder callerToken) {
enforceNotIsolatedCaller("checkUriPermission"); enforceNotIsolatedCaller("checkUriPermission");
// Another redirected-binder-call permissions check as in // Another redirected-binder-call permissions check as in
// {@link checkComponentPermission}. // {@link checkPermissionWithToken}.
Identity tlsIdentity = sCallerIdentity.get(); Identity tlsIdentity = sCallerIdentity.get();
if (tlsIdentity != null) { if (tlsIdentity != null && tlsIdentity.token == callerToken) {
uid = tlsIdentity.uid; uid = tlsIdentity.uid;
pid = tlsIdentity.pid; 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 // we do the check against the caller's permissions even though it looks
// to the content provider like the Activity Manager itself is making // to the content provider like the Activity Manager itself is making
// the request. // the request.
Binder token = new Binder();
sCallerIdentity.set(new Identity( sCallerIdentity.set(new Identity(
Binder.getCallingPid(), Binder.getCallingUid())); token, Binder.getCallingPid(), Binder.getCallingUid()));
try { try {
pfd = cph.provider.openFile(null, uri, "r", null); pfd = cph.provider.openFile(null, uri, "r", null, token);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
// do nothing; pfd will be returned null // do nothing; pfd will be returned null
} finally { } finally {

View File

@ -91,8 +91,8 @@ public class MockContentProvider extends ContentProvider {
@Override @Override
public ParcelFileDescriptor openFile( public ParcelFileDescriptor openFile(
String callingPackage, Uri url, String mode, ICancellationSignal signal) String callingPackage, Uri url, String mode, ICancellationSignal signal,
throws RemoteException, FileNotFoundException { IBinder callerToken) throws RemoteException, FileNotFoundException {
return MockContentProvider.this.openFile(url, mode); return MockContentProvider.this.openFile(url, mode);
} }

View File

@ -37,6 +37,7 @@ import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder;
import android.os.Looper; import android.os.Looper;
import android.os.UserHandle; import android.os.UserHandle;
import android.view.DisplayAdjustments; import android.view.DisplayAdjustments;
@ -483,6 +484,12 @@ public class MockContext extends Context {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/** @hide */
@Override
public int checkPermission(String permission, int pid, int uid, IBinder callerToken) {
return checkPermission(permission, pid, uid);
}
@Override @Override
public int checkCallingPermission(String permission) { public int checkCallingPermission(String permission) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@ -524,6 +531,12 @@ public class MockContext extends Context {
throw new UnsupportedOperationException(); 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 @Override
public int checkCallingUriPermission(Uri uri, int modeFlags) { public int checkCallingUriPermission(Uri uri, int modeFlags) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();

View File

@ -62,7 +62,8 @@ public class MockIContentProvider implements IContentProvider {
} }
public ParcelFileDescriptor openFile( 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"); throw new UnsupportedOperationException("unimplemented mock method");
} }

View File

@ -90,7 +90,7 @@ public final class BridgeContentProvider implements IContentProvider {
@Override @Override
public ParcelFileDescriptor openFile( public ParcelFileDescriptor openFile(
String callingPackage, Uri arg0, String arg1, ICancellationSignal signal) String callingPackage, Uri arg0, String arg1, ICancellationSignal signal, IBinder token)
throws RemoteException, FileNotFoundException { throws RemoteException, FileNotFoundException {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return null; return null;

View File

@ -16,6 +16,7 @@
package com.android.layoutlib.bridge.android; package com.android.layoutlib.bridge.android;
import android.os.IBinder;
import com.android.annotations.Nullable; import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.ILayoutPullParser; import com.android.ide.common.rendering.api.ILayoutPullParser;
import com.android.ide.common.rendering.api.IProjectCallback; import com.android.ide.common.rendering.api.IProjectCallback;
@ -937,12 +938,24 @@ public final class BridgeContext extends Context {
return 0; return 0;
} }
@Override
public int checkPermission(String arg0, int arg1, int arg2, IBinder arg3) {
// pass
return 0;
}
@Override @Override
public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) { public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3) {
// pass // pass
return 0; return 0;
} }
@Override
public int checkUriPermission(Uri arg0, int arg1, int arg2, int arg3, IBinder arg4) {
// pass
return 0;
}
@Override @Override
public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3, public int checkUriPermission(Uri arg0, String arg1, String arg2, int arg3,
int arg4, int arg5) { int arg4, int arg5) {