From 8e806dd2b155e67fab40698d80d6c4e4b3e54d5c Mon Sep 17 00:00:00 2001 From: mattgilbride Date: Thu, 20 Oct 2022 23:48:52 +0000 Subject: [PATCH] Add parameters to @PermissionMethod - orSelf: signifies that this method checks if the calling process OR the current process has the permission - anyOf: signifies that if this method checks multiple permissions, the check passes if ANY ONE of the permissions is granted - value (default parameter): a hard coded list of permissions that this method checks. This parameter is useful for static analysis, where the implementation of some @PermissionMethod may not be visible across library boundaries. A good example of this is NetworkStack#checkNetworkStackPermission, which is a source in framework-minus-apex, but is used from services.core.unboosted. Since it passes straight into a helper which checks the actual permissions, it's not possible for lint running on services.core.unboosted to see which permissions are checked. Bug: 247537842 Test: TH Change-Id: Ia5d92149763766576602f5d84a86c67f6fb7e96d --- core/java/android/content/Context.java | 4 ++-- .../android/content/pm/PermissionMethod.java | 18 +++++++++++++++++- .../server/am/ActivityManagerService.java | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index ae1f68958d0f1..05beef8ce3584 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -6172,7 +6172,7 @@ public abstract class Context { */ @CheckResult(suggest="#enforceCallingOrSelfPermission(String,String)") @PackageManager.PermissionResult - @PermissionMethod + @PermissionMethod(orSelf = true) public abstract int checkCallingOrSelfPermission(@NonNull @PermissionName String permission); /** @@ -6240,7 +6240,7 @@ public abstract class Context { * * @see #checkCallingOrSelfPermission(String) */ - @PermissionMethod + @PermissionMethod(orSelf = true) public abstract void enforceCallingOrSelfPermission( @NonNull @PermissionName String permission, @Nullable String message); diff --git a/core/java/android/content/pm/PermissionMethod.java b/core/java/android/content/pm/PermissionMethod.java index ba97342c5e3ee..647c696b87f33 100644 --- a/core/java/android/content/pm/PermissionMethod.java +++ b/core/java/android/content/pm/PermissionMethod.java @@ -33,4 +33,20 @@ import java.lang.annotation.Target; */ @Retention(CLASS) @Target({METHOD}) -public @interface PermissionMethod {} +public @interface PermissionMethod { + /** + * Hard-coded list of permissions checked by this method + */ + @PermissionName String[] value() default {}; + /** + * If true, the check passes if the caller + * has any ONE of the supplied permissions + */ + boolean anyOf() default false; + /** + * Signifies that the permission check passes if + * the calling process OR the current process has + * the permission + */ + boolean orSelf() default false; +} diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 6394d77446454..c48fb66fe3e77 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -6141,6 +6141,7 @@ public class ActivityManagerService extends IActivityManager.Stub /** * This can be called with or without the global lock held. */ + @PermissionMethod(anyOf = true) private void enforceCallingHasAtLeastOnePermission(String func, String... permissions) { for (String permission : permissions) { if (checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) {