summaryrefslogtreecommitdiffstats
path: root/core/java/android/app
diff options
context:
space:
mode:
authorSvet Ganov <svetoslavganov@google.com>2015-06-27 13:15:22 -0700
committerSvet Ganov <svetoslavganov@google.com>2015-07-01 16:20:00 -0700
commit99b6043dad9d215cf15810b885b6b8c215dd5b5a (patch)
treeab714f7926640fbe8dafa4668f251e33e5f915c4 /core/java/android/app
parent2438c9b2e7892a8515209cb1d440c3b5147165b2 (diff)
downloadframeworks_base-99b6043dad9d215cf15810b885b6b8c215dd5b5a.zip
frameworks_base-99b6043dad9d215cf15810b885b6b8c215dd5b5a.tar.gz
frameworks_base-99b6043dad9d215cf15810b885b6b8c215dd5b5a.tar.bz2
Teach receivers, activities, providers, and services app ops.
Perform app op check in addition to the permisison check for all four paltform components - activities, content providers, broadcast receivers, services - if they are guarded by a permssion that has an associated app op. This ensures that legacy apps will behave correctly if the permission of the caller has been revoked, i.e. the app op for that permission was disabled. bug:22199666 Change-Id: Ia22d1c38d58b3cd6aabdc655cb7c7bddd85da7a2
Diffstat (limited to 'core/java/android/app')
-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
4 files changed, 117 insertions, 21 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;