Android selinux详解

文章目录

1、preface

jsx 复制代码
1、
1)认识selinux(NSA开发)
<https://blog.csdn.net/tkwxty/article/details/104538447>
2)如何处理selinux权限
<https://blog.csdn.net/qq_43804080/article/details/106496536>

2、缩略词
SELinux : Security-Enhanced Linux
LSM : Linux Security Module
MAC : Mandatory Access Control(强制访问控制-SELinux采用的策略)
DAC : Discretionary Access Control(自主访问控制-Linux采用的策略)
AVC : Access Vector Cache(访问向量缓存 - 指的是权限描述表)
TE :typer enforcement

3、SELinux策略
SELinux给每个进程(Subject)和资源(Object,如文件、端口)都打上一个"安全上下文"(Security Context),严格规定谁能访问什么
一句话,te文件 声明 谁(以进程为单位)对谁(资源,以文件、file_context为单位)有权限(write/read)

4、什么情况需要开?
一般不开,过认证会要求开

5、sepolicy影响运行还是编译?
影响运行,运行时校验

6、什么场景下需要使用Selinux
1)Android5之后支持selinux,如果selinux打开了,则需要配置;
2)新增设备节点(新增驱动)、新增属性、新增rc文件等等,均需要在对应的te文件声明;

7、selinux与root的关系
1)root可以关闭selinux
2)但是拥有root不可突破selinux的规则(没有selinux,root拥有最高权限-增删无阻碍)
3)selinux的处理单位是进程,te文件描述 进程拥有哪些权限(目录、文件读写权限);

2、selinux架构

1)LSM架构图
复制代码
1、LSM架构
┌─────────────────────────────────────────┐
│           Linux Security Module (LSM)   │
│              SELinux 挂载点              │
├─────────────────────────────────────────┤
│                                         │
│  系统调用入口                            │
│       │                                │
│       ▼                                │
│  ┌─────────┐    ┌─────────┐            │
│  │ open()  │───→│ LSM Hook│            │
│  │ read()  │    │ 检查点   │            │
│  │ write() │    │         │            │
│  │ exec()  │    │ selinux_inode_permission│
│  │ ioctl() │    │ selinux_file_permission │
│  │ mmap()  │    │ selinux_bprm_checking   │
│  │ bind()  │    │ selinux_socket_bind     │
│  └─────────┘    └────┬────┘            │
│                      │                  │
│                      ▼                  │
│              ┌─────────────┐            │
│              │  AVC (Access │            │
│              │   Vector Cache)│          │
│              │              │            │
│              │  缓存决策结果 │            │
│              │  加速重复检查 │            │
│              └──────┬──────┘            │
│                     │                   │
│                     ▼                   │
│              ┌─────────────┐            │
│              │  Security Server│        │
│              │              │           │
│              │  查询 Policy DB │         │
│              │  (sepolicy)   │           │
│              │              │            │
│              │  决定: 允许/拒绝 │          │
│              └─────────────┘            │
│                     │                   │
│                     ▼                   │
│              ┌─────────────┐            │
│              │  允许: 继续执行 │          │
│              │  拒绝: -EACCES │          │
│              │  记录: audit log │        │
│              └─────────────┘            │
│                                         │
└─────────────────────────────────────────┘

1、从源码和系统架构的角度来看,SELinux 并不是一个独立运行的软件,而是作为一个 Linux 安全模块(LSM, Linux Security Module) 直接编译进 Linux 内核中的

2、内核级拦截: 当用户空间的程序发起系统调用(如 open, read, execve)时,内核在执行实际操作前,会触发 LSM 框架中的 SELinux 钩子函数(Hooks)。
3、策略语言:SELinux 的策略是用一种专门的声明式语言编写的。这些 .te 文件会被编译成二进制格式(.pp 模块),在系统启动时解析成AVC
4、访问向量缓存(AVC): 为了提高性能,SELinux 不会每次都去遍历庞大的策略规则。它会将已经做出的"允许/拒绝"决策缓存起来,这就是 AVC。只有当缓存未命中时,才会去查询策略数据库。

5、总的来说与ftrace/eBPF(实际也是利用bpf机制)类似,在内核入口处增加钩子,根据AVC来判定是否合规
2)selinux工作模式
模式 说明 类比
Enforcing 强制模式:违反策略就拒绝,并记录日志 拦截并记录
Permissive 宽容模式:不阻止,只记录日志(用于调试) 打印并记录,不但会拦截
Disabled 完全关闭 SELinux 没有保安
3)selinux决策三要素
复制代码
┌─────────────────────────────────────────┐
│           SELinux 决策三要素              │
├─────────────────────────────────────────┤
│                                         │
│  ┌─────────┐   ┌─────────┐   ┌────────┐│
│  │  Subject │ + │  Object │ + │ Action ││
│  │  (主体)  │   │  (客体)  │   │ (动作) ││
│  │          │   │          │   │        ││
│  │ 进程     │   │ 文件/资源 │   │ 读/写/执行││
│  │ apache   │   │ /var/www │   │ read   ││
│  │ sshd     │   │ /etc/shadow│  │ write  ││
│  │ app      │   │ /dev/video0│  │ open   ││
│  └─────────┘   └─────────┘   └────────┘│
│       │             │            │        │
│       └─────────────┴────────────┘        │
│                     │                    │
│                     ▼                    │
│              ┌─────────────┐             │
│              │  SELinux Policy│            │
│              │  (安全策略)   │            │
│              │              │             │
│              │ allow httpd_t │             │
│              │       var_www_t:file read; ││
│              └─────────────┘             │
│                     │                    │
│                     ▼                    │
│              ┌─────────────┐             │
│              │   允许 / 拒绝  │            │
│              │   AVC (Audit) │            │
│              └─────────────┘             │
│                                         │
└─────────────────────────────────────────┘
4)Selinux标签机制
复制代码
1、标签格式user:role:type:level
┌─────────────────────────────────────────┐
│           SELinux 标签系统              │
├─────────────────────────────────────────┤
│                                         │
│  用户 (User)        u:r:t:s0:s0:c0      │
│  │                  │││ │  │  │          │
│  │                  │││ │  │  └─ 安全级别 │
│  │                  │││ │  └─ 类别       │
│  │                  │││ └─ 灵敏度        │
│  │                  ││└─ 类型 (最关键!) │
│  │                  │└─ 角色             │
│  │                  └─ 用户              │
│  │                                     │
│  │  示例: u:r:kernel_t:s0               │
│  │         u:r:init_t:s0                │
│  │         u:r:httpd_t:s0             │
│  │         u:r:unconfined_t:s0         │
│  │                                     │
│  ├─────────────────────────────────────┤
│  │                                     │
│  │  文件 (File)                        │
│  │  system_u:object_r:var_www_t:s0     │
│  │  system_u:object_r:shadow_t:s0      │
│  │  system_u:object_r:device_t:s0     │
│  │                                     │
│  │  类型匹配: httpd_t 进程  ←→ var_www_t 文件 │
│  │  才能访问!                           │
│  │                                     │
│  └─────────────────────────────────────┘
│                                         │
└─────────────────────────────────────────┘
5)策略规则(Policy - Tyle Enforcement)
jsx 复制代码
1、什么时候用到?-> 新增文件/进程服务
2、有几种te文件,例子
1)设备文件规则te
1、type hello_dev_t, dev_type; //type "", dev_type  >> 定义设备类型,一般在device.te中定义
2、/dev/hello u:object_r:hello_dev_t:s0 //定义设备权限,s0 为安全级别,一般在file_contexts.te中定义

2)进程规则te
核心语法:allow 主体 客体:类别 权限
1、allow factory hello_dev_t:chr_file { read write ioctl open }; //授权访问,factory 域中的进程对 hello_dev_t 类型的字符设备文件执行读写操作

3)
1.te文件(静态描述文件) -> 转化为AVC(运行时生成)

3、源码

复制代码
源码实现
1、/kernel/security/selinux
security/selinux/hooks.c  --LSM钩子函数实现
security/selinux/avc.c  --AVC缓存
security/selinux/ss/services.c  --安全服务器
security/selinux/ss/policydb.c  -- 策略数据库
security/selinux/netlabel.c -- 网络标签

2.系统调用open使用的SELinux hooks
/kernel/security/selinux/hooks.c
selinux_inode_permission(struct inode *inode, int mask)
--cred_sid(cred); //获取进程的安全上下文
/kernel/security/selinux/avc.c
--avc_has_perm_noaudit(); //查询安全服务器
--avc_audit_required(); //审计日志处理
--audit_inode_permission(); //返回结果 (允许/拒绝) 

3.security_compute_av() - Compute access vector decisions.
/kernel/security/selinux/ss/services.c
security_compute_av(struct selinux_state *state, ssid, tsid, orig_tclass, struct av_decision *avd, struct extended_perms *xperms)
--sidtab_search(sidtab, tsid);
--ebitmap_get_bit();
--context_struct_compute_av()
--map_decision();

4、调试

复制代码
1、selinux命令
setenforce 0 (临时禁用掉SELinux)
getenforce  (得到结果为Permissive)

2、系统上如何打开selinux? - 可以咨询对应方案的PL
/android/device/mediatek/m7332/common/scripts/tvapiservice
function_save_selinux()
{
     if [ -f /system/bin/getenforce ] && [ -f /system/bin/setenforce ]; then
         selinux=`getenforce`
         if [ x${selinux} == xEnforcing ]; then
             setenforce 0
         fi
     fi
}

3、selinux配置文件
1) etc
/system/etc/selinux/*
cat /system/etc/selinux/plat_file_contexts | grep audio

1) 审计日志
/var/log/audit/audit.log


4、查看报错
实时查看:dmesg -w | grep avc
查看dmesg缓存: cat /proc/kmsg | grep avc
通用的selinux排查思路
复制代码
一、
1. 确认是 SELinux 问题
   getenforce  →  如果是 Enforcing,可能是 SELinux
   setenforce 0  →  临时关闭,如果问题解决,确认是 SELinux

2. 查看拒绝日志
   dmesg | grep avc  →  找到 avc: denied 行

3. 分析日志
   scontext=谁? (进程类型)
   tcontext=什么? (目标类型)
   { 操作 } = 被拒绝的动作

4. 判断是否合理
   ├─ 合理需求 → 修改 .te 策略,添加 allow 规则
   ├─ 路径错误 → 用 restorecon 恢复正确标签
   └─ 恶意访问 → 保持拒绝,修复应用

5. 修改策略
   ├─ 临时: chcon 修改标签
   └─ 永久: 修改 .te 文件,重新编译 sepolicy

二、   
1、selinux报错及解决案例 - Permission denied
1)报错日志
avc: denied { read } for comm="Binder:264_2" name="wakeup8" dev="sysfs" ino=24935 scontext=u:r:system_suspend:s0 tcontext=u:object_r:sysfs_devices_mstar_ehci:s0 tclass=dir permissive=1

permissive=1 代表不拦截,只提示报错和记录日志

报错解析:
avc: denied { read }: 表示被拒绝的操作是"读取"。
comm="Binder:264_2": 表示发起操作的进程名为Binder:264_2。
name="wakeup8": 表示操作的对象是名为"wakeup8"的文件或目录。
dev="sysfs": 该对象位于sysfs文件系统中。
ino=24935: 对象的inode号。
scontext=u:r:system_suspend:s0: 发起操作的安全上下文是system_suspend(指的是 system_suspend.te)
tcontext=u:object_r:sysfs_devices_mstar_ehci:s0: 目标对象的安全上下文是sysfs_devices_mstar_ehci。
tclass=dir: 目标对象是一个目录。
permissive=1: 当前是在permissive模式下,所以只是记录而不真正拒绝。

解决:
# 在 system_suspend.te 或相应的 te 文件中添加
allow system_suspend sysfs_devices_mstar_ehci:dir read;
相关推荐
jzwalliser1 小时前
安卓手机玩转Manim动画制作
android·manim
zhangphil2 小时前
Android图片解码器libjpeg-turbo vs Skia最佳实践
android
河铃旅鹿2 小时前
在Ubuntu系统上为Android交叉编译OpenSSL
android·linux·ubuntu
nannan85862 小时前
android 性能+AI 日志库-StatLog
android
xuankuxiaoyao3 小时前
Zygisk-LSPosed 模块完整作用说明
android
YXL1111YXL3 小时前
ViewModel 底层原理
android
阿pin3 小时前
Android随笔-APP首次启动流程
android·application·activity
阿pin3 小时前
Android随笔-SELinux是什么?
android·selinux
红糖奶茶3 小时前
设备管理器中Android出现黄色感叹号怎么办? 如何修复?
android