diff options
Diffstat (limited to 'services')
7 files changed, 272 insertions, 94 deletions
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index 79c66b9..f0fc399 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -116,6 +116,8 @@ public class AppOpsService extends IAppOpsService.Stub { public final static class Op { public final int uid; public final String packageName; + public int proxyUid = -1; + public String proxyPackageName; public final int op; public int mode; public int duration; @@ -289,7 +291,8 @@ public class AppOpsService extends IAppOpsService.Stub { for (int j=0; j<pkgOps.size(); j++) { Op curOp = pkgOps.valueAt(j); resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, - curOp.rejectTime, curOp.duration)); + curOp.rejectTime, curOp.duration, curOp.proxyUid, + curOp.proxyPackageName)); } } else { for (int j=0; j<ops.length; j++) { @@ -299,7 +302,8 @@ public class AppOpsService extends IAppOpsService.Stub { resOps = new ArrayList<AppOpsManager.OpEntry>(); } resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, - curOp.rejectTime, curOp.duration)); + curOp.rejectTime, curOp.duration, curOp.proxyUid, + curOp.proxyPackageName)); } } } @@ -659,9 +663,28 @@ public class AppOpsService extends IAppOpsService.Stub { } @Override + public int noteProxyOperation(int code, String proxyPackageName, + int proxiedUid, String proxiedPackageName) { + verifyIncomingOp(code); + final int proxyMode = noteOperationUnchecked(code, Binder.getCallingUid(), + proxyPackageName, -1, null); + if (proxyMode != AppOpsManager.MODE_ALLOWED || Binder.getCallingUid() == proxiedUid) { + return proxyMode; + } + return noteOperationUnchecked(code, proxiedUid, proxiedPackageName, + Binder.getCallingUid(), proxyPackageName); + + } + + @Override public int noteOperation(int code, int uid, String packageName) { verifyIncomingUid(uid); verifyIncomingOp(code); + return noteOperationUnchecked(code, uid, packageName, 0, null); + } + + private int noteOperationUnchecked(int code, int uid, String packageName, + int proxyUid, String proxyPackageName) { synchronized (this) { Ops ops = getOpsLocked(uid, packageName, true); if (ops == null) { @@ -690,6 +713,8 @@ public class AppOpsService extends IAppOpsService.Stub { + " package " + packageName); op.time = System.currentTimeMillis(); op.rejectTime = 0; + op.proxyUid = proxyUid; + op.proxyPackageName = proxyPackageName; return AppOpsManager.MODE_ALLOWED; } } @@ -1051,6 +1076,14 @@ public class AppOpsService extends IAppOpsService.Stub { if (dur != null) { op.duration = Integer.parseInt(dur); } + String proxyUid = parser.getAttributeValue(null, "pu"); + if (proxyUid != null) { + op.proxyUid = Integer.parseInt(proxyUid); + } + String proxyPackageName = parser.getAttributeValue(null, "pp"); + if (proxyPackageName != null) { + op.proxyPackageName = proxyPackageName; + } HashMap<String, Ops> pkgOps = mUidOps.get(uid); if (pkgOps == null) { pkgOps = new HashMap<String, Ops>(); @@ -1132,6 +1165,14 @@ public class AppOpsService extends IAppOpsService.Stub { if (dur != 0) { out.attribute(null, "d", Integer.toString(dur)); } + int proxyUid = op.getProxyUid(); + if (proxyUid != -1) { + out.attribute(null, "pu", Integer.toString(proxyUid)); + } + String proxyPackageName = op.getProxyPackageName(); + if (proxyPackageName != null) { + out.attribute(null, "pp", proxyPackageName); + } out.endTag(null, "op"); } out.endTag(null, "uid"); diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 333db5d..899139f 100755 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -29,6 +29,7 @@ import java.util.List; import java.util.Set; import android.app.ActivityThread; +import android.app.AppOpsManager; import android.os.Build; import android.os.DeadObjectException; import android.os.Handler; @@ -302,8 +303,8 @@ public final class ActiveServices { return getServiceMap(callingUser).mServicesByName; } - ComponentName startServiceLocked(IApplicationThread caller, Intent service, - String resolvedType, int callingPid, int callingUid, int userId) + ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, + int callingPid, int callingUid, String callingPackage, int userId) throws TransactionTooLargeException { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service + " type=" + resolvedType + " args=" + service.getExtras()); @@ -324,7 +325,7 @@ public final class ActiveServices { ServiceLookupResult res = - retrieveServiceLocked(service, resolvedType, + retrieveServiceLocked(service, resolvedType, callingPackage, callingPid, callingUid, userId, true, callerFg); if (res == null) { return null; @@ -490,7 +491,7 @@ public final class ActiveServices { } // If this service is active, make sure it is stopped. - ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, + ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null, Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false); if (r != null) { if (r.record != null) { @@ -508,8 +509,8 @@ public final class ActiveServices { return 0; } - IBinder peekServiceLocked(Intent service, String resolvedType) { - ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, + IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) { + ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), UserHandle.getCallingUserId(), false, false); @@ -694,8 +695,8 @@ public final class ActiveServices { } int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, - String resolvedType, IServiceConnection connection, int flags, int userId) - throws TransactionTooLargeException { + String resolvedType, IServiceConnection connection, int flags, + String callingPackage, int userId) throws TransactionTooLargeException { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service + " type=" + resolvedType + " conn=" + connection.asBinder() + " flags=0x" + Integer.toHexString(flags)); @@ -746,7 +747,7 @@ public final class ActiveServices { final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE; ServiceLookupResult res = - retrieveServiceLocked(service, resolvedType, + retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg); if (res == null) { return 0; @@ -1022,7 +1023,7 @@ public final class ActiveServices { } private ServiceLookupResult retrieveServiceLocked(Intent service, - String resolvedType, int callingPid, int callingUid, int userId, + String resolvedType, String callingPackage, int callingPid, int callingUid, int userId, boolean createIfNeeded, boolean callingFromFg) { ServiceRecord r = null; if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "retrieveServiceLocked: " + service @@ -1112,7 +1113,18 @@ public final class ActiveServices { + ", uid=" + callingUid + " requires " + r.permission); return new ServiceLookupResult(null, r.permission); + } else if (r.permission != null && callingPackage != null) { + final int opCode = AppOpsManager.permissionToOpCode(r.permission); + if (opCode != AppOpsManager.OP_NONE && mAm.mAppOpsService.noteOperation( + opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) { + Slog.w(TAG, "Appop Denial: Accessing service " + r.name + + " from pid=" + callingPid + + ", uid=" + callingUid + + " requires appop " + AppOpsManager.opToName(opCode)); + return null; + } } + if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid, resolvedType, r.appInfo)) { return null; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 959fd37..6522d40 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -15554,13 +15554,18 @@ public final class ActivityManagerService extends ActivityManagerNative @Override public ComponentName startService(IApplicationThread caller, Intent service, - String resolvedType, int userId) throws TransactionTooLargeException { + String resolvedType, String callingPackage, int userId) + throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); // Refuse possible leaked file descriptors if (service != null && service.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } + if (callingPackage == null) { + throw new IllegalArgumentException("callingPackage cannot be null"); + } + if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "startService: " + service + " type=" + resolvedType); synchronized(this) { @@ -15568,20 +15573,21 @@ public final class ActivityManagerService extends ActivityManagerNative final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res = mServices.startServiceLocked(caller, service, - resolvedType, callingPid, callingUid, userId); + resolvedType, callingPid, callingUid, callingPackage, userId); Binder.restoreCallingIdentity(origId); return res; } } - ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, int userId) + ComponentName startServiceInPackage(int uid, Intent service, String resolvedType, + String callingPackage, int userId) throws TransactionTooLargeException { synchronized(this) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "startServiceInPackage: " + service + " type=" + resolvedType); final long origId = Binder.clearCallingIdentity(); ComponentName res = mServices.startServiceLocked(null, service, - resolvedType, -1, uid, userId); + resolvedType, -1, uid, callingPackage, userId); Binder.restoreCallingIdentity(origId); return res; } @@ -15602,14 +15608,19 @@ public final class ActivityManagerService extends ActivityManagerNative } @Override - public IBinder peekService(Intent service, String resolvedType) { + public IBinder peekService(Intent service, String resolvedType, String callingPackage) { enforceNotIsolatedCaller("peekService"); // Refuse possible leaked file descriptors if (service != null && service.hasFileDescriptors() == true) { throw new IllegalArgumentException("File descriptors passed in Intent"); } + + if (callingPackage == null) { + throw new IllegalArgumentException("callingPackage cannot be null"); + } + synchronized(this) { - return mServices.peekServiceLocked(service, resolvedType); + return mServices.peekServiceLocked(service, resolvedType, callingPackage); } } @@ -15779,8 +15790,8 @@ public final class ActivityManagerService extends ActivityManagerNative } public int bindService(IApplicationThread caller, IBinder token, Intent service, - String resolvedType, IServiceConnection connection, int flags, int userId) - throws TransactionTooLargeException { + String resolvedType, IServiceConnection connection, int flags, String callingPackage, + int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("bindService"); // Refuse possible leaked file descriptors @@ -15788,9 +15799,13 @@ public final class ActivityManagerService extends ActivityManagerNative throw new IllegalArgumentException("File descriptors passed in Intent"); } + if (callingPackage == null) { + throw new IllegalArgumentException("callingPackage cannot be null"); + } + synchronized(this) { - return mServices.bindServiceLocked(caller, token, service, resolvedType, - connection, flags, userId); + return mServices.bindServiceLocked(caller, token, service, + resolvedType, connection, flags, callingPackage, userId); } } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 4ce5c7e..c12aff6 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -187,12 +187,12 @@ public final class ActivityStackSupervisor implements DisplayListener { Manifest.permission.CALL_PHONE); } - /** Action not restricted for the calling package. */ - private static final int ACTION_RESTRICTION_NONE = 0; - /** Action restricted for the calling package by not granting a used permission. */ - private static final int ACTION_RESTRICTION_PERMISSION = 1; - /** Action restricted for the calling package by not allowing a used permission's app op. */ - private static final int ACTION_RESTRICTION_APPOP = 2; + /** Action restriction: launching the activity is not restricted. */ + private static final int ACTIVITY_RESTRICTION_NONE = 0; + /** Action restriction: launching the activity is restricted by a permission. */ + private static final int ACTIVITY_RESTRICTION_PERMISSION = 1; + /** Action restriction: launching the activity is restricted by an app op. */ + private static final int ACTIVITY_RESTRICTION_APPOP = 2; /** Status Bar Service **/ private IBinder mToken = new Binder(); @@ -1539,51 +1539,61 @@ public final class ActivityStackSupervisor implements DisplayListener { return err; } + boolean abort = false; + final int startAnyPerm = mService.checkPermission( START_ANY_ACTIVITY, callingPid, callingUid); - final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid, - callingUid, aInfo.applicationInfo.uid, aInfo.exported); - final int actionRestriction = getActionRestrictionForCallingPackage( - intent.getAction(), callingPackage, callingPid, callingUid); - if (startAnyPerm != PERMISSION_GRANTED && (componentPerm != PERMISSION_GRANTED - || actionRestriction == ACTION_RESTRICTION_PERMISSION)) { - if (resultRecord != null) { - resultStack.sendActivityResultLocked(-1, - resultRecord, resultWho, requestCode, - Activity.RESULT_CANCELED, null); + if (startAnyPerm != PERMISSION_GRANTED) { + final int componentRestriction = getComponentRestrictionForCallingPackage( + aInfo, callingPackage, callingPid, callingUid); + final int actionRestriction = getActionRestrictionForCallingPackage( + intent.getAction(), callingPackage, callingPid, callingUid); + + if (componentRestriction == ACTIVITY_RESTRICTION_PERMISSION + || actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { + if (resultRecord != null) { + resultStack.sendActivityResultLocked(-1, + resultRecord, resultWho, requestCode, + Activity.RESULT_CANCELED, null); + } + String msg; + if (actionRestriction == ACTIVITY_RESTRICTION_PERMISSION) { + msg = "Permission Denial: starting " + intent.toString() + + " from " + callerApp + " (pid=" + callingPid + + ", uid=" + callingUid + ")" + " with revoked permission " + + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()); + } else if (!aInfo.exported) { + msg = "Permission Denial: starting " + intent.toString() + + " from " + callerApp + " (pid=" + callingPid + + ", uid=" + callingUid + ")" + + " not exported from uid " + aInfo.applicationInfo.uid; + } else { + msg = "Permission Denial: starting " + intent.toString() + + " from " + callerApp + " (pid=" + callingPid + + ", uid=" + callingUid + ")" + + " requires " + aInfo.permission; + } + Slog.w(TAG, msg); + throw new SecurityException(msg); } - String msg; - if (actionRestriction == ACTION_RESTRICTION_PERMISSION) { - msg = "Permission Denial: starting " + intent.toString() - + " from " + callerApp + " (pid=" + callingPid - + ", uid=" + callingUid + ")" + " with revoked permission " - + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction()); - } else if (!aInfo.exported) { - msg = "Permission Denial: starting " + intent.toString() + + if (actionRestriction == ACTIVITY_RESTRICTION_APPOP) { + String message = "Appop Denial: starting " + intent.toString() + " from " + callerApp + " (pid=" + callingPid + ", uid=" + callingUid + ")" - + " not exported from uid " + aInfo.applicationInfo.uid; - } else { - msg = "Permission Denial: starting " + intent.toString() + + " requires " + AppOpsManager.permissionToOp( + ACTION_TO_RUNTIME_PERMISSION.get(intent.getAction())); + Slog.w(TAG, message); + abort = true; + } else if (componentRestriction == ACTIVITY_RESTRICTION_APPOP) { + String message = "Appop Denial: starting " + intent.toString() + " from " + callerApp + " (pid=" + callingPid + ", uid=" + callingUid + ")" - + " requires " + aInfo.permission; + + " requires appop " + AppOpsManager.permissionToOp(aInfo.permission); + Slog.w(TAG, message); + abort = true; } - Slog.w(TAG, msg); - throw new SecurityException(msg); - } - - boolean abort = false; - - if (startAnyPerm != PERMISSION_GRANTED - && actionRestriction == ACTION_RESTRICTION_APPOP) { - String msg = "Permission Denial: starting " + intent.toString() - + " from " + callerApp + " (pid=" + callingPid - + ", uid=" + callingUid + ")" - + " requires " + aInfo.permission; - Slog.w(TAG, msg); - abort = true; } abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, @@ -1664,15 +1674,40 @@ public final class ActivityStackSupervisor implements DisplayListener { return err; } + private int getComponentRestrictionForCallingPackage(ActivityInfo activityInfo, + String callingPackage, int callingPid, int callingUid) { + if (activityInfo.permission == null) { + return ACTIVITY_RESTRICTION_NONE; + } + + if (mService.checkComponentPermission(activityInfo.permission, callingPid, callingUid, + activityInfo.applicationInfo.uid, activityInfo.exported) + == PackageManager.PERMISSION_DENIED) { + return ACTIVITY_RESTRICTION_PERMISSION; + } + + final int opCode = AppOpsManager.permissionToOpCode(activityInfo.permission); + if (opCode == AppOpsManager.OP_NONE) { + return ACTIVITY_RESTRICTION_NONE; + } + + if (mService.mAppOpsService.noteOperation(opCode, callingUid, + callingPackage) != AppOpsManager.MODE_ALLOWED) { + return ACTIVITY_RESTRICTION_APPOP; + } + + return ACTIVITY_RESTRICTION_NONE; + } + private int getActionRestrictionForCallingPackage(String action, String callingPackage, int callingPid, int callingUid) { if (action == null) { - return ACTION_RESTRICTION_NONE; + return ACTIVITY_RESTRICTION_NONE; } String permission = ACTION_TO_RUNTIME_PERMISSION.get(action); if (permission == null) { - return ACTION_RESTRICTION_NONE; + return ACTIVITY_RESTRICTION_NONE; } final PackageInfo packageInfo; @@ -1681,29 +1716,29 @@ public final class ActivityStackSupervisor implements DisplayListener { .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS); } catch (PackageManager.NameNotFoundException e) { Slog.i(TAG, "Cannot find package info for " + callingPackage); - return ACTION_RESTRICTION_NONE; + return ACTIVITY_RESTRICTION_NONE; } if (!ArrayUtils.contains(packageInfo.requestedPermissions, permission)) { - return ACTION_RESTRICTION_NONE; + return ACTIVITY_RESTRICTION_NONE; } if (mService.checkPermission(permission, callingPid, callingUid) == PackageManager.PERMISSION_DENIED) { - return ACTION_RESTRICTION_PERMISSION; + return ACTIVITY_RESTRICTION_PERMISSION; } final int opCode = AppOpsManager.permissionToOpCode(permission); if (opCode == AppOpsManager.OP_NONE) { - return ACTION_RESTRICTION_NONE; + return ACTIVITY_RESTRICTION_NONE; } if (mService.mAppOpsService.noteOperation(opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) { - return ACTION_RESTRICTION_APPOP; + return ACTIVITY_RESTRICTION_APPOP; } - return ACTION_RESTRICTION_NONE; + return ACTIVITY_RESTRICTION_NONE; } ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) { diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 2335071..30aa411 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -463,7 +463,7 @@ public final class BroadcastQueue { } } - private final void deliverToRegisteredReceiverLocked(BroadcastRecord r, + private void deliverToRegisteredReceiverLocked(BroadcastRecord r, BroadcastFilter filter, boolean ordered) { boolean skip = false; if (filter.requiredPermission != null) { @@ -477,9 +477,23 @@ public final class BroadcastQueue { + " requires " + filter.requiredPermission + " due to registered receiver " + filter); skip = true; + } else { + final int opCode = AppOpsManager.permissionToOpCode(filter.requiredPermission); + if (opCode != AppOpsManager.OP_NONE + && mService.mAppOpsService.noteOperation(opCode, r.callingUid, + r.callerPackage) != AppOpsManager.MODE_ALLOWED) { + Slog.w(TAG, "Appop Denial: broadcasting " + + r.intent.toString() + + " from " + r.callerPackage + " (pid=" + + r.callingPid + ", uid=" + r.callingUid + ")" + + " requires appop " + AppOpsManager.permissionToOp( + filter.requiredPermission) + + " due to registered receiver " + filter); + skip = true; + } } } - if (!skip && r.requiredPermission != null) { + if (!skip) { int perm = mService.checkComponentPermission(r.requiredPermission, filter.receiverList.pid, filter.receiverList.uid, -1, true); if (perm != PackageManager.PERMISSION_GRANTED) { @@ -493,17 +507,42 @@ public final class BroadcastQueue { + " (uid " + r.callingUid + ")"); skip = true; } - } - if (r.appOp != AppOpsManager.OP_NONE) { - int mode = mService.mAppOpsService.noteOperation(r.appOp, - filter.receiverList.uid, filter.packageName); - if (mode != AppOpsManager.MODE_ALLOWED) { - if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, - "App op " + r.appOp + " not allowed for broadcast to uid " - + filter.receiverList.uid + " pkg " + filter.packageName); - 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 " + + r.intent.toString() + + " to " + filter.receiverList.app + + " (pid=" + filter.receiverList.pid + + ", uid=" + filter.receiverList.uid + ")" + + " requires appop " + AppOpsManager.permissionToOp( + r.requiredPermission) + + " due to sender " + r.callerPackage + + " (uid " + r.callingUid + ")"); + skip = true; + } + } + if (!skip && r.appOp != appOp && 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.permissionToOp( + r.requiredPermission) + + " 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); @@ -804,8 +843,23 @@ public final class BroadcastQueue { + " due to receiver " + component.flattenToShortString()); } skip = true; + } else if (info.activityInfo.permission != null) { + final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission); + if (opCode != AppOpsManager.OP_NONE + && mService.mAppOpsService.noteOperation(opCode, r.callingUid, + r.callerPackage) != AppOpsManager.MODE_ALLOWED) { + Slog.w(TAG, "Appop Denial: broadcasting " + + r.intent.toString() + + " from " + r.callerPackage + " (pid=" + + r.callingPid + ", uid=" + r.callingUid + ")" + + " requires appop " + AppOpsManager.permissionToOp( + info.activityInfo.permission) + + " due to registered receiver " + + component.flattenToShortString()); + skip = true; + } } - if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && + if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID && r.requiredPermission != null) { try { perm = AppGlobals.getPackageManager(). @@ -825,17 +879,36 @@ public final class BroadcastQueue { skip = true; } } - if (r.appOp != AppOpsManager.OP_NONE) { - int mode = mService.mAppOpsService.noteOperation(r.appOp, - info.activityInfo.applicationInfo.uid, info.activityInfo.packageName); - if (mode != AppOpsManager.MODE_ALLOWED) { - if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, - "App op " + r.appOp + " not allowed for broadcast to uid " - + info.activityInfo.applicationInfo.uid + " pkg " - + info.activityInfo.packageName); + 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; } } + if (!skip && r.appOp != appOp && r.appOp != AppOpsManager.OP_NONE + && mService.mAppOpsService.noteOperation(r.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; + } if (!skip) { skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid, r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid); diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index ece3ffb..5b46799 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -305,7 +305,8 @@ final class PendingIntentRecord extends IIntentSender.Stub { break; case ActivityManager.INTENT_SENDER_SERVICE: try { - owner.startServiceInPackage(uid, finalIntent, resolvedType, userId); + owner.startServiceInPackage(uid, finalIntent, + resolvedType, key.packageName, userId); } catch (RuntimeException e) { Slog.w(TAG, "Unable to send startService intent", e); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 1385440..f51e679 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -9163,7 +9163,8 @@ public class PackageManagerService extends IPackageManager.Stub { IActivityManager am = ActivityManagerNative.getDefault(); if (am != null) { try { - am.startService(null, intent, null, UserHandle.USER_OWNER); + am.startService(null, intent, null, mContext.getOpPackageName(), + UserHandle.USER_OWNER); } catch (RemoteException e) { } } |