selinux在 android 上的實現

1.  在init.c main函數裏面初始化
int main(int argc, char **argv){
..........
union selinux_callback cb;
cb.func_log = log_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
selinux_initialize();
.......
}
selinux_initialize()這個函數裏面先判斷SELinux 是否啓用,啓用則載入編譯出來的策略文件,並在用戶空間用mmap方式與內核共享策略文件,這樣內核之後就按照拿到的策略來控制訪問,然後設置SELinux啓動模式。(./external/libselinux/src)
   SELinux 啓動模式有兩種enforcing 和permissive。 enforcing 是強制安全檢查,不符合安全策略時不允許執行;permissive 模式也進行安全檢測,但是遇到不符合安全策略時僅僅打印警告信息,依然運行程序執行。
   可以在編譯文件裏面kernel cmdline 裏面加入啓動模式如androidboot.selinux=permissive。 一般eng版本使用的是permissive,user和user-debug版本啓動的是enforcing。當然如果對安全性要求不高,完全可以不啓用SELinux。在android5.1 之前默認並沒有真正意義上的使用。
 2. 策略文件在哪配置
    android模式的策略配置文件放在 external/sepolicy目錄下,一般不提倡直接修改這下面的文件,而是針對平臺或者項目在device或者vendor目錄下添加。比如:
  自己策略文件所在目錄:
    BOARD_SEPOLICY_DIRS += \
                    device/xxx/sepolicy

  所添加的策略文件
BOARD_SEPOLICY_UNION := \
        bluetooth.te \
        file.te 
  這樣添加的策略就參與編譯了。
3. 編譯出來的策略文件在哪?
    編譯出來的策略文件在out\...\root目錄下
   root\file_contexts
   root\sepolicy
   root\property_contexts
   root\seapp_contexts
   root\service_contexts
   所以修改完只需要編譯bootimage,但是燒錄boot 就可以驗證了。
4. 如何配置策略
   需要先了解系統針對客體和主體提供了哪些設置屬性和操作。
   external/sepolicy/security_classes 定義了客體的基本類型,比如下面的
 # for userspace object managers
class security
class process
class system
class capability
# file-related classes
class filesystem
class file
class dir
class fd
class lnk_file
class chr_file
class blk_file
class sock_file

     external/sepolicy/access_vectors 文件列出來各種客體類型所擁有的屬性,比如下面的file類型和dir 類型,類型間可以有集成關係。
common file
{
ioctl
read
write
create
getattr
setattr
lock
relabelfrom
relabelto
append
unlink
link
rename
execute
swapon
quotaon
mounton
}
class dir
inherits file
{
add_name
remove_name
reparent
search
rmdir
open
audit_access
execmod
}
external/sepolicy/global_macros全局宏變量定義文件,也就是用一個宏變量同時表示幾個屬性。如下例子
define(`x_file_perms', `{ getattr execute execute_no_trans }')
define(`r_file_perms', `{ getattr open read ioctl lock }')
define(`w_file_perms', `{ open append write }')
define(`rx_file_perms', `{ r_file_perms x_file_perms }')
define(`ra_file_perms', `{ r_file_perms append }')
define(`rw_file_perms', `{ r_file_perms w_file_perms }')
define(`rwx_file_perms', `{ rw_file_perms x_file_perms }')
define(`link_file_perms', `{ getattr link unlink rename }')
define(`create_file_perms', `{ create setattr rw_file_perms link_file_perms }')
external/sepolicy/te_macros 宏規則變量定義文件,也就是用一個變量來表示連續執行幾條規則。如下例子
define(`domain_trans', `
# Old domain may exec the file and transition to the new domain.
allow $1 $2:file { getattr open read execute };
allow $1 $3:process transition;
# New domain is entered by executing the file.
allow $3 $2:file { entrypoint open read execute getattr };
# New domain can send SIGCHLD to its caller.
allow $3 $1:process sigchld;
# Enable AT_SECURE, i.e. libc secure mode.
dontaudit $1 $3:process noatsecure;
# XXX dontaudit candidate but requires further study.
allow $1 $3:process { siginh rlimitinh };
')
external/sepolicy/file_contexts  文件安全上下文定義文件。就是說對於一個文件或者目錄,它的安全上下文應該在這裏定義,如果沒有定義,那麼默認和父目錄的安全上下文一樣。
比如說我們在data目錄下建了一個log目錄存放系統運行時的log,那麼我們可能希望這個log目錄的的安全上下文是u:object_r:data_log_file:s0
那麼就應該在file_contexts文件裏做如下定義:/data/log(/.*)?u:object_r:data_log_file:s0

external/sepolicy/property_contexts 屬性安全上下文定義文件。比如說新加了一個persist.log. * 開頭的屬性,那麼就需要給它添加對應的安全上下文,如果不添加或者添加的上下文不對,那麼在的某個進程裏寫入時就寫不進去。
比如做了如下定義,那麼是具有system_prop域安全上下文,只能在system進程裏修改值,在shell裏是不能訪問的。
persist.log.        u:object_r:system_prop:s0
如果希望在shell裏能修改值,就應該這麼寫persist.log.        u:object_r:shell_prop:s0 ,當然如果通過修改相關*.te 文件也能實現,但是不是很規範。

external/sepolicy/property.te 文件允許我們定義自己的prop 類型域,還有seapp_contexts、service_contexts 文件等,都是類似的,都可以根據需要修改。

下面幾個是常用到的規則操作
allow:賦予某項權限。
allowaudit:audit含義就是記錄某項操作。默認情況下是SELinux只記錄那些權限檢查失敗的操作。allowaudit則使得權限檢查成功的操作也被記錄。注意,allowaudit只是允許記錄,它和賦予權限沒關係。賦予權限必須且只能使用allow語句。
dontaudit:對那些權限檢查失敗的操作不做記錄。
neverallow:前面講過,用來檢查安全策略文件中是否有違反該項規則的allow語句
規則命令格式:規則名 主體域 客體域:類型權限屬性 ;       或者    規則名 主體域 客體域:類型 {權限屬性集合} ;
比如:
allow domain system_data_file:dir { search getattr };
allow domain system_file:file r_file_perms;

規則都定義在以te爲後綴的文件裏面,比如見到的init.te  installd.te system_app.te platform_app.te shell.te 等等。init.te 是針對init進程定義的規則,system_app.te 針對的是app進程是system的應用定義的規則,shell.te 針對的是shell進程定義的規則,以此類推。如果我們對某種類型的進程定義了新的規則,那麼我們應該把新規則添加到它對應的te文件裏面。比如我們在data目錄下加了一個log目錄,並且它的DAC權限爲777,安全上下文是u:object_r:data_log_file:s0,我們希望系統運行過程通過shell命令查看log,那麼我們就可以往shell.te 文件添加如下策略:
allow shelldata_log_file:dir r_dir_perms;
allow shell data_log_file:file r_file_perms;
如果我們新啓了一個進程,並且希望它運行在自己定義的安全上下文裏面,那麼我們應該給它添加對應的te規則文件。

————————————————
版權聲明:本文爲CSDN博主「譚小工」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/tww85/article/details/52451606

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章