summaryrefslogtreecommitdiffstats
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ActivityManagerNative.java20
-rw-r--r--core/java/android/app/AppOpsManager.java97
-rw-r--r--core/java/android/app/ContextImpl.java10
-rw-r--r--core/java/android/app/IActivityManager.java11
-rw-r--r--core/java/android/content/BroadcastReceiver.java2
-rw-r--r--core/java/android/content/ContentProvider.java24
6 files changed, 140 insertions, 24 deletions
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 2bb4e76..cc93ac9 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -921,8 +921,9 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
IApplicationThread app = ApplicationThreadNative.asInterface(b);
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
+ String callingPackage = data.readString();
int userId = data.readInt();
- ComponentName cn = startService(app, service, resolvedType, userId);
+ ComponentName cn = startService(app, service, resolvedType, callingPackage, userId);
reply.writeNoException();
ComponentName.writeToParcel(cn, reply);
return true;
@@ -976,9 +977,11 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
String resolvedType = data.readString();
b = data.readStrongBinder();
int fl = data.readInt();
+ String callingPackage = data.readString();
int userId = data.readInt();
IServiceConnection conn = IServiceConnection.Stub.asInterface(b);
- int res = bindService(app, token, service, resolvedType, conn, fl, userId);
+ int res = bindService(app, token, service, resolvedType, conn, fl,
+ callingPackage, userId);
reply.writeNoException();
reply.writeInt(res);
return true;
@@ -1568,7 +1571,8 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
data.enforceInterface(IActivityManager.descriptor);
Intent service = Intent.CREATOR.createFromParcel(data);
String resolvedType = data.readString();
- IBinder binder = peekService(service, resolvedType);
+ String callingPackage = data.readString();
+ IBinder binder = peekService(service, resolvedType, callingPackage);
reply.writeNoException();
reply.writeStrongBinder(binder);
return true;
@@ -3638,7 +3642,7 @@ class ActivityManagerProxy implements IActivityManager
}
public ComponentName startService(IApplicationThread caller, Intent service,
- String resolvedType, int userId) throws RemoteException
+ String resolvedType, String callingPackage, int userId) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
@@ -3646,6 +3650,7 @@ class ActivityManagerProxy implements IActivityManager
data.writeStrongBinder(caller != null ? caller.asBinder() : null);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
+ data.writeString(callingPackage);
data.writeInt(userId);
mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
@@ -3708,7 +3713,7 @@ class ActivityManagerProxy implements IActivityManager
}
public int bindService(IApplicationThread caller, IBinder token,
Intent service, String resolvedType, IServiceConnection connection,
- int flags, int userId) throws RemoteException {
+ int flags, String callingPackage, int userId) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
@@ -3718,6 +3723,7 @@ class ActivityManagerProxy implements IActivityManager
data.writeString(resolvedType);
data.writeStrongBinder(connection.asBinder());
data.writeInt(flags);
+ data.writeString(callingPackage);
data.writeInt(userId);
mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
@@ -3783,12 +3789,14 @@ class ActivityManagerProxy implements IActivityManager
reply.recycle();
}
- public IBinder peekService(Intent service, String resolvedType) throws RemoteException {
+ public IBinder peekService(Intent service, String resolvedType, String callingPackage)
+ throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
service.writeToParcel(data, 0);
data.writeString(resolvedType);
+ data.writeString(callingPackage);
mRemote.transact(PEEK_SERVICE_TRANSACTION, data, reply, 0);
reply.readException();
IBinder binder = reply.readStrongBinder();
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 9faadd3..bf3bfae 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1082,13 +1082,18 @@ public class AppOpsManager {
private final long mTime;
private final long mRejectTime;
private final int mDuration;
+ private final int mProxyUid;
+ private final String mProxyPackageName;
- public OpEntry(int op, int mode, long time, long rejectTime, int duration) {
+ public OpEntry(int op, int mode, long time, long rejectTime, int duration,
+ int proxyUid, String proxyPackage) {
mOp = op;
mMode = mode;
mTime = time;
mRejectTime = rejectTime;
mDuration = duration;
+ mProxyUid = proxyUid;
+ mProxyPackageName = proxyPackage;
}
public int getOp() {
@@ -1115,6 +1120,14 @@ public class AppOpsManager {
return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
}
+ public int getProxyUid() {
+ return mProxyUid;
+ }
+
+ public String getProxyPackageName() {
+ return mProxyPackageName;
+ }
+
@Override
public int describeContents() {
return 0;
@@ -1127,6 +1140,8 @@ public class AppOpsManager {
dest.writeLong(mTime);
dest.writeLong(mRejectTime);
dest.writeInt(mDuration);
+ dest.writeInt(mProxyUid);
+ dest.writeString(mProxyPackageName);
}
OpEntry(Parcel source) {
@@ -1135,6 +1150,8 @@ public class AppOpsManager {
mTime = source.readLong();
mRejectTime = source.readLong();
mDuration = source.readInt();
+ mProxyUid = source.readInt();
+ mProxyPackageName = source.readString();
}
public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
@@ -1379,6 +1396,33 @@ public class AppOpsManager {
}
/**
+ * Make note of an application performing an operation on behalf of another
+ * application when handling an IPC. Note that you must pass the package name
+ * of the application that is being proxied while its UID will be inferred from
+ * the IPC state; this function will verify that the calling uid and proxied
+ * package name match, and if not, return {@link #MODE_IGNORED}. If this call
+ * succeeds, the last execution time of the operation for the proxied app and
+ * your app will be updated to the current time.
+ * @param op The operation to note. One of the OPSTR_* constants.
+ * @param proxiedPackageName The name of the application calling into the proxy application.
+ * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+ * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+ * causing the app to crash).
+ * @throws SecurityException If the app has been configured to crash on this op.
+ */
+ public int noteProxyOp(String op, String proxiedPackageName) {
+ return noteProxyOp(strOpToOp(op), proxiedPackageName);
+ }
+
+ /**
+ * Like {@link #noteProxyOp(String, String)} but instead
+ * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
+ */
+ public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
+ return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
+ }
+
+ /**
* Report that an application has started executing a long-running operation. Note that you
* must pass in both the uid and name of the application to be checked; this function will
* verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
@@ -1455,7 +1499,7 @@ public class AppOpsManager {
return mService.checkOperation(op, uid, packageName);
} catch (RemoteException e) {
}
- return MODE_IGNORED;
+ return MODE_ERRORED;
}
/**
@@ -1501,7 +1545,7 @@ public class AppOpsManager {
return mService.checkAudioOperation(op, stream, uid, packageName);
} catch (RemoteException e) {
}
- return MODE_IGNORED;
+ return MODE_ERRORED;
}
/**
@@ -1532,6 +1576,49 @@ public class AppOpsManager {
}
/**
+ * Make note of an application performing an operation on behalf of another
+ * application when handling an IPC. Note that you must pass the package name
+ * of the application that is being proxied while its UID will be inferred from
+ * the IPC state; this function will verify that the calling uid and proxied
+ * package name match, and if not, return {@link #MODE_IGNORED}. If this call
+ * succeeds, the last execution time of the operation for the proxied app and
+ * your app will be updated to the current time.
+ * @param op The operation to note. One of the OPSTR_* constants.
+ * @param proxiedPackageName The name of the application calling into the proxy application.
+ * @return Returns {@link #MODE_ALLOWED} if the operation is allowed, or
+ * {@link #MODE_IGNORED} if it is not allowed and should be silently ignored (without
+ * causing the app to crash).
+ * @throws SecurityException If the proxy or proxied app has been configured to
+ * crash on this op.
+ *
+ * @hide
+ */
+ public int noteProxyOp(int op, String proxiedPackageName) {
+ int mode = noteProxyOpNoThrow(op, proxiedPackageName);
+ if (mode == MODE_ERRORED) {
+ throw new SecurityException("Proxy package " + mContext.getOpPackageName()
+ + " from uid " + Process.myUid() + " or calling package "
+ + proxiedPackageName + " from uid " + Binder.getCallingUid()
+ + " not allowed to perform " + sOpNames[op]);
+ }
+ return mode;
+ }
+
+ /**
+ * Like {@link #noteProxyOp(int, String)} but instead
+ * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
+ * @hide
+ */
+ public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
+ try {
+ return mService.noteProxyOperation(op, mContext.getOpPackageName(),
+ Binder.getCallingUid(), proxiedPackageName);
+ } catch (RemoteException e) {
+ }
+ return MODE_ERRORED;
+ }
+
+ /**
* Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
* returns {@link #MODE_ERRORED}.
* @hide
@@ -1541,7 +1628,7 @@ public class AppOpsManager {
return mService.noteOperation(op, uid, packageName);
} catch (RemoteException e) {
}
- return MODE_IGNORED;
+ return MODE_ERRORED;
}
/** @hide */
@@ -1603,7 +1690,7 @@ public class AppOpsManager {
return mService.startOperation(getToken(mService), op, uid, packageName);
} catch (RemoteException e) {
}
- return MODE_IGNORED;
+ return MODE_ERRORED;
}
/** @hide */
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 0420fb6..6639486 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1202,8 +1202,8 @@ class ContextImpl extends Context {
validateServiceIntent(service);
service.prepareToLeaveProcess();
ComponentName cn = ActivityManagerNative.getDefault().startService(
- mMainThread.getApplicationThread(), service,
- service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
+ mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
+ getContentResolver()), getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
@@ -1279,9 +1279,9 @@ class ContextImpl extends Context {
}
service.prepareToLeaveProcess();
int res = ActivityManagerNative.getDefault().bindService(
- mMainThread.getApplicationThread(), getActivityToken(),
- service, service.resolveTypeIfNeeded(getContentResolver()),
- sd, flags, user.getIdentifier());
+ mMainThread.getApplicationThread(), getActivityToken(), service,
+ service.resolveTypeIfNeeded(getContentResolver()),
+ sd, flags, getOpPackageName(), user.getIdentifier());
if (res < 0) {
throw new SecurityException(
"Not allowed to bind to service " + service);
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 1423e4b..acce81c 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -160,16 +160,16 @@ public interface IActivityManager extends IInterface {
public PendingIntent getRunningServiceControlPanel(ComponentName service)
throws RemoteException;
public ComponentName startService(IApplicationThread caller, Intent service,
- String resolvedType, int userId) throws RemoteException;
+ String resolvedType, String callingPackage, int userId) throws RemoteException;
public int stopService(IApplicationThread caller, Intent service,
String resolvedType, int userId) throws RemoteException;
public boolean stopServiceToken(ComponentName className, IBinder token,
int startId) throws RemoteException;
public void setServiceForeground(ComponentName className, IBinder token,
int id, Notification notification, boolean keepNotification) throws RemoteException;
- public int bindService(IApplicationThread caller, IBinder token,
- Intent service, String resolvedType,
- IServiceConnection connection, int flags, int userId) throws RemoteException;
+ public int bindService(IApplicationThread caller, IBinder token, Intent service,
+ String resolvedType, IServiceConnection connection, int flags,
+ String callingPackage, int userId) throws RemoteException;
public boolean unbindService(IServiceConnection connection) throws RemoteException;
public void publishService(IBinder token,
Intent intent, IBinder service) throws RemoteException;
@@ -178,7 +178,8 @@ public interface IActivityManager extends IInterface {
/* oneway */
public void serviceDoneExecuting(IBinder token, int type, int startId,
int res) throws RemoteException;
- public IBinder peekService(Intent service, String resolvedType) throws RemoteException;
+ public IBinder peekService(Intent service, String resolvedType, String callingPackage)
+ throws RemoteException;
public boolean bindBackupAgent(ApplicationInfo appInfo, int backupRestoreMode)
throws RemoteException;
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index af74e73..2260d7e 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -524,7 +524,7 @@ public abstract class BroadcastReceiver {
try {
service.prepareToLeaveProcess();
binder = am.peekService(service, service.resolveTypeIfNeeded(
- myContext.getContentResolver()));
+ myContext.getContentResolver()), myContext.getOpPackageName());
} catch (RemoteException e) {
}
return binder;
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index d4c4437..3cc7684 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -475,18 +475,38 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
private int enforceReadPermission(String callingPkg, Uri uri, IBinder callerToken)
throws SecurityException {
enforceReadPermissionInner(uri, callerToken);
+
+ final int permOp = AppOpsManager.permissionToOpCode(mReadPermission);
+ if (permOp != AppOpsManager.OP_NONE) {
+ final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg);
+ if (mode != AppOpsManager.MODE_ALLOWED) {
+ return mode;
+ }
+ }
+
if (mReadOp != AppOpsManager.OP_NONE) {
- return mAppOpsManager.noteOp(mReadOp, Binder.getCallingUid(), callingPkg);
+ return mAppOpsManager.noteProxyOp(mReadOp, callingPkg);
}
+
return AppOpsManager.MODE_ALLOWED;
}
private int enforceWritePermission(String callingPkg, Uri uri, IBinder callerToken)
throws SecurityException {
enforceWritePermissionInner(uri, callerToken);
+
+ final int permOp = AppOpsManager.permissionToOpCode(mWritePermission);
+ if (permOp != AppOpsManager.OP_NONE) {
+ final int mode = mAppOpsManager.noteProxyOp(permOp, callingPkg);
+ if (mode != AppOpsManager.MODE_ALLOWED) {
+ return mode;
+ }
+ }
+
if (mWriteOp != AppOpsManager.OP_NONE) {
- return mAppOpsManager.noteOp(mWriteOp, Binder.getCallingUid(), callingPkg);
+ return mAppOpsManager.noteProxyOp(mWriteOp, callingPkg);
}
+
return AppOpsManager.MODE_ALLOWED;
}
}