selinux 代码实现原理

1. 概述 & 原理

selinux描述的是主体(进程)和客体(文件,socket, 进程间通信的管道)间的访问控制的安全上下文。一个进程或者一个文件,目录相当于有了独有的一个安全域,其他的文件,进程要访问具有安全上下文的文件或者进程,需要有安全上下文标识的标签,才能互通有无。

比如可以自己定义一个域:
type test_monitor, domain; //test_monitor具有domain属性
type test_monitor_exec, exec_type, file_type; //test_monitor_exec具有exec_type, file_type属性
init_daemon_domain(test_monitor) //初始化并启用

//规则定义
allow test_monitor system_file:file { read open getattr execute_no_trans};
allow test_monitor sysfs_devices_system_cpu:file rw_file_perms;
allow test_monitor shell_exec:file read;

系统中,在已有的模块中添加一些需求,涉及安全上下文的话,就直接添加对应的安全策略就行;如果是新添加模块,就需要自己新定义安全域(domain)和type 标签,如上例子。

2. 代码角度

(1)系统内部的访问,selinux调用栈(mount命令示例):
SYSCALL_mount(fs/namespace.c) –>
do_mount() –>
security_sb_mount(security/security.c) –>
security_ops->sb_mount(security/selinux/hooks.c) –>
selinux_mount() –>
path_has_perm() –>
avc_has_perm_flags(security/selinux/avc.c)

(2) 系统工具,对selinux子系统模块的设置:
~$ setenforce 1/0

~$ getenforce

setenforce / getenforce的命令代码位置:external/toybox/toys/android/(Android的busybox代码位置:external/toybox)
我们可以通过selinuxfs来对selinux进行整体的设置,比如通过setenforce / getenforce系统命令打开/关闭selinux:
setenforce_main()(external/toybox/toys/android/setenforce.c) –>
security_setenforce()(external/libselinux/src/setenforce.c) –>
open(/sys/fs/selinux/enforce, …) –>
write(/sys/fs/selinux/enforce, …) –>
sel_enforce_ops->sel_read_enforce()/sel_write_enforce()(kernel/security/selinux/selinuxfs.c) –>
close(/sys/fs/selinux/enforce)

(3) LSM(Linux Security Module)主要是由hook函数组成的安全控制框架:
hooks.c :
selinux_init() :
–> security_module_enable(&selinux_ops)
–> cred_init_security()
–> create “selinux_inode_security”cache
–> avc_init()(avc.c)
avc.c (Access Vector Cache):
avc_init():
—> avc中的各个cache的申请

include/linux/selinux.h
–> 主要是security operation函数结构体的申明
include/linux/selinux.h

(4) 代码路径
a). external/sepolicy/
(1) 包含一些原生的安全策略文件和工具
(2) 使用m4工具,将各个安全策略文件生成policy.conf :
all of te file(有的平台直接使用cat命令将各个te文件收集在一起) –>
m4 macro processor –>
checkpolicy(语法,规则检查,生成二进制文件) –>
Binary policy file(sepolicy)

b). external/libselinux(libselinux 动态库) :
setenforce/getenforce/…,这些系统命令实现时候,需要的一些接口:
eg :
security_setenforce(), 该接口会打开 “/sys/fs/selinux/enforce”属性节点,设置1/0

c). external/selinux(selinux自用的一些工具):
checkpolicy
libselinux(编译后包含各个独立的小工具,自带main)
libsemanage
libsepol

d). kernel/security/selinux(kernel中selinux代码):
包括selinuxfs, AVC, hook等.
hooks.c:
security_initcall(selinux_init);//独立的模块加载
selinux_fs.c:
register_filesystem(&sel_fs_type);
__initcall(init_sel_fs);

static struct file_system_type sel_fs_type = {
.name = “selinuxfs”,
.mount = sel_mount,
.kill_sb = kill_litter_super,
};

(5) 根据需要,放置在各个地方的安全策略文件,比如,device/qcom/sepolicy/

(6) 系统调用,busybox中的命令实现(setenforce/getenforce/…),代码路径:
external/toybox/toys/android/
(7) 启动过程中的初始化:
system/core/init/init.cpp:
main() –>
selinux_initialize() –>
selinux_android_load_policy()(external/libselinux/src/android.c)

(8) 主体访问客体的流程:
selinux 代码实现原理_第1张图片

你可能感兴趣的:(Android)