diff options
6 files changed, 170 insertions, 18 deletions
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 42fa9e7d7994..74d729857cc8 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -4177,6 +4177,35 @@ public class DevicePolicyManager { } } + + /** + * Similar to the public variant of {@link #setMtePolicy} but for use by the system. + * + * <p>Called by a system service only, meaning that the caller's UID must be equal to + * {@link Process#SYSTEM_UID}. + * + * @throws SecurityException if caller is not permitted to set Mte policy + * @throws UnsupportedOperationException if the device does not support MTE + * @param systemEntity The service entity that adds the restriction. A user restriction set by + * a service entity can only be cleared by the same entity. This can be + * just the calling package name, or any string of the caller's choice + * can be used. + * @param policy the MTE policy to be set + * @hide + */ + public void setMtePolicy(@NonNull String systemEntity, @MtePolicy int policy) { + throwIfParentInstance("setMtePolicyForUser"); + if (mService != null) { + try { + mService.setMtePolicyBySystem(systemEntity, policy); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + } + + + /** * Called by a device owner, profile owner of an organization-owned device to * get the Memory Tagging Extension (MTE) policy diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index d048b5371fc4..e7be822d52d3 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -617,6 +617,7 @@ interface IDevicePolicyManager { int[] getApplicationExemptions(String packageName); void setMtePolicy(int flag, String callerPackageName); + void setMtePolicyBySystem(in String systemEntity, int policy); int getMtePolicy(String callerPackageName); void setManagedSubscriptionsPolicy(in ManagedSubscriptionsPolicy policy); diff --git a/core/java/android/security/responsible_apis_flags.aconfig b/core/java/android/security/responsible_apis_flags.aconfig index 357aba3fb136..3c3570173442 100644 --- a/core/java/android/security/responsible_apis_flags.aconfig +++ b/core/java/android/security/responsible_apis_flags.aconfig @@ -125,3 +125,10 @@ flag { description: "Android Advanced Protection Mode Feature: Disable Install Unknown Sources" bug: "369361373" } + +flag { + name: "aapm_feature_memory_tagging_extension" + namespace: "responsible_apis" + description: "Android Advanced Protection Mode Feature: Memory Tagging Extension" + bug: "378931989" +} diff --git a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java index e8723b91a541..c9655c684e7f 100644 --- a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java +++ b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java @@ -47,6 +47,7 @@ import com.android.server.pm.UserManagerInternal; import com.android.server.security.advancedprotection.features.AdvancedProtectionHook; import com.android.server.security.advancedprotection.features.AdvancedProtectionProvider; import com.android.server.security.advancedprotection.features.DisallowInstallUnknownSourcesAdvancedProtectionHook; +import com.android.server.security.advancedprotection.features.MemoryTaggingExtensionHook; import java.io.FileDescriptor; import java.util.ArrayList; @@ -80,6 +81,9 @@ public class AdvancedProtectionService extends IAdvancedProtectionService.Stub if (android.security.Flags.aapmFeatureDisableInstallUnknownSources()) { mHooks.add(new DisallowInstallUnknownSourcesAdvancedProtectionHook(mContext, enabled)); } + if (android.security.Flags.aapmFeatureMemoryTaggingExtension()) { + mHooks.add(new MemoryTaggingExtensionHook(mContext, enabled)); + } } // Only for tests diff --git a/services/core/java/com/android/server/security/advancedprotection/features/MemoryTaggingExtensionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/MemoryTaggingExtensionHook.java new file mode 100644 index 000000000000..d3d39371e883 --- /dev/null +++ b/services/core/java/com/android/server/security/advancedprotection/features/MemoryTaggingExtensionHook.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2024 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 com.android.server.security.advancedprotection.features; + +import static android.security.advancedprotection.AdvancedProtectionManager.ADVANCED_PROTECTION_SYSTEM_ENTITY; +import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_ENABLE_MTE; + +import android.annotation.NonNull; +import android.app.admin.DevicePolicyManager; +import android.content.Context; +import android.os.SystemProperties; +import android.security.advancedprotection.AdvancedProtectionFeature; +import android.util.Slog; + +/** @hide */ +public final class MemoryTaggingExtensionHook + extends AdvancedProtectionHook { + private static final String TAG = "AdvancedProtectionMTE"; + private static final String MTE_DPM_SYSTEM_PROPERTY = + "ro.arm64.memtag.bootctl_device_policy_manager"; + private static final String MTE_SETTINGS_SYSTEM_PROPERTY = + "ro.arm64.memtag.bootctl_settings_toggle"; + + private final AdvancedProtectionFeature mFeature = new AdvancedProtectionFeature( + FEATURE_ID_ENABLE_MTE); + private final DevicePolicyManager mDevicePolicyManager; + + public MemoryTaggingExtensionHook(@NonNull Context context, + boolean enabled) { + super(context, enabled); + mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class); + onAdvancedProtectionChanged(enabled); + } + + @NonNull + @Override + public AdvancedProtectionFeature getFeature() { + return mFeature; + } + + @Override + public boolean isAvailable() { + return SystemProperties.getBoolean(MTE_DPM_SYSTEM_PROPERTY, + SystemProperties.getBoolean(MTE_SETTINGS_SYSTEM_PROPERTY, false)); + } + + @Override + public void onAdvancedProtectionChanged(boolean enabled) { + if (!isAvailable()) { + Slog.i(TAG, "MTE unavailable on device, skipping."); + return; + } + final int mtePolicy; + if (enabled) { + mtePolicy = DevicePolicyManager.MTE_ENABLED; + } else { + mtePolicy = DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY; + } + + Slog.d(TAG, "Setting MTE state to " + mtePolicy); + try { + mDevicePolicyManager.setMtePolicy(ADVANCED_PROTECTION_SYSTEM_ENTITY, mtePolicy); + } catch (UnsupportedOperationException e) { + Slog.i(TAG, "Setting MTE policy unsupported", e); + } + } +} diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index dde213de1d40..1de45f4be617 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -23708,24 +23708,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } public void setMtePolicy(int flags, String callerPackageName) { - final Set<Integer> allowedModes = - Set.of( - DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY, - DevicePolicyManager.MTE_DISABLED, - DevicePolicyManager.MTE_ENABLED); - Preconditions.checkArgument( - allowedModes.contains(flags), "Provided mode is not one of the allowed values."); - // In general, this API should be available when "bootctl_settings_toggle" is set, which - // signals that there is a control for MTE in the user settings and this API fundamentally - // is a way for the device admin to override that setting. - // Allow bootctl_device_policy_manager as an override, e.g. to offer the - // DevicePolicyManager only without a visible user setting. - if (!mInjector.systemPropertiesGetBoolean( - "ro.arm64.memtag.bootctl_device_policy_manager", - mInjector.systemPropertiesGetBoolean( - "ro.arm64.memtag.bootctl_settings_toggle", false))) { - throw new UnsupportedOperationException("device does not support MTE"); - } + checkMteSupportedAndAllowedPolicy(flags); final CallerIdentity caller = getCallerIdentity(callerPackageName); // For now we continue to restrict the DISABLED setting to device owner - we might need // another permission for this in future. @@ -23783,6 +23766,53 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } @Override + public void setMtePolicyBySystem( + @NonNull String systemEntity, int policy) { + Objects.requireNonNull(systemEntity); + checkMteSupportedAndAllowedPolicy(policy); + + Preconditions.checkCallAuthorization(isSystemUid(getCallerIdentity()), + "Only system services can call setMtePolicyBySystem"); + + if (!Flags.setMtePolicyCoexistence()) { + throw new UnsupportedOperationException("System can not set MTE policy only"); + } + + EnforcingAdmin admin = EnforcingAdmin.createSystemEnforcingAdmin(systemEntity); + if (policy != DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY) { + mDevicePolicyEngine.setGlobalPolicy( + PolicyDefinition.MEMORY_TAGGING, + admin, + new IntegerPolicyValue(policy)); + } else { + mDevicePolicyEngine.removeGlobalPolicy( + PolicyDefinition.MEMORY_TAGGING, + admin); + } + } + + private void checkMteSupportedAndAllowedPolicy(int policy) { + final Set<Integer> allowedModes = + Set.of( + DevicePolicyManager.MTE_NOT_CONTROLLED_BY_POLICY, + DevicePolicyManager.MTE_DISABLED, + DevicePolicyManager.MTE_ENABLED); + Preconditions.checkArgument( + allowedModes.contains(policy), "Provided mode is not one of the allowed values."); + // In general, this API should be available when "bootctl_settings_toggle" is set, which + // signals that there is a control for MTE in the user settings and this API fundamentally + // is a way for the device admin to override that setting. + // Allow bootctl_device_policy_manager as an override, e.g. to offer the + // DevicePolicyManager only without a visible user setting. + if (!mInjector.systemPropertiesGetBoolean( + "ro.arm64.memtag.bootctl_device_policy_manager", + mInjector.systemPropertiesGetBoolean( + "ro.arm64.memtag.bootctl_settings_toggle", false))) { + throw new UnsupportedOperationException("device does not support MTE"); + } + } + + @Override public int getMtePolicy(String callerPackageName) { final CallerIdentity caller = getCallerIdentity(callerPackageName); if (Flags.setMtePolicyCoexistence()) { |