特权应用是位于系统映像某个分区上 priv-app
目录下的系统应用。在各 Android 版本中,相应分区为:
- Android 9 及更高版本:
/system, /product, /vendor
- Android 8.1 及更低版本:
/system
过去,设备制造商几乎无法控制可对特权应用授予哪些签名|特许权限。从 Android 8.0 开始,制造商可以在 /etc/permissions
目录下的系统配置 XML 文件中明确授予特许权限。从 Android 9 开始,实现人员可以明确授予或拒绝授予所有特许权限。如果未被授予特许权限,设备将无法启动。
privapp-permissions.xml
文件只有在与特权应用位于同一分区时才能授予或拒绝授予该应用权限。例如,如果 /product
分区上的应用请求特许权限,则只能由 /product
上的 privapp-permissions.xml
文件来同意或拒绝该请求。
添加许可名单
应用的权限许可名单可列在位于 frameworks/base/etc/permissions
目录下的单个或多个 XML 文件中:
/etc/permissions/privapp-permissions-OEM_NAME.xml
/etc/permissions/privapp-permissions-DEVICE_NAME.xml
对于内容的组织方式,没有严格的规则。设备实现人员可以决定内容结构,只要 /system/priv-app
下的所有应用均列入许可名单即可。例如,Google 针对所有特权应用制定了一个许可名单。我们建议使用以下组织方式:
- 已包含在 Android 开源项目 (AOSP) 树中的应用的权限列在
/etc/permissions/privapp-permissions-platform.xml
中。 - 对于其他应用,请使用以下格式的文件:
/etc/permissions/privapp-permissions-DEVICE_NAME.xml
。
自定义许可名单
AOSP 包含可根据需要自定义的许可名单实现。
如果必须拒绝权限,请将 XML 修改为使用 deny-permission
标记,而不是 permission
标记。例如:
<!-- 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> ...
查找缺少的权限
如需在启动新设备时查找缺少的权限,请启用过渡日志模式:
ro.control_privapp_permissions=log
违规行为会在日志文件中报告。授予非特许权限。这样做可确保设备保持工作状态,同时仍然提供违规行为列表。错误消息格式如下:
PackageManager: Privileged permission {PERMISSION_NAME} for package {PACKAGE_NAME} - not in privapp-permissions allowlist
必须将缺少的权限加入相应的许可名单来解决所有违规行为。 请注意:
- 在 Android 9 及更高版本中,特许权限的违规行为会导致设备无法启动。您必须明确允许或拒绝所有特许权限。
- 在 Android 8.0 及更低版本中,即使应用位于
priv-app
路径中,也不会向受影响的应用授予缺少的权限。
强制执行许可名单
创建许可名单后,可设置 build 属性 ro.control_privapp_permissions=enforce
使其在运行时强制执行。
只有使用 package="android"
的应用声明的权限才需要列入许可名单。ro.control_privapp_permissions
属性状态必须遵循兼容性定义文档 (CDD) 中的第 9.1 节“权限”。