diff options
| author | 2022-11-02 23:03:07 +0000 | |
|---|---|---|
| committer | 2022-11-02 23:03:07 +0000 | |
| commit | 4f2bc9a73a4403a91644668de899301bf3b4124f (patch) | |
| tree | a23d298e2cddfa434580a393335dab2c077d66d3 | |
| parent | f74a4b312b92e84e4a18eecea8cdabc689e58dde (diff) | |
| parent | 0e318f1938dfa0c7a9ef789e8ca4fe1273e429f3 (diff) | |
Merge changes I72f810a7,I2bd23f62
* changes:
Add OWNER entry for android.os.PermissionEnforcer
Add PermissionEnforcer class
| -rw-r--r-- | core/java/android/app/SystemServiceRegistry.java | 9 | ||||
| -rw-r--r-- | core/java/android/content/Context.java | 8 | ||||
| -rw-r--r-- | core/java/android/os/OWNERS | 4 | ||||
| -rw-r--r-- | core/java/android/os/PermissionEnforcer.java | 101 |
4 files changed, 122 insertions, 0 deletions
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index bdecca379b20..8bbddbf136b9 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -171,6 +171,7 @@ import android.os.IThermalService; import android.os.IUserManager; import android.os.IncidentManager; import android.os.PerformanceHintManager; +import android.os.PermissionEnforcer; import android.os.PowerManager; import android.os.RecoverySystem; import android.os.ServiceManager; @@ -1351,6 +1352,14 @@ public final class SystemServiceRegistry { return new PermissionCheckerManager(ctx.getOuterContext()); }}); + registerService(Context.PERMISSION_ENFORCER_SERVICE, PermissionEnforcer.class, + new CachedServiceFetcher<PermissionEnforcer>() { + @Override + public PermissionEnforcer createService(ContextImpl ctx) + throws ServiceNotFoundException { + return new PermissionEnforcer(ctx.getOuterContext()); + }}); + registerService(Context.DYNAMIC_SYSTEM_SERVICE, DynamicSystemManager.class, new CachedServiceFetcher<DynamicSystemManager>() { @Override diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index fce23cf6819a..0735532ce037 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -5135,6 +5135,14 @@ public abstract class Context { public static final String PERMISSION_CHECKER_SERVICE = "permission_checker"; /** + * Official published name of the (internal) permission enforcer service. + * + * @see #getSystemService(String) + * @hide + */ + public static final String PERMISSION_ENFORCER_SERVICE = "permission_enforcer"; + + /** * Use with {@link #getSystemService(String) to retrieve an * {@link android.apphibernation.AppHibernationManager}} for * communicating with the hibernation service. diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS index d84037f66648..9d8df7e62bce 100644 --- a/core/java/android/os/OWNERS +++ b/core/java/android/os/OWNERS @@ -70,3 +70,7 @@ per-file Vintf* = file:/platform/system/libvintf:/OWNERS # Tracing per-file Trace.java = file:/TRACE_OWNERS + +# PermissionEnforcer +per-file PermissionEnforcer.java = tweek@google.com, brufino@google.com +per-file PermissionEnforcer.java = file:/core/java/android/permission/OWNERS diff --git a/core/java/android/os/PermissionEnforcer.java b/core/java/android/os/PermissionEnforcer.java new file mode 100644 index 000000000000..221e89a6a76f --- /dev/null +++ b/core/java/android/os/PermissionEnforcer.java @@ -0,0 +1,101 @@ +/* + * 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.os; + +import android.annotation.NonNull; +import android.annotation.SystemService; +import android.content.AttributionSource; +import android.content.Context; +import android.content.PermissionChecker; +import android.permission.PermissionCheckerManager; + +/** + * PermissionEnforcer check permissions for AIDL-generated services which use + * the @EnforcePermission annotation. + * + * <p>AIDL services may be annotated with @EnforcePermission which will trigger + * the generation of permission check code. This generated code relies on + * PermissionEnforcer to validate the permissions. The methods available are + * purposely similar to the AIDL annotation syntax. + * + * @see android.permission.PermissionManager + * + * @hide + */ +@SystemService(Context.PERMISSION_ENFORCER_SERVICE) +public class PermissionEnforcer { + + private final Context mContext; + + /** Protected constructor. Allows subclasses to instantiate an object + * without using a Context. + */ + protected PermissionEnforcer() { + mContext = null; + } + + /** Constructor, prefer using the fromContext static method when possible */ + public PermissionEnforcer(@NonNull Context context) { + mContext = context; + } + + @PermissionCheckerManager.PermissionResult + protected int checkPermission(@NonNull String permission, @NonNull AttributionSource source) { + return PermissionChecker.checkPermissionForDataDelivery( + mContext, permission, PermissionChecker.PID_UNKNOWN, source, "" /* message */); + } + + public void enforcePermission(@NonNull String permission, @NonNull + AttributionSource source) throws SecurityException { + int result = checkPermission(permission, source); + if (result != PermissionCheckerManager.PERMISSION_GRANTED) { + throw new SecurityException("Access denied, requires: " + permission); + } + } + + public void enforcePermissionAllOf(@NonNull String[] permissions, + @NonNull AttributionSource source) throws SecurityException { + for (String permission : permissions) { + int result = checkPermission(permission, source); + if (result != PermissionCheckerManager.PERMISSION_GRANTED) { + throw new SecurityException("Access denied, requires: allOf={" + + String.join(", ", permissions) + "}"); + } + } + } + + public void enforcePermissionAnyOf(@NonNull String[] permissions, + @NonNull AttributionSource source) throws SecurityException { + for (String permission : permissions) { + int result = checkPermission(permission, source); + if (result == PermissionCheckerManager.PERMISSION_GRANTED) { + return; + } + } + throw new SecurityException("Access denied, requires: anyOf={" + + String.join(", ", permissions) + "}"); + } + + /** + * Returns a new PermissionEnforcer based on a Context. + * + * @hide + */ + public static PermissionEnforcer fromContext(@NonNull Context context) { + return context.getSystemService(PermissionEnforcer.class); + } +} |