[Linux] SEAndroid基础学习

概述

SEAndroid是在Android 4.3版本中开始引入的基于SELinux的系统安全机制。

关于SELinux的一些基础已经在SELinux基础中总结了。
在平时工作中,遇到SEAndroid最多的,就是一些权限问题,因此,本文的主要目标,是如何查看SELinux权限拒绝信息、如何修改添加权限。

1.SEAndroid相关文件

1.system/sepolicy目录

该目录是SEAndroid的核心,该目录中的文件在编译后会包含 SELinux 内核安全政策,并涵盖上游 Android 操作系统。
一般来说,不能直接修改system/sepolicy文件,而是添加或修改自己的设备专用政策文件,即在/device/xxx/xxx/sepolicy文件。

2.te文件

以.te结尾的文件是SEAndroid的政策文件,在文件位于/system/sepolicy中,用来定义域(domain)和标签.如在/system/sepolicy/public/init.te中:

# Create and mount on directories in /.
allow init rootfs:dir create_dir_perms;
allow init { rootfs cache_file cgroup storage_file system_data_file system_file vendor_file postinstall_mnt_dir }:dir mounton;
allow init cgroup_bpf:dir { create mounton };
...
# Init should not access sysfs node that are not explicitly labeled.
neverallow init sysfs:file { open read write };

allow语句和neverallow语句用来定义规则,具体含义参见在SELinux中的说明.

1.一般情况下,不能修改/system/sepolicy下的.te文件,而是在/device/xxx/xxx/sepolicy下进行修改或添加。

2.定义权限时,遵循最小权限原则,即缺什么权限,就添加什么权限。

3.上下文描述文件

该文件也位于/system/sepolicy中,上下文描述文件中可以给客体目标指定一个标签。上下文描述文件共有五个,其中使用最多的为file_contexts。如:

/(vendor|system/vendor)/bin/hw/android\.hardware\.ir@1\.0-service             u:object_r:hal_ir_default_exec:s0

一般情况下,不能修改/system/sepolicy下的file_contexts文件,而是在/device/xxx/xxx/sepolicy下进行修改或添加。

4.BoardConfig.mk文件

修改或添加政策文件和上下文的描述文件后,需要更新 /device/manufacturer/device-name/BoardConfig.mk文件,设置BOARD_SEPOLICY_DIRS,以引用sepolicy子目录和每个新的政策文件。
如:

/android9.0/device/xxx/xxx/xxx/BoardConfig.mk中:

BOARD_SEPOLICY_DIRS += device/xxx/xxx/common/sepolicy \
		       build/target/board/generic/sepolicy

2.SEAndroid权限拒绝信息分析

SELinux中,查看权限拒绝信息,就需要查看log中的avc信息,在SEAndroid也是如此。一般来说,SEAndorid中如果存在权限拒绝,那么在kernel.log中搜索avc关键字,会有如下格式信息:

[118.812005] c3 type=1400 audit(1325540997.019:195): avc: denied { setattr } for pid=1 comm="init" name="brightness" dev="sysfs" ino=24526 scontext=u:r:init:s0 tcontext=u:object_r:sysfs:s0 tclass=file permissive=0

以上avc信息中各个关键字含义如下:

  • audit:内核审计log的时间戳;
  • denied {xxx}:表示拒绝的操作;
  • pid:主体对象的进程pid;
  • comm:表示被否决的应用程序;
  • name:表示尝试操作的目标文件或目录的路径,即客体资源名称;
  • scontext:表示主体对象的安全上下文;
  • tcontext:表示客体(目标)对象的安全上下文;
  • tclass:客体(目标)对象的文件类型;
  • permissive=0:表示SElinux处于enforing模式。

因此,从avc log中看出,主体类型为init对客体类型为sysfsfile类型文件没有setattr权限。
还有一种方式就是进入adb shell直接查看kernal 中的avc log:

adb root
adb remount
adb shell
cat /proc/kmsg
<11>[ 3370.846310] c1     1 selinux: avc:  denied  { set } for property=persist.vendor.power.debug_d pid=14256 uid=1000 gid=1000 scontext=u:r:sprd_engineermode_app:s0:c512,c768 tcontext=u:object_r:vendor_power_prop:s0 tclass=property_service permissive=0
<11>[ 3370.846310] c1     1 
<11>[ 3370.846405] c1     1 init: Unable to set property 'persist.vendor.power.debug_d' to '1' from uid:1000 gid:1000 pid:14256: SELinux permission check failed

对于SELinux权限拒绝问题,可以有两种方式对其进行修改,第一种方式是配置相关权限,这也是优先选择的方式,于是我们可以在/device/xxx/…/sepolicy/init.te中配置权限:

allow init sysfs:file setattr;

这种方式如果编译不过,说明违反了Google原生的策略。

针对于该问题,一般采用第二种方式:修改安全上下文。

首先,通过ls -lZ查看对应节点的安全上下文:

这里写图片描述

图中第5列是安全上下文信息,由四部分组成,分别表示SELinux用户、SELinux角色、类型、安全级别,我们只关注类型,这里类型为sysfs.

从查看结果看,/sys/class/leds/下的文件其实是/sys/device/…/的连接文件,所以使用同样的方式再查看实际文件的安全上下文信息,并且修改时也需要修改原文件安全上下文。

然后,开始修改安全上下文,可以将sysfs修改为sysfs_leds,在/device/BOARD/common/sepolicy/file_context中,自定义安全上下文信息:
这里写图片描述

修改之后,编译烧录,我们直接查看对应节点连接的原文件:

[Linux] SEAndroid基础学习_第1张图片

说明修改生效了。

这里为何要将安全上下文类型由sysfs修改为sysfs_leds呢?
因为在Google原生init.te中,有如下定义:

332# init chmod/chown access to /sys files.
333allow init {
334  sysfs_android_usb
335  sysfs_devices_system_cpu
336  sysfs_ipv4
337  sysfs_leds
338  sysfs_lowmemorykiller
339  sysfs_power
340  sysfs_vibrator
341  sysfs_wake_lock
342}:file setattr;

3.实例总结

1.开机后电池无数据

搜索avc log信息:

E SELinux : avc:  denied  { find } for interface=android.hardware.health::IHealth pid=367 scontext=u:r:hal_power_default:s0 tcontext=u:object_r:hal_health_hwservice:s0 tclass=hwservice_manager permissive=0

在以上avc denied信息中,主体安全上下文类型为hal_power_default,客体安全上下文类型为hal_health_hwservice,客体文件类型为hwservice_manager,拒绝原因是hal_power_defaulthal_health_hwservice缺少find权限。

于是在/device/…/sepolicy/hal_power_default.te中:

allow hal_power_default hal_health_hwservice:hwservice_manager find;

如果不存在/device/…/sepolicy/hal_power_default.te文件,则新建该文件,并配置BoardConfig.mk的BOARD_SEPOLICY_DIRS变量中即可。

4.修改安全上下文还是配置权限?

优先配置权限,如果配置权限违反Google原生策略,则只能修改安全上下文。是否违反Google原生策略,根据修改后是否编译失败来判定。如果编译成功,则说明没有违反,反之。

参考资料

Android Open Source Project

你可能感兴趣的:(Android系统开发)