does not have a SELinux domain defined. android 开机启动
实践:
1、
msm8909:/sbin # ls -Z
ls -Z
u:object_r:rootfs:s0 adbd u:object_r:rootfs:s0 ueventd
u:object_r:rootfs:s0 healthd u:object_r:rootfs:s0 watchdogd
u:object_r:rootfs:s0 target-android
msm8909:/sbin # ls -lZ
ls -lZ
total 39024
-rwxr-x--- 1 root root u:object_r:rootfs:s0 712728 1970-01-01 08:00 adbd
-rwxr-x--- 1 root root u:object_r:rootfs:s0 532072 1970-01-01 08:00 healthd
-rwxr-x--- 1 root root u:object_r:rootfs:s0 18728134 1970-01-01 08:00 mytest
lrwxrwxrwx 1 root root u:object_r:rootfs:s0 7 1970-01-01 08:00 ueventd -> ../init
lrwxrwxrwx 1 root root u:object_r:rootfs:s0 7 1970-01-01 08:00 watchdogd -> ../init
msm8909:/sbin #
问题:
dmesg
[ 46.089306] init: Service mysvc2 does not have a SELinux domain defined.
service mysvc1 /system/vendor/bin/app1
class main
user root
group root system readproc
disabled
writepid /dev/cpuset/foreground/tasks
service mysvc2 /system/bin/app2
class main
user root
group root system readproc
disabled
writepid /dev/cpuset/foreground/tasks
on property:sys.boot_completed=1
start mysvc1
start mysvc2
实现 SELinux | Android 开源项目 | Android Open Source Project https://source.android.google.cn/docs/security/selinux/implement?hl=zh-cn#use_cases
实现 SELinux
SELinux 被设置为“默认拒绝”模式,这表示,对于在内核中存在钩子的每一次访问,都必须获得政策的明确许可。这意味着政策文件中包含规则、类型、类、权限等方面的大量信息。关于 SELinux 的完整注意事项不在本文档的讨论范围之内,现在您必须要了解的是在启动新的 Android 设备时如何编写政策规则。目前有大量关于 SELinux 的信息可供您参考。关于建议的资源,请参阅支持文档。
关键文件
如需启用 SELinux,请集成最新的 Android 内核,然后整合 system/sepolicy 目录中的文件。这些文件在编译后会包含 SELinux 内核安全政策,并涵盖上游 Android 操作系统。
通常情况下,您不能直接修改 system/sepolicy
文件,但您可以添加或修改自己的设备专用政策文件(位于 /device/manufacturer/device-name/sepolicy
目录中)。在 Android 8.0 及更高版本中,您对这些文件所做的更改只会影响供应商目录中的政策。如需详细了解 Android 8.0 及更高版本中的公共 sepolicy 分离,请参阅在 Android 8.0 及更高版本中自定义 SEPolicy。无论是哪个 Android 版本,您都仍需要修改以下文件:
政策文件
以 *.te
结尾的文件是 SELinux 政策源代码文件,用于定义域及其标签。您可能需要在 /device/manufacturer/device-name/sepolicy
中创建新的政策文件,但您应尽可能尝试更新现有文件。
上下文的描述文件
您可以在上下文的描述文件中为您的对象指定标签。
file_contexts
用于为文件分配标签,并且可供多种用户空间组件使用。在创建新政策时,请创建或更新该文件,以便为文件分配新标签。如需应用新的file_contexts
,请重新构建文件系统映像,或对要重新添加标签的文件运行restorecon
。在升级时,对file_contexts
所做的更改会在升级过程中自动应用于系统和用户数据分区。此外,您还可以通过以下方式使这些更改在升级过程中自动应用于其他分区:在以允许读写的方式装载相应分区后,将restorecon_recursive
调用添加到 init.board.rc 文件中。genfs_contexts
用于为不支持扩展属性的文件系统(例如,proc
或vfat
)分配标签。此配置会作为内核政策的一部分进行加载,但更改可能对内核 inode 无效。要全面应用更改,您需要重新启动设备,或卸载并重新装载文件系统。 此外,通过使用context=mount
选项,您还可以为装载的特定系统文件(例如vfat
)分配特定标签。property_contexts
用于为 Android 系统属性分配标签,以便控制哪些进程可以设置这些属性。在启动期间,init
进程会读取此配置。service_contexts
用于为 Android binder 服务分配标签,以便控制哪些进程可以为相应服务添加(注册)和查找(查询)binder 引用。在启动期间,servicemanager
进程会读取此配置。seapp_contexts
用于为应用进程和/data/data
目录分配标签。在每次应用启动时,zygote
进程都会读取此配置;在启动期间,installd
会读取此配置。mac_permissions.xml
用于根据应用签名和应用软件包名称(后者可选)为应用分配seinfo
标记。随后,分配的seinfo
标记可在seapp_contexts
文件中用作密钥,以便为带有该seinfo
标记的所有应用分配特定标签。在启动期间,system_server
会读取此配置。keystore2_key_contexts
用于为密钥库 2.0 命名空间分配标签。 这些命名空间由 keystore2 守护程序强制执行。密钥库始终都提供基于 UID/AID 的命名空间。密钥库 2.0 还会强制执行 sepolicy 定义的命名空间。如需详细了解此文件的格式和规范,请点击此处。
BoardConfig.mk makefile
修改或添加政策文件和上下文的描述文件后,请更新您的 /device/manufacturer/device-name/BoardConfig.mk
makefile 以引用 sepolicy
子目录和每个新的政策文件。 如需详细了解 BOARD_SEPOLICY
变量,请参阅 system/sepolicy/README
文件。
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
重新进行构建后,您的设备会启用 SELinux。现在,您可以根据您向 Android 操作系统添加的内容自定义 SELinux 政策(如自定义中所述),也可以验证现有设置(如验证中所述)。
在新政策文件和 BoardConfig.mk 更新部署到位后,新政策设置会自动内置到最终的内核政策文件中。如需详细了解如何在设备上构建 sepolicy,请参阅构建 sepolicy。
实现
注意:AOSP 不再提供 audit2allow,请使用主机中的版本(Debian 和 Ubuntu 上的软件包“policycoreutils-python-utils”)。如需开始使用 SELinux,请执行以下操作:
- 在内核中启用 SELinux:
CONFIG_SECURITY_SELINUX=y
- 更改 kernel_cmdline 或 bootconfig 参数,以便:
BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
或BOARD_BOOTCONFIG := androidboot.selinux=permissive
这仅适用于初始制定设备政策的情况。在拥有初始引导程序政策后,请移除此参数,以便将设备恢复强制模式,否则设备将无法通过 CTS 验证。 - 以宽容模式启动系统,看看在启动时会遇到哪些拒绝事件:
在 Ubuntu 14.04 或更高版本中,请运行以下命令:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
在 Ubuntu 12.04 中,请运行以下命令:adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- 评估警告输出,此类警告类似于
init: Warning! Service name needs a SELinux domain defined; please fix!
。如需查看相关说明和工具,请参阅验证。 - 标识设备以及需要添加标签的其他新文件。
- 为您的对象使用现有标签或新标签。查看
*_contexts
文件,了解之前是如何为内容添加标签的,然后根据对标签含义的了解分配一个新标签。这个标签最好是能够融入到政策中的现有标签,但有时也需要使用新标签,而且还需要提供关于访问该标签的规则。将您的标签添加到相应的上下文的描述文件中。 - 标识应该拥有自己的安全域的域/进程。您可能需要为每一项分别编写一个全新的政策。例如,从
init
衍生的所有服务都应该有自己的安全域。以下命令有助于查看保持运行的服务(不过所有服务都需要如此处理):
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
- 查看
init.device.rc
以发现没有域类型的域。请在开发过程早期为其提供相应的域,以避免向init
添加规则或将init
访问权限与其自身政策中的访问权限混淆。 - 设置
BOARD_CONFIG.mk
以使用BOARD_SEPOLICY_*
变量。如需详细了解如何进行此项设置,请参阅system/sepolicy
中的 README。 - 检查 init.device.rc 和 fstab.device 文件,确保每一次使用
mount
都对应一个添加了适当标签的文件系统,或者指定了context= mount
选项。 - 查看每个拒绝事件,并创建 SELinux 政策以妥善处理每个拒绝事件。请参阅自定义中的示例。
建议从 AOSP 中的政策入手,然后在这些政策的基础上创建自己的自定义政策。如需详细了解政策策略以及其中一些步骤,请参阅编写 SELinux 政策。
用例
下面列举了一些在开发软件以及制定关联的 SELinux 政策时需要注意的具体漏洞:
符号链接 - 由于符号链接以文件形式显示,因此系统通常将其作为文件进行读取,而这可能会导致漏洞。例如,某些特权组件(例如 init
)会更改某些文件的权限,有时会使之极度开放。
这样一来,攻击者便可以将这些文件替换成指向其控制的代码的符号链接,从而重写任意文件。但如果您知道自己的应用绝不会遍历符号链接,则可以通过 SELinux 来禁止您的应用遍历符号链接。
系统文件 - 以应该只有系统服务器可以修改的一系列系统文件为例。由于 netd
、init
和 vold
是以 root 身份运行的,因此它们也可以访问这些系统文件。这样一来,如果 netd
遭到入侵,这些文件乃至系统服务器本身都可能遭到入侵。
借助 SELinux,您可以将这些文件标识为系统服务器数据文件。这样一来,系统服务器就是唯一对这些文件具有读写权限的域。即使 netd
遭到入侵,它也无法将域切换到系统服务器域并访问这些系统文件,就算它是以 root 身份运行的也是如此。
应用数据 - 另一个示例是必须以 root 身份运行但不应获得应用数据访问权限的一系列函数。这一项非常有用,因为它可以做出广泛的声明,例如禁止与应用数据无关的特定域访问互联网。
setattr - 对于 chmod
和 chown
等命令,您可以标识关联域可以在哪些文件中进行 setattr
操作。这样一来,便可以禁止对这些文件之外的任何文件进行这类更改,即使以 root 身份进行也不例外。因此,应用可以对带 app_data_files
标签的文件运行 chmod
和 chown
,但不能对带 shell_data_files
或 system_data_files
标签的文件运行这些命令。
Android 中的安全增强型 Linux | Android 开源项目 | Android Open Source Project https://source.android.google.cn/docs/security/features/selinux?hl=zh-cn
SELinux 概念 | Android 开源项目 | Android Open Source Project https://source.android.google.cn/docs/security/selinux/concepts?hl=zh_cn
SELinux 概念
请查看此页中的内容,熟悉 SELinux 概念。
强制访问控制
安全增强型 Linux (SELinux) 是适用于 Linux 操作系统的强制访问控制 (MAC) 系统。作为 MAC 系统,它与 Linux 中用户非常熟悉的自主访问控制 (DAC) 系统不同。在 DAC 系统中,存在所有权的概念,即特定资源的所有者可以控制与该资源关联的访问权限。这种系统通常比较粗放,并且容易出现无意中提权的问题。MAC 系统则会在每次收到访问请求时都先咨询核心机构,再做出决定。
SELinux 已作为 Linux 安全模块 (LSM) 框架的一部分实现,该框架可识别各种内核对象以及对这些对象执行的敏感操作。其中每项操作要执行时,系统都会调用 LSM 钩子函数,以便根据不透明安全对象中存储的关于相应操作的信息来确定是否应允许执行相应操作。SELinux 针对这些钩子以及这些安全对象的管理提供了相应的实现,该实现可结合自己的政策来决定是否允许相应访问。
通过结合使用其他 Android 安全措施,Android 的访问权限控制政策能够大大降低遭到入侵的计算机和帐号可能蒙受的损失。Android 的自主访问控制和强制访问控制等工具可为您提供一种结构,确保您的软件仅以最低权限级别运行。这样可降低攻击造成的影响,并降低错误进程重写数据甚至是传输数据的可能性。
在 Android 4.3 及更高版本中,SELinux 开始为传统的自主访问控制 (DAC) 环境提供强制访问控制 (MAC) 保护功能。例如,软件通常情况下必须以 root 用户帐号的身份运行,才能向原始块设备写入数据。在基于 DAC 的传统 Linux 环境中,如果 root 用户遭到入侵,攻击者便可以利用该用户身份向每个原始块设备写入数据。不过,可以使用 SELinux 为这些设备添加标签,以便被分配了 root 权限的进程可以只向相关政策中指定的设备写入数据。这样一来,该进程便无法重写特定原始块设备之外的数据和系统设置。
如需更多安全威胁示例以及使用 SELinux 解决安全威胁的方法,请参阅用例。
强制执行级别
SELinux 可以在各种模式下实现:
- 宽容模式 - 仅记录但不强制执行 SELinux 安全政策。
- 强制模式 - 强制执行并记录安全政策。如果失败,则显示为 EPERM 错误。
在选择强制执行级别时只能二择其一,您的选择将决定您的政策是采取操作,还是仅允许您收集潜在的失败事件。宽容模式在实现过程中尤其有用。
类型、属性和规则
Android 依靠 SELinux 的类型强制执行 (TE) 组件来实施其政策。这表示所有对象(例如文件、进程或套接字)都具有相关联的类型。例如,默认情况下,应用的类型为 untrusted_app
。对于进程而言,其类型也称为域。可以使用一个或多个属性为类型添加注解。属性可用于同时指代多种类型。
对象会映射到类(例如文件、目录、符号链接、套接字),并且每个类的不同访问权限类型由权限表示。 例如,file
类存在权限 open
。虽然类型和属性作为 Android SELinux 政策的一部分会进行定期更新,但权限和类是静态定义的,并且作为新 Linux 版本的一部分也很少进行更新。
政策规则采用以下格式:allow source target:class permissions;
,其中:
- source - 规则主题的类型(或属性)。谁正在请求访问权限?
- 目标 - 对象的类型(或属性)。对哪些内容提出了访问权限请求?
- 类 - 要访问的对象(例如,文件、套接字)的类型。
- 权限 - 要执行的操作(或一组操作,例如读取、写入)。
规则的一个示例如下:
allow untrusted_app app_data_file:file { read write };
这表示应用可以读取和写入带有 app_data_file
标签的文件。还有其他应用类型。例如,isolated_app
用于清单中含有 isolatedProcess=true
的应用服务。Android 对涵盖应用的所有类型使用名为 appdomain
的属性,而不是对这两种类型重复同一规则:
# Associate the attribute appdomain with the type untrusted_app. typeattribute untrusted_app, appdomain; # Associate the attribute appdomain with the type isolated_app. typeattribute isolated_app, appdomain; allow appdomain app_data_file:file { read write };
当编写的规则指定了某个属性名称时,该名称会自动扩展为列出与该属性关联的所有域或类型。一些重要属性包括:
domain
- 与所有进程类型相关联的属性file_type
- 与所有文件类型相关联的属性。
宏
特别是对于文件访问权限,有很多种权限需要考虑。例如,read
权限不足以打开相应文件或对其调用 stat
。为了简化规则定义,Android 提供了一组宏来处理最常见的情况。例如,若要添加 open
等缺少的权限,可以将上述规则改写为:
allow appdomain app_data_file:file rw_file_perms;
如需查看实用宏的更多示例,请参阅 global_macros
和 te_macros
文件。请尽可能使用宏,以降低因相关权限被拒而导致失败的可能性。
定义类型后,需要将其与所代表的文件或进程相关联。如需详细了解如何实现这种关联,请参阅实现 SELinux。如需详细了解规则,请参阅 SELinux Notebook。
安全上下文和类别
调试 SELinux 政策或为文件添加标签时(通过 file_contexts
或运行 ls -Z
),您可能会遇到安全上下文(也称为标签)。例如 u:r:untrusted_app:s0:c15,c256,c513,c768
。安全上下文的格式为:user:role:type:sensitivity[:categories]
。您通常可以忽略上下文的 user
、role
和 sensitivity
字段(请参阅明确性)。上一部分介绍了 type
字段。categories
是 SELinux 中多级安全 (MLS) 支持的一部分。从 Android S 开始,类别被用于:
- 分隔应用数据,使其不被其他应用访问。
- 分隔不同实际用户的应用数据。
明确性
Android 并不会使用 SELinux 提供的所有功能。阅读外部文档时,请记住以下几点: