当前位置:   article > 正文

Android系统SELinux详解

selinux

前言

SELinux是一种加强文件安全的一种策略,可以更好地保护我们的Android系统, 比如限制系统服务的访问权限、控制应用对数据和系统日志的访问等措施,这样就降低了恶意软件的影响,并且可以防止因代码存在的缺陷而产生的对系统安全的影响。

从系统安全方面考虑,SELinux是保护神,但是从软件开发方面,SELinux就是一道牵绊,这是一把双刃剑。SELinux默认开启,即使获得了该系统的root权限,也只能向相关策略中指定的设备写入数据,从而更好地保护和限制系统服务,保障系统和数据的安全。

环境

硬件平台:Google Pixel2
操作系统:Android10.0

selinux有两种工作模式

名称作用
permissive所有操作都被允许(即没有MAC),但是如果有违反权限的话,会记录日志
enforcing所有操作都会进行权限检查

标签、规则和域

SELinux 依靠标签来匹配操作和策略。标签用于决定允许的事项。套接字、文件和进程在 SELinux 中都有标签。SELinux 在做决定时需参照两点:一是为这些对象分配的标签,二是定义这些对象如何交互的策略。

在 SELinux 中,标签采用以下形式:user:role:type:mls_level,其中 type 是访问决定的主要组成部分,可通过构成标签的其他组成部分进行修改。对象会映射到类,对每个类的不同访问类型由权限表示。

策略规则采用以下形式:allow domains types:classes permissions;,其中:

名称作用
domain一个进程或一组进程的标签。也称为域类型,因为它只是指进程的类型。
type一个对象(例如,文件、套接字)或一组对象的标签。
class要访问的对象(例如,文件、套接字)的类型。Permission - 要执行的操作(例如,读取、写入)。

策略配置源文件

  1. external/sepolicy
    这是独立于设备的配置,一般不能针对设备进行修改
  2. device///sepolicy
    这是特定于设备的配置,基于 BOARD_SEPOLICY_* 变量来选择对应平台的策略配置。

Type Enforcement (TE) 配置文件

.te 文件中保存了对应对象的域和类型定义、规则。通常每个域一个 .te 文件,例如installd.te。在 device.te、file.te 中声明了设备和文件类型。在某些文件(例如domain.te、app.te)中则存储着共享规则。

标签配置文件

  1. file_contexts:文件安全上下文
  2. property_contexts:属性安全上下文
SEAndroid app分类

SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):

名称作用
untrusted_app第三方app,没有Android平台签名,没有system权限
platform_app有android平台签名,没有system权限
system_app有android平台签名和system权限

从上面划分,权限等级,理论上:untrusted_app < platform_app < system_app

user

user可以理解为UID。android的UID和linux的UID根本是两回事,Linux的UID是用于针对多用户操作系统中用于区分用户的,而Android中的UID是用于系统进行权限管理的。参考链接中的文章对于uid的产生讲的很清楚。

seinfo

不同签名会创建对应的selinux上下文。
Android.mk
LOCAL_CERTIFICATE := platform
有platform签名,所以seinfo是platform。

自定义安全策略

以上面两个运行的app来说,我们为这两个APP添加额外的权限,对应的TE配置文件分别就是system_app.te、untrusted_app.te,对应路径为:

$aosp/system/sepolicy/public/system_app.te
$aosp/system/sepolicy/public/untrusted_app.te

  • 1
  • 2
  • 3

以longzhiye.example.app为例,我们为其添加can设备的执行权限:

longzhiye@longzhiye-laptop:~/mount/project/androidq$ vi system/sepolicy/public/system_app.te

  • 1
  • 2
......
allow system_app vendor_shell_exec:file { getattr open read execute execute_no_trans };
allow system_app shell_exec:file { getattr open read execute execute_no_trans };
allow system_app shell:file { getattr open read execute execute_no_trans };
......

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

以策略规则配置形式(allow domains types:classes permissions)

分析:

策略规则示例
domainssystem_app
typesvendor_shell_exec
classesfile
permissionsgetattr open read execute execute_no_trans

neverallow failures

有时我们增加的权限,系统默认的配置是不允许的,比如我们上面给forlinx.example.app增加的执行脚本的权限,报错如下:

libsepol.report_failure: neverallow on line 9 of system/sepolicy/private/system_app.te

(or line 41463 of policy.conf) violated by allow system_app shell:file { read open };

libsepol.report_failure: neverallow on line 22 of system/sepolicy/private/shell.te

(or line 40025 of policy.conf) violated by allow system_app shell:file { read open };

libsepol.check_assertions: 2 neverallow failures occurred

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

系统默认的安全策略的路径为system/sepolicy/,根据报错的提示,我们可以修改默认的配置,修改system/sepolicy/private/system_app.te和system/sepolicy/private/shell.te,从而完成权限的赋予。

安卓中快速编译sepolicy并验证(需要本地代码整编过一次,已经生成out目录)

$ mmm system/sepolicy/
$ adb push out/target/product/xxx/system/etc/selinux /system/etc/selinux
$ adb push out/target/product/xxx/vendor/etc/selinux /vendor/etc/selinux

  • 1
  • 2
  • 3
  • 4

也可单编systemimage,并刷机

$ make systemimage
$ adb reboot bootloader
$ fastboot flash system ./system.img
$ fastboot reboot

  • 1
  • 2
  • 3
  • 4
  • 5

如何应对neverallow? 绕过CTS认证

在system/sepolicy/private/logpersist.te与system/sepolicy/prebuilts/api/29.0/private/logpersist.te中配置以下allow语句并编译,
会报neverallow的错。如下声明allow:
allow logpersist system_data_file:dir write;
这表示谷歌不允许我们使用allow语句,解除限制的最暴力方法就是将报错处的neverallow语句删掉,这样确实可行,但是会过不了cts。
由于我们要访问的目录path为/data/syslog,将该目录定义成自己的Type,可以自定义Type,如下:
在file.te中自定义一个type为file_type,data_file_type,core_data_file_type:

  1. type log_data_file, file_type, data_file_type, core_data_file_type;
    在file_contexts中定义安全上下文:
  2. /data/syslog(/.*)? u:object_r:log_data_file:s0
    在logpersist.te将allow语句改为:
  3. allow logpersist log_data_file write;
    然后在logpersist.te中单独将自定义的log_data_file减去即可。(这里最好的是自定义一个service代替logpersist,那就要新建一个te文件了,比较麻烦)
neverallow logpersist {
  file_type
  userdebug_or_eng(`-misc_logd_file -coredump_file')
  with_native_coverage(`-method_trace_data_file')
  -log_data_file
}:file { create write append };

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

如何新增domian域?(一般在平台相关目录下添加)

例子如下
在device/平台名/system/private/file_contexts 文件添加

# tcontext=u:object_r:sysfs:s0

  • 1
  • 2

/sys/kernel/display/abcd u:object_r:wxl_abcd:s0 #wxl_abcd替换sysfs,wxl_abcd随便取

在device/平台名/system/public/file.te 中添加

type wxl_cabc, fs_type,sysfs_type;

  • 1
  • 2

在 device/平台名/system/private/system_server.te 文件中添加

allow system_server wxl_abcd:file { r_file_perms w_file_perms rw_file_perms };

  • 1
  • 2

添加 write 或者 read 的权限要注意 open 的权限,最后使用 r_file_perms、w_file_perms、rw_file_perms。

添加设备文件节点权限(sysfs gpio管脚节点权限)?

/sys/class/leds/green/brightness //快捷方式
/sys/devices/soc.0/gpio-leds.66/leds/green/brightness //实际节点

操作LED灯的设备文件节点为APP层system app进程开放该节点访问权限(读或写),权限配置主要修改(一般在/device/平台/sepolicy/common)目录下的file.te、file_contexts和system_app.te三个文件
(1)file.te修改如下:
# GPIO accessed by system app

    type sysfs_gpio, fs_type, sysfs_type;

  • 1
  • 2

(2)file_contexts修改如下:

    /sys/devices/soc/1010000.pinctrl/gpio/gpio62/value           u:object_r:sysfs_gpio:s0
    /sys/devices/soc/1010000.pinctrl/gpio/gpio63/value           u:object_r:sysfs_gpio:s0

  • 1
  • 2
  • 3

(3)system_app.te修改如下:

    allow system_app sysfs_gpio:file rw_file_perms;

  • 1
  • 2

如果通过以上添加SELinux之后,仍没有权限读写sys或proc节点,需要到/system/core/rootdir/init.rc里面配置如下:
(1)修改设备节点用户所有者和所属用户组,以及它们所对应的权限
chown system system 设备文件结点
chmod 777 设备文件结点

修改selinux没有生效???

将SELinux Policy 文件存放在下面目录
(1) Google 原生目录 /system/sepolicy
(2) 厂商配置目录 /device/厂商平台/sepolicy/
android将SELinux Policy 文件存放的te一般都是在device/平台/sepolicy 和 /system/sepolicy两个目录下

最后

如果想要成为架构师或想突破20~30K薪资范畴,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。

如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。
img
相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。

欢迎大家一键三连支持,若需要文中资料,直接扫描文末CSDN官方认证微信卡片免费领取↓↓↓(文末还有ChatGPT机器人小福利哦,大家千万不要错过)

PS:群里还设有ChatGPT机器人,可以解答大家在工作上或者是技术上的问题

图片

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/961941
推荐阅读
相关标签
  

闽ICP备14008679号