特许权限白名单

特权应用是位于其中一个系统映像分区上的 priv-app 目录下的系统应用。用于 Android 版本的分区有:

  • Android 8.0 及更低版本 - /system
  • Android 9 及更高版本 - /system, /product, /vendor
  • Android 10 及更高版本 - /system, /product, /vendor, /product-services

在整个页面中,/etc/permissions/priv-app 解析为 partition/etc/permissions/priv-app

过去,设备制造商几乎无法控制可以向特权应用授予哪些签名|特许权限。从 Android 8.0 开始,制造商必须在 /etc/permissions 目录下的系统配置 XML 文件中明确授予特许权限。从 Android 9 开始,实现人员必须明确授予或拒绝所有特许权限,否则设备将无法启动。

privapp-permissions.xml 文件只能为同一分区上的特权应用授予或拒绝权限。例如,如果 /vendor 分区上的应用请求特许权限,则该请求权限只能由同样位于 /vendor 上的 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 针对由 Google 开发的所有特权应用提供了一个白名单,建议使用以下组织方式:

  • 对于已包含在 Android 开源项目 (AOSP) 树中的应用,请将其权限列在 /etc/permissions/privapp-permissions-platform.xml 中。
  • 对于 Google 应用,请将其权限列在 /etc/permissions/privapp-permissions-google.xml 中。
  • 对于其他应用,请使用以下格式的文件: /etc/permissions/privapp-permissions-DEVICE_NAME.xml

生成白名单

要针对系统映像上提供的所有应用自动生成白名单,请使用位于以下位置的 AOSP 命令行工具: development/tools/privapp_permissions/privapp_permissions.py。要生成特定于设备的 privapp-permissions.xml 的初始版本,请执行以下操作:

  1. 编译系统映像:
        . build/envsetup.sh
        lunch PRODUCT_NAME
        make -j
  2. 运行 privapp_permissions.py 脚本以生成一个 privapp-permissions.xml 文件,该文件会列出需要列入白名单的所有签名|特许权限:
    development/tools/privapp_permissions/privapp_permissions.py
    此工具会输出可在 /etc/permissions 目录路径下作为单个文件或拆分为多个文件的 XML 内容。如果设备已在 /etc/permissions 目录下包含白名单,则该工具将仅输出差异内容(也就是说,只输出缺少的将列入白名单的签名|特许权限)。这对审核也很有用,当添加新版本的应用时,该工具会检测所需的其他权限。
  3. 将生成的文件复制到相应的 /etc/permissions 目录下,系统将在启动过程中从这里读取这些文件。

自定义白名单

AOSP 包含可视需要自定义的白名单实现。 对于包含在 AOSP 中的应用,其权限已在 /etc/permissions/privapp-permissions-platform.xml 中列入白名单。

默认情况下,privapp_permissions.py 脚本生成的输出会自动授予特权应用所请求的任何权限。如果有应被拒绝的权限,请修改 XML 以使用“拒绝权限”标记而非“权限”标记。示例:

<!--
    This XML file declares which signature|privileged permissions should be
    granted 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 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 whitelist

所有违规行为均必须通过将缺少的权限加入相应的白名单来予以解决。

  • 在 Android 8.0 及更低版本中,受影响的应用即使位于 priv-app 路径中也不会被授予缺少的权限。
  • 在 Android 9 及更高版本中,违反(特许权限)意味着设备无法启动您必须明确允许或拒绝所有特许权限。

强制执行白名单

白名单列好后,可通过设置版本属性 ro.control_privapp_permissions=enforce 来启用运行时强制执行。