1. 程式人生 > >selinux 程式碼實現原理

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) 主體訪問客體的流程: