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;
相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui