Android SELinux——调试工具audio2allow介绍(十三)
audit2allow 是一个强大的 SELinux 调试工具,用于帮助开发者和系统管理员分析 SELinux 拒绝事件,并生成相应的allow规则,以便调整SELinux策略。
一、工具介绍
audit2allow 工具可以获取 dmesg 拒绝事件并将其转换成相应的 SELinux 政策声明。因此,该工具有 助于大幅加快 SELinux 开发速度。 audit2allow 包含在 Android 源代码树中,会在您基于源代码构建 Android 时自动编译。
1、主要功能
- 分析拒绝日志:从系统日志中提取与音频相关的 SELinux 拒绝事件。
- 生成 allow 规则:基于拒绝事件,自动生成可能需要添加到 SELinux 策略中的 allow 规则。
- 简化调试过程:减少手动分析日志和编写策略的时间,提高解决SELinux相关问题的效率。
当应用程序因 SELinux 权限问题被拒绝执行某些操作时。开发者或管理员需要快速定位并解决相关的 SELinux 权限问题。
但需要注意在应用任何生成的 allow 规则之前,应仔细评估其安全影响。audit2allow 旨在简化调试过程,但最终的 SELinux 策略调整仍需结合具体的应用环境和安全要求来完成。
2、使用方法
- 收集日志:确保已开启 SELinux 审计日志记录,并收集含有拒绝事件的日志文件。
- 运行工具:将日志文件作为输入传递给 audit2allow 工具。
- 审查建议:查看工具输出的 allow 规则建议,并根据实际情况决定是否应用这些建议到 SELinux 策略中。
在使用 audio2allow 前,首先你要有 root 权限来安装此工具,熟悉 SELinux 的格式与 Log,并了解如何调试 SELinux。
二、实际操作
1、工具安装
audit2allow 相关命令通常来自于 policycoreutils-python-utils 这个 Debian 软件包。所以在在使用前需要先安装对应工具,命令如下:
sudo apt-get install policycoreutils-python-utils
这里使用的是 Ubuntu 18.04.6 LTS。
2、工具使用
在我们不了解 audit2allow 工具使用规则的情况下,先通过 audit2allow --help 命令来显示显示帮助信息。如下:
Usage: audit2allow [options]Options:--version show program's version number and exit-h, --help show this help message and exit-b, --boot audit messages since last boot conflicts with -i-a, --all read input from audit log - conflicts with -i-p POLICY, --policy=POLICYPolicy file to use for analysis-d, --dmesg read input from dmesg - conflicts with --all and--input-i INPUT, --input=INPUTread input from <input> - conflicts with -a-l, --lastreload read input only after the last reload-r, --requires generate require statements for rules-m MODULE, --module=MODULEset the module name - implies --requires-M MODULE_PACKAGE, --module-package=MODULE_PACKAGEgenerate a module package - conflicts with -o and -m-o OUTPUT, --output=OUTPUTappend output to <filename>, conflicts with -M-D, --dontaudit generate policy with dontaudit rules-R, --reference generate refpolicy style output-N, --noreference do not generate refpolicy style output-v, --verbose explain generated output-e, --explain fully explain generated output-t TYPE, --type=TYPE only process messages with a type that matches thisregex--perm-map=PERM_MAP file name of perm map--interface-info=INTERFACE_INFOfile name of interface information--debug leave generated modules for -M-w, --why Translates SELinux audit messages into a descriptionof why the access was denied
- 显示版本信息:audit2allow --version
- 从审计日志读取数据:audit2allow --all
- 从指定文件读取输入:audit2allow --input=my_input_file
- 生成模块包:audit2allow --module-package=my_module_package
- 将输出追加到文件:audit2allow --output=my_output_file
- 生成 require 语句:audit2allow --requires
- 设置模块名称:audit2allow --module=my_module_name
- 生成带有详细解释的输出:audit2allow --explain
- 处理特定类型的审计消息:audit2allow --type=my_regex_type
- 生成 refpolicy 样式的输出:audit2allow --reference
- 不生成 refpolicy 样式的输出:audit2allow --noreference
- 生成带有详细解释的输出:audit2allow --verbose
- 生成带有 dontaudit 规则的策略:audit2allow --dontaudit
- 解释为什么访问被拒绝:audit2allow --why
示例用法
假设你想从审计日志中读取所有数据并生成详细的解释输出:
audit2allow --all --explain
如果你需要生成一个模块包并设置模块名称:
audit2allow --module-package=my_module_package --module=my_module_name
如果你需要从特定输入文件读取数据并追加到输出文件:
audit2allow --input=my_input_file --output=my_output_file
3、自动生成策略
过滤日志
假如 Logcat 通过过滤的 avc 后内容如下:
08-17 11:12:40.109 1103 1103 W HwBinder:1103_2: type=1400 audit(0.0:41): avc: denied { read } for name="u:object_r:default_prop:s0" dev="tmpfs" ino=20871 scontext=u:r:mediacodec:s0 tcontext=u:object_r:default_prop:s0 tclass=file permissive=0
08-17 11:12:42.759 1069 1069 W Binder:1069_3: type=1400 audit(0.0:42): avc: denied { read } for name="u:object_r:vendor_media_sdm660_version_prop:s0" dev="tmpfs" ino=20979 scontext=u:r:mediaserver:s0 tcontext=u:object_r:vendor_media_sdm660_version_prop:s0 tclass=file permissive=0
08-17 11:13:41.679 3812 3812 I om.ubx.scandemo: type=1400 audit(0.0:47): avc: denied { write } for name="ScanDemo" dev="mmcblk0p14" ino=339 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:system_file:s0 tclass=dir permissive=1
08-17 11:13:42.639 3812 3812 I om.ubx.scandemo: type=1400 audit(0.0:48): avc: denied { read write } for name="i2c-7" dev="tmpfs" ino=21076 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:i2c_device:s0 tclass=chr_file permissive=1
08-17 11:13:42.639 3812 3812 I om.ubx.scandemo: type=1400 audit(0.0:50): avc: denied { ioctl } for path="/dev/i2c-7" dev="tmpfs" ino=21076 ioctlcmd=707 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:i2c_device:s0 tclass=chr_file permissive=1
08-17 11:13:43.169 1619 1619 I android.bg: type=1400 audit(0.0:51): avc: denied { write } for name="ScanDemo" dev="mmcblk0p14" ino=339 scontext=u:r:system_server:s0 tcontext=u:object_r:system_file:s0 tclass=dir permissive=1
08-17 11:13:51.809 3812 3812 I om.ubx.scandemo: type=1400 audit(0.0:52): avc: denied { ioctl } for path="/dev/i2c-7" dev="tmpfs" ino=21076 ioctlcmd=707 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:i2c_device:s0 tclass=chr_file permissive=1
08-17 11:13:51.989 3812 3812 I Thread-2: type=1400 audit(0.0:53): avc: denied { search } for name="leds" dev="sysfs" ino=26711 scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:sysfs_leds:s0 tclass=dir permissive=1
策略生成
audit2allow -i dmesg.log > avc.txt
输出结果如下所示:
#============= mediaserver ==============
allow mediaserver vendor_media_sdm660_version_prop:file read;#============= platform_app ==============
allow platform_app i2c_device:chr_file { read write ioctl };
allow platform_app sysfs_leds:dir search;
allow platform_app system_file:dir write;#============= system_server ==============
allow system_server system_file:dir write;
注意: 请务必仔细审核要添加到政策中的条目,以免出现权限过宽的情况。通 常情况下, audit2allow 给出的声明建议只是一个大致的基础。在添加这些声明后,您可能需要更改来源域和目标标签,并纳入适当的宏,才能实现良好的政策配置。有时,应对拒绝事件的合理 方式不是更改政策,而是更改违规的应用。
上面的方式是通过一直日志进行策略生成,如果没有拿到对应日志,可以直接使用下面命令:
adb pull /sys/fs/selinux/policy
adb logcat -b all -d | audit2allow -p policy
拉取 SELinux 策略文件: adb pull /sys/fs/selinux/policy
获取审计日志 | 生成策略:adb logcat -b all -d | audit2allow -p policy
audit2allow 在项目中的路径是 external/selinux/prebuilts/bin/audit2allow ,执行过 source build/envsetup 和 lunch 命令后,就可以直接在根目录使用 audit2allow 工具了。