summaryrefslogtreecommitdiffstats
path: root/services/core/java
diff options
context:
space:
mode:
authorFyodor Kupolov <fkupolov@google.com>2015-07-13 19:19:25 -0700
committerFyodor Kupolov <fkupolov@google.com>2015-07-14 12:50:22 -0700
commitb4e7283c9afd9fb15ebd63f6ce9b75c9c1af658b (patch)
tree16259cb24eda7170075fb4ff4d90d34c77c2463f /services/core/java
parent37511e35ae22ea88539f1137ea2f74c9cb17f60c (diff)
downloadframeworks_base-b4e7283c9afd9fb15ebd63f6ce9b75c9c1af658b.zip
frameworks_base-b4e7283c9afd9fb15ebd63f6ce9b75c9c1af658b.tar.gz
frameworks_base-b4e7283c9afd9fb15ebd63f6ce9b75c9c1af658b.tar.bz2
Allow array of required permissions in sendBroadcast
Added Context.sendBroadcast(Intent intent, String[] receiverPermissions) method, which allows an array of required permissions to be enforced. Bug: 21852542 Change-Id: I3b8ff258fa9f3249c344bb8093b820b24eef00c0
Diffstat (limited to 'services/core/java')
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java40
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java161
-rw-r--r--services/core/java/com/android/server/am/BroadcastRecord.java15
3 files changed, 121 insertions, 95 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6e94647..9651067 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -6348,7 +6348,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
},
0, null, null,
- android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
+ new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
AppOpsManager.OP_NONE, null, true, false,
MY_PID, Process.SYSTEM_UID, userId);
}
@@ -11766,7 +11766,7 @@ public final class ActivityManagerService extends ActivityManagerNative
throws RemoteException {
}
}, 0, null, null,
- INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
+ new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
} catch (Throwable t) {
Slog.wtf(TAG, "Failed sending first user broadcasts", t);
@@ -16320,7 +16320,7 @@ public final class ActivityManagerService extends ActivityManagerNative
private final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
- Bundle resultExtras, String requiredPermission, int appOp, Bundle options,
+ Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
intent = new Intent(intent);
@@ -16573,9 +16573,9 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
- if (requiredPermission != null) {
+ if (requiredPermissions != null && requiredPermissions.length > 0) {
Slog.w(TAG, "Can't broadcast sticky intent " + intent
- + " and enforce permission " + requiredPermission);
+ + " and enforce permissions " + Arrays.toString(requiredPermissions));
return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
}
if (intent.getComponent() != null) {
@@ -16683,7 +16683,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// components to be launched.
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
- callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
+ callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
resultExtras, ordered, sticky, false, userId);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
@@ -16773,7 +16773,7 @@ public final class ActivityManagerService extends ActivityManagerNative
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, resolvedType,
- requiredPermission, appOp, brOptions, receivers, resultTo, resultCode,
+ requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId);
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
@@ -16822,7 +16822,7 @@ public final class ActivityManagerService extends ActivityManagerNative
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
- String requiredPermission, int appOp, Bundle options,
+ String[] requiredPermissions, int appOp, Bundle options,
boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
@@ -16835,13 +16835,14 @@ public final class ActivityManagerService extends ActivityManagerNative
int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
- requiredPermission, appOp, null, serialized, sticky,
+ requiredPermissions, appOp, null, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
+
int broadcastIntentInPackage(String packageName, int uid,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
@@ -16851,9 +16852,12 @@ public final class ActivityManagerService extends ActivityManagerNative
intent = verifyBroadcastLocked(intent);
final long origId = Binder.clearCallingIdentity();
+ String[] requiredPermissions = requiredPermission == null ? null
+ : new String[] {requiredPermission};
int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
- resultTo, resultCode, resultData, resultExtras, requiredPermission,
- AppOpsManager.OP_NONE, options, serialized, sticky, -1, uid, userId);
+ resultTo, resultCode, resultData, resultExtras,
+ requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
+ sticky, -1, uid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
@@ -19788,7 +19792,7 @@ public final class ActivityManagerService extends ActivityManagerNative
int sendingUser) throws RemoteException {
}
}, 0, null, null,
- INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
+ new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
}
}
@@ -19850,8 +19854,9 @@ public final class ActivityManagerService extends ActivityManagerNative
intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null,
- android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
- null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
+ new String[] {android.Manifest.permission.MANAGE_USERS},
+ AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
+ UserHandle.USER_ALL);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -20034,8 +20039,9 @@ public final class ActivityManagerService extends ActivityManagerNative
intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
broadcastIntentLocked(null, null, intent,
null, null, 0, null, null,
- android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
- null, true, false, MY_PID, Process.SYSTEM_UID, userId);
+ new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
+ AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
+ userId);
}
}
}
@@ -20173,7 +20179,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// Kick things off.
broadcastIntentLocked(null, null, stoppingIntent,
null, stoppingReceiver, 0, null, null,
- INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
+ new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 30aa411..7766539 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -493,59 +493,74 @@ public final class BroadcastQueue {
}
}
}
- if (!skip) {
- int perm = mService.checkComponentPermission(r.requiredPermission,
- filter.receiverList.pid, filter.receiverList.uid, -1, true);
- if (perm != PackageManager.PERMISSION_GRANTED) {
- Slog.w(TAG, "Permission Denial: receiving "
- + r.intent.toString()
- + " to " + filter.receiverList.app
- + " (pid=" + filter.receiverList.pid
- + ", uid=" + filter.receiverList.uid + ")"
- + " requires " + r.requiredPermission
- + " due to sender " + r.callerPackage
- + " (uid " + r.callingUid + ")");
- skip = true;
- }
- int appOp = AppOpsManager.OP_NONE;
- if (r.requiredPermission != null) {
- appOp = AppOpsManager.permissionToOpCode(r.requiredPermission);
- if (appOp != AppOpsManager.OP_NONE
- && mService.mAppOpsService.noteOperation(appOp,
- filter.receiverList.uid, filter.packageName)
- != AppOpsManager.MODE_ALLOWED) {
- Slog.w(TAG, "Appop Denial: receiving "
+ if (!skip && r.requiredPermissions != null && r.requiredPermissions.length > 0) {
+ for (int i = 0; i < r.requiredPermissions.length; i++) {
+ String requiredPermission = r.requiredPermissions[i];
+ int perm = mService.checkComponentPermission(requiredPermission,
+ filter.receiverList.pid, filter.receiverList.uid, -1, true);
+ if (perm != PackageManager.PERMISSION_GRANTED) {
+ Slog.w(TAG, "Permission Denial: receiving "
+ r.intent.toString()
+ " to " + filter.receiverList.app
+ " (pid=" + filter.receiverList.pid
+ ", uid=" + filter.receiverList.uid + ")"
- + " requires appop " + AppOpsManager.permissionToOp(
- r.requiredPermission)
+ + " requires " + requiredPermission
+ " due to sender " + r.callerPackage
+ " (uid " + r.callingUid + ")");
skip = true;
+ break;
}
- }
- if (!skip && r.appOp != appOp && r.appOp != AppOpsManager.OP_NONE
- && mService.mAppOpsService.noteOperation(r.appOp,
- filter.receiverList.uid, filter.packageName)
- != AppOpsManager.MODE_ALLOWED) {
+ int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
+ if (appOp != r.appOp
+ && mService.mAppOpsService.noteOperation(appOp,
+ filter.receiverList.uid, filter.packageName)
+ != AppOpsManager.MODE_ALLOWED) {
Slog.w(TAG, "Appop Denial: receiving "
+ r.intent.toString()
+ " to " + filter.receiverList.app
+ " (pid=" + filter.receiverList.pid
+ ", uid=" + filter.receiverList.uid + ")"
+ " requires appop " + AppOpsManager.permissionToOp(
- r.requiredPermission)
+ requiredPermission)
+ " due to sender " + r.callerPackage
+ " (uid " + r.callingUid + ")");
skip = true;
+ break;
+ }
+ }
+ }
+ if (!skip && (r.requiredPermissions == null || r.requiredPermissions.length == 0)) {
+ int perm = mService.checkComponentPermission(null,
+ filter.receiverList.pid, filter.receiverList.uid, -1, true);
+ if (perm != PackageManager.PERMISSION_GRANTED) {
+ Slog.w(TAG, "Permission Denial: security check failed when receiving "
+ + r.intent.toString()
+ + " to " + filter.receiverList.app
+ + " (pid=" + filter.receiverList.pid
+ + ", uid=" + filter.receiverList.uid + ")"
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
+ skip = true;
}
}
+ if (!skip && r.appOp != AppOpsManager.OP_NONE
+ && mService.mAppOpsService.noteOperation(r.appOp,
+ filter.receiverList.uid, filter.packageName)
+ != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Appop Denial: receiving "
+ + r.intent.toString()
+ + " to " + filter.receiverList.app
+ + " (pid=" + filter.receiverList.pid
+ + ", uid=" + filter.receiverList.uid + ")"
+ + " requires appop " + AppOpsManager.opToName(r.appOp)
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
+ skip = true;
+ }
- if (!skip) {
- skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
- r.callingPid, r.resolvedType, filter.receiverList.uid);
+ if (!mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
+ r.callingPid, r.resolvedType, filter.receiverList.uid)) {
+ return;
}
if (filter.receiverList.app == null || filter.receiverList.app.crashing) {
@@ -860,51 +875,53 @@ public final class BroadcastQueue {
}
}
if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
- r.requiredPermission != null) {
- try {
- perm = AppGlobals.getPackageManager().
- checkPermission(r.requiredPermission,
- info.activityInfo.applicationInfo.packageName,
- UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
- } catch (RemoteException e) {
- perm = PackageManager.PERMISSION_DENIED;
- }
- if (perm != PackageManager.PERMISSION_GRANTED) {
- Slog.w(TAG, "Permission Denial: receiving "
- + r.intent + " to "
- + component.flattenToShortString()
- + " requires " + r.requiredPermission
- + " due to sender " + r.callerPackage
- + " (uid " + r.callingUid + ")");
- skip = true;
- }
- }
- int appOp = AppOpsManager.OP_NONE;
- if (!skip && r.requiredPermission != null) {
- appOp = AppOpsManager.permissionToOpCode(r.requiredPermission);
- if (appOp != AppOpsManager.OP_NONE
- && mService.mAppOpsService.noteOperation(appOp,
- info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
- != AppOpsManager.MODE_ALLOWED) {
- Slog.w(TAG, "Appop Denial: receiving "
- + r.intent + " to "
- + component.flattenToShortString()
- + " requires appop " + AppOpsManager.permissionToOp(
- r.requiredPermission)
- + " due to sender " + r.callerPackage
- + " (uid " + r.callingUid + ")");
- skip = true;
+ r.requiredPermissions != null && r.requiredPermissions.length > 0) {
+ for (int i = 0; i < r.requiredPermissions.length; i++) {
+ String requiredPermission = r.requiredPermissions[i];
+ try {
+ perm = AppGlobals.getPackageManager().
+ checkPermission(requiredPermission,
+ info.activityInfo.applicationInfo.packageName,
+ UserHandle
+ .getUserId(info.activityInfo.applicationInfo.uid));
+ } catch (RemoteException e) {
+ perm = PackageManager.PERMISSION_DENIED;
+ }
+ if (perm != PackageManager.PERMISSION_GRANTED) {
+ Slog.w(TAG, "Permission Denial: receiving "
+ + r.intent + " to "
+ + component.flattenToShortString()
+ + " requires " + requiredPermission
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
+ skip = true;
+ break;
+ }
+ int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
+ if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
+ && mService.mAppOpsService.noteOperation(appOp,
+ info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+ != AppOpsManager.MODE_ALLOWED) {
+ Slog.w(TAG, "Appop Denial: receiving "
+ + r.intent + " to "
+ + component.flattenToShortString()
+ + " requires appop " + AppOpsManager.permissionToOp(
+ requiredPermission)
+ + " due to sender " + r.callerPackage
+ + " (uid " + r.callingUid + ")");
+ skip = true;
+ break;
+ }
}
}
- if (!skip && r.appOp != appOp && r.appOp != AppOpsManager.OP_NONE
+ if (!skip && r.appOp != AppOpsManager.OP_NONE
&& mService.mAppOpsService.noteOperation(r.appOp,
- info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
- != AppOpsManager.MODE_ALLOWED) {
+ info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
+ != AppOpsManager.MODE_ALLOWED) {
Slog.w(TAG, "Appop Denial: receiving "
+ r.intent + " to "
+ component.flattenToShortString()
- + " requires appop " + AppOpsManager.permissionToOp(
- r.requiredPermission)
+ + " requires appop " + AppOpsManager.opToName(r.appOp)
+ " due to sender " + r.callerPackage
+ " (uid " + r.callingUid + ")");
skip = true;
diff --git a/services/core/java/com/android/server/am/BroadcastRecord.java b/services/core/java/com/android/server/am/BroadcastRecord.java
index b943222..a7e6471 100644
--- a/services/core/java/com/android/server/am/BroadcastRecord.java
+++ b/services/core/java/com/android/server/am/BroadcastRecord.java
@@ -32,6 +32,7 @@ import android.util.PrintWriterPrinter;
import android.util.TimeUtils;
import java.io.PrintWriter;
+import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Set;
@@ -51,7 +52,7 @@ final class BroadcastRecord extends Binder {
final boolean initialSticky; // initial broadcast from register to sticky?
final int userId; // user id this broadcast was for
final String resolvedType; // the resolved data type
- final String requiredPermission; // a permission the caller has required
+ final String[] requiredPermissions; // permissions the caller has required
final int appOp; // an app op that is associated with this broadcast
final BroadcastOptions options; // BroadcastOptions supplied by caller
final List receivers; // contains BroadcastFilter and ResolveInfo
@@ -103,9 +104,11 @@ final class BroadcastRecord extends Binder {
pw.print(callerApp != null ? callerApp.toShortString() : "null");
pw.print(" pid="); pw.print(callingPid);
pw.print(" uid="); pw.println(callingUid);
- if (requiredPermission != null || appOp != AppOpsManager.OP_NONE) {
- pw.print(prefix); pw.print("requiredPermission="); pw.print(requiredPermission);
- pw.print(" appOp="); pw.println(appOp);
+ if ((requiredPermissions != null && requiredPermissions.length > 0)
+ || appOp != AppOpsManager.OP_NONE) {
+ pw.print(prefix); pw.print("requiredPermissions=");
+ pw.print(Arrays.toString(requiredPermissions));
+ pw.print(" appOp="); pw.println(appOp);
}
if (options != null) {
pw.print(prefix); pw.print("options="); pw.println(options.toBundle());
@@ -184,7 +187,7 @@ final class BroadcastRecord extends Binder {
BroadcastRecord(BroadcastQueue _queue,
Intent _intent, ProcessRecord _callerApp, String _callerPackage,
- int _callingPid, int _callingUid, String _resolvedType, String _requiredPermission,
+ int _callingPid, int _callingUid, String _resolvedType, String[] _requiredPermissions,
int _appOp, BroadcastOptions _options, List _receivers, IIntentReceiver _resultTo,
int _resultCode, String _resultData, Bundle _resultExtras, boolean _serialized,
boolean _sticky, boolean _initialSticky,
@@ -197,7 +200,7 @@ final class BroadcastRecord extends Binder {
callingPid = _callingPid;
callingUid = _callingUid;
resolvedType = _resolvedType;
- requiredPermission = _requiredPermission;
+ requiredPermissions = _requiredPermissions;
appOp = _appOp;
options = _options;
receivers = _receivers;