diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 419b8e1ef0164..626b7d3cd5b1c 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -30,6 +30,7 @@ import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ActivityPresentationInfo; import android.content.pm.ApplicationInfo; +import android.content.pm.PermissionMethod; import android.content.pm.UserInfo; import android.net.Uri; import android.os.Bundle; @@ -292,6 +293,7 @@ public abstract class ActivityManagerInternal { boolean allowAll, int allowMode, String name, String callerPackage); /** Checks if the calling binder pid as the permission. */ + @PermissionMethod public abstract void enforceCallingPermission(String permission, String func); /** Returns the current user id. */ diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 97da2daf6e595..430b52c28f272 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -51,6 +51,7 @@ import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.content.pm.PermissionMethod; import android.content.res.AssetManager; import android.content.res.ColorStateList; import android.content.res.Configuration; @@ -6066,6 +6067,7 @@ public abstract class Context { */ @CheckResult(suggest="#enforcePermission(String,int,int,String)") @PackageManager.PermissionResult + @PermissionMethod public abstract int checkPermission(@NonNull String permission, int pid, int uid); /** @hide */ @@ -6098,6 +6100,7 @@ public abstract class Context { */ @CheckResult(suggest="#enforceCallingPermission(String,String)") @PackageManager.PermissionResult + @PermissionMethod public abstract int checkCallingPermission(@NonNull String permission); /** @@ -6118,6 +6121,7 @@ public abstract class Context { */ @CheckResult(suggest="#enforceCallingOrSelfPermission(String,String)") @PackageManager.PermissionResult + @PermissionMethod public abstract int checkCallingOrSelfPermission(@NonNull String permission); /** @@ -6146,6 +6150,7 @@ public abstract class Context { * * @see #checkPermission(String, int, int) */ + @PermissionMethod public abstract void enforcePermission( @NonNull String permission, int pid, int uid, @Nullable String message); @@ -6167,6 +6172,7 @@ public abstract class Context { * * @see #checkCallingPermission(String) */ + @PermissionMethod public abstract void enforceCallingPermission( @NonNull String permission, @Nullable String message); @@ -6183,6 +6189,7 @@ public abstract class Context { * * @see #checkCallingOrSelfPermission(String) */ + @PermissionMethod public abstract void enforceCallingOrSelfPermission( @NonNull String permission, @Nullable String message); diff --git a/core/java/android/content/pm/PermissionMethod.java b/core/java/android/content/pm/PermissionMethod.java new file mode 100644 index 0000000000000..021b2e1cd8f12 --- /dev/null +++ b/core/java/android/content/pm/PermissionMethod.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.CLASS; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Documents that the subject method's job is to look + * up whether the provided or calling uid/pid has the requested permission. + * + * Methods should either return `void`, but potentially throw {@link SecurityException}, + * or return {@link android.content.pm.PackageManager.PermissionResult} `int`. + * + * @hide + */ +@Retention(CLASS) +@Target({METHOD}) +public @interface PermissionMethod {} diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index d98dffbe1f562..50b47a6b22f14 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -245,6 +245,7 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.PermissionInfo; +import android.content.pm.PermissionMethod; import android.content.pm.ProcessInfo; import android.content.pm.ProviderInfo; import android.content.pm.ProviderInfoList; @@ -5963,6 +5964,12 @@ public class ActivityManagerService extends IActivityManager.Stub } } + /** + * Allows if {@code pid} is {@link #MY_PID}, then denies if the {@code pid} has been denied + * provided non-{@code null} {@code permission} before. Otherwise calls into + * {@link ActivityManager#checkComponentPermission(String, int, int, boolean)}. + */ + @PermissionMethod public static int checkComponentPermission(String permission, int pid, int uid, int owningUid, boolean exported) { if (pid == MY_PID) { @@ -6009,6 +6016,7 @@ public class ActivityManagerService extends IActivityManager.Stub * This can be called with or without the global lock held. */ @Override + @PermissionMethod public int checkPermission(String permission, int pid, int uid) { if (permission == null) { return PackageManager.PERMISSION_DENIED; @@ -6020,6 +6028,7 @@ public class ActivityManagerService extends IActivityManager.Stub * Binder IPC calls go through the public entry point. * This can be called with or without the global lock held. */ + @PermissionMethod int checkCallingPermission(String permission) { return checkPermission(permission, Binder.getCallingPid(), @@ -6029,6 +6038,7 @@ public class ActivityManagerService extends IActivityManager.Stub /** * This can be called with or without the global lock held. */ + @PermissionMethod void enforceCallingPermission(String permission, String func) { if (checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED) { @@ -6046,6 +6056,7 @@ public class ActivityManagerService extends IActivityManager.Stub /** * This can be called with or without the global lock held. */ + @PermissionMethod void enforcePermission(String permission, int pid, int uid, String func) { if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) { return;