summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author ThiƩbaud Weksteen <tweek@google.com> 2022-11-02 23:03:07 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2022-11-02 23:03:07 +0000
commit4f2bc9a73a4403a91644668de899301bf3b4124f (patch)
treea23d298e2cddfa434580a393335dab2c077d66d3
parentf74a4b312b92e84e4a18eecea8cdabc689e58dde (diff)
parent0e318f1938dfa0c7a9ef789e8ca4fe1273e429f3 (diff)
Merge changes I72f810a7,I2bd23f62
* changes: Add OWNER entry for android.os.PermissionEnforcer Add PermissionEnforcer class
-rw-r--r--core/java/android/app/SystemServiceRegistry.java9
-rw-r--r--core/java/android/content/Context.java8
-rw-r--r--core/java/android/os/OWNERS4
-rw-r--r--core/java/android/os/PermissionEnforcer.java101
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);
+ }
+}