Privileged apps are system apps located in a priv-app
directory on a
system image partition. The partitions used for Android releases are:
- Android 9 and higher:
/system, /product, /vendor
- Android 8.1 and lower:
/system
Historically, device manufacturers had little control over which
signature | privileged permissions could be granted to
privileged apps. Starting in Android 8.0, manufacturers can explicitly grant
privileged permissions in the system configuration XML files in the
/etc/permissions
directory. As of Android 9, implementors can
explicitly grant or deny all privileged permissions. If privileged permissions are not granted,
the device won't boot.
The privapp-permissions.xml
file can only grant or deny
permissions for privileged apps on the same partition. For example, if
an app on the /product
partition requests privileged permissions,
the request can only be granted or denied by a privapp-permissions.xml
file on /product
.
Add an allowlist
Permission allowlists for apps can be listed in a single XML file or in multiple
XML files located in the frameworks/base/etc/permissions
directory:
/etc/permissions/privapp-permissions-OEM_NAME.xml
/etc/permissions/privapp-permissions-DEVICE_NAME.xml
No strict rule applies to how content is organized. Device implementers can
determine content structure as long as all apps from /system/priv-app
are allowlisted. For example, Google has developed a single allowlist for all privileged apps.
We recommend the following organization:
- Permissions for apps already included in the
Android Open Source Project (AOSP)
tree are listed in
/etc/permissions/privapp-permissions-platform.xml
. - For other apps, use files of the form,
/etc/permissions/privapp-permissions-DEVICE_NAME.xml
.
Customize an allowlist
AOSP includes an allowlist implementation that can be customized as needed.
If a permission must be denied, edit the XML to use a deny-permission
tag
instead of a permission
tag. For example:
<!-- This XML file declares which signature|privileged permissions to grant to privileged apps that come with the platform --> <permissions> <privapp-permissions package="com.android.backupconfirm"> <permission name="android.permission.BACKUP"/> <permission name="android.permission.CRYPT_KEEPER"/> </privapp-permissions> <privapp-permissions package="com.android.cellbroadcastreceiver"> <!-- Don't allow the application to interact across users --> <deny-permission name="android.permission.INTERACT_ACROSS_USERS"/> <permission name="android.permission.MANAGE_USERS"/> <permission name="android.permission.MODIFY_PHONE_STATE"/> <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/> </privapp-permissions> ...
Find missing permissions
To find missing permissions when starting a new device, enable transitional log mode:
ro.control_privapp_permissions=log
Violations are reported in the log file. Non-privileged permissions are granted. Doing so ensures the device remains in a working state while still providing the list of violations. The error message format is as follows:
PackageManager: Privileged permission {PERMISSION_NAME} for package {PACKAGE_NAME} - not in privapp-permissions allowlist
All violations must be addressed by adding the missing permissions to the appropriate allowlists. Note that in:
- Android 9 and higher, violations of privileged permissions prevent the device from starting. Instead, you must explicitly allow or deny all privileged permissions.
- Android 8.0 and lower, missing permissions are not granted to the affected apps despite
being in the
priv-app
path.
Enforce an allowlist
After you create your allowlists, enable runtime enforcement by setting the build
property ro.control_privapp_permissions=enforce
.
Allowlisting is required only for permissions declared by apps with
package="android"
. The ro.control_privapp_permissions
property state must adhere to
Section 9.1 Permissions
in the Compatibility Definition Document (CDD).