From ca643c5c337a910559e5c1d25cb3f692bdd272ff Mon Sep 17 00:00:00 2001 From: Soonil Nagarkar Date: Thu, 16 Jul 2020 13:07:08 -0700 Subject: [PATCH] DO NOT MERGE Add permission checks before delivery PendingIntent.send() only checks permissions for broadcast intents, and not for activity/service intents. In order to ensure permissions are checked for all types of intents, we need to add permission checks earlier in the process. Bug: 161456367 Test: presubmits + manual Change-Id: Ib56a382f4a2a8d25aa23a8230e0b82edf024a6fd --- .../android/server/location/AppOpsHelper.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/location/AppOpsHelper.java b/services/core/java/com/android/server/location/AppOpsHelper.java index c598fb1dbe260..d0192cdb93d32 100644 --- a/services/core/java/com/android/server/location/AppOpsHelper.java +++ b/services/core/java/com/android/server/location/AppOpsHelper.java @@ -18,7 +18,9 @@ package com.android.server.location; import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION; import static android.app.AppOpsManager.OP_MONITOR_LOCATION; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static com.android.server.location.CallerIdentity.PERMISSION_NONE; import static com.android.server.location.LocationManagerService.D; import static com.android.server.location.LocationManagerService.TAG; @@ -122,8 +124,18 @@ public class AppOpsHelper { Preconditions.checkState(mAppOps != null); } + if (callerIdentity.permissionLevel == PERMISSION_NONE) { + return false; + } + long identity = Binder.clearCallingIdentity(); try { + if (mContext.checkPermission( + CallerIdentity.asPermission(callerIdentity.permissionLevel), callerIdentity.pid, + callerIdentity.uid) != PERMISSION_GRANTED) { + return false; + } + return mAppOps.checkOpNoThrow( CallerIdentity.asAppOp(callerIdentity.permissionLevel), callerIdentity.uid, @@ -138,8 +150,24 @@ public class AppOpsHelper { * called right before a location is delivered, and if it returns false, the location should not * be delivered. */ - public boolean noteLocationAccess(CallerIdentity identity) { - return noteOpNoThrow(CallerIdentity.asAppOp(identity.permissionLevel), identity); + public boolean noteLocationAccess(CallerIdentity callerIdentity) { + if (callerIdentity.permissionLevel == PERMISSION_NONE) { + return false; + } + + long identity = Binder.clearCallingIdentity(); + try { + if (mContext.checkPermission( + CallerIdentity.asPermission(callerIdentity.permissionLevel), callerIdentity.pid, + callerIdentity.uid) != PERMISSION_GRANTED) { + return false; + } + } finally { + Binder.restoreCallingIdentity(identity); + } + + return noteOpNoThrow(CallerIdentity.asAppOp(callerIdentity.permissionLevel), + callerIdentity); } /**