SELinux/SEAndroid 實例簡述(二) TE語言規則



  1. /***********************************
  2. * Author:劉江明
  3. * Environment:MTK Android 6.0
  4. * Date:2016年11月05日
  5. ***********************************/

一. 基本語法
很多te文件集中在\external\sepolicy文件夾下,MTK也有很多自定義的在\device\mediatek\common\sepolicy。它的最基本樣式是      
  1. allow factory powerctl_prop:property_service set;
  2. allow factory ttyGS_device:chr_file { read write open ioctl};
  3. allow factory ttyMT_device:chr_file { read write open ioctl};
  4. allow factory irtx_device:chr_file { read write ioctl open };
  5. allow factory devpts:chr_file { read write getattr ioctl };
這些allow語句就是最基本的te語句了,相似的te語句的會被歸類在一個的te文件下面。如上面的語句是作用於factory,則會在factory.te文件裏。\external\sepolicy集中了很多系統定義的te文件 
文件名 歸類
mac_permissions.xml App進程
seapp_contexts App數據文件
file_contexts 系統文件
property_contexts 系統屬性
最基本的語法爲:   
  1. /*
  2. rule_name:規則名,分別有allow,dontaudit,neverallow等
  3. source_type:主要作用是用來填寫一個域(domain)
  4. target_type:類型
  5. class:類別,主要有File,Dir,Socket,SEAndroid還有Binder等
  6. perm_set:動作集
  7. */
  8. rule_name source_type target_type:class perm_set
我們 從上面拿一個實例下來分析一下:
  1. /*
  2. 用中文來表述是:允許factory域裏的進程或服務
  3. 對類型爲ttyMT_device的類別爲文件(file)
  4. 執行open,read,write,ioctl權限
  5. */
  6. allow factory ttyMT_device:chr_file { read write open ioctl};

te表達式基本上就是這樣:
rule_name:規則名稱,除了有allow還有dontaudit,auditallow和neverallow
source_type:源類型,對應一個很重要的概念--------域(domain)
tartget_type:目標的類型,即安全上下文,SELinux一個重要的判斷對象
class:類別,目標(客體)是哪種類別,主要有File,Dir,Socket,SEAndroid還有Binder等,在這些基礎上又細分出設備字符類型(chr_file),鏈接文件(lnk_file)等。可以通過ls -l查看文件類型
perm_set:動作集

從上到下按順序介紹一下:
rule_name:

 allow:允許某個進程執行某個動作
auditallow:audit含義就是記錄某項操作。默認SELinux只記錄那些權限檢查失敗的操作。 auditallow則使得權限檢查成功的操作也被記錄。注意,allowaudit只是允許記錄,它和賦予權限沒關係。賦予權限必須且只能使用allow語句。
dontaudit:對那些權限檢查失敗的操作不做記錄。
neverallow:沒有被allow到的動作默認就不允許執行的。neverallow只是顯式地寫出某個動作不被允許,如果添加了該動作的allow,則會編譯錯誤

source_type:
指定一個“域”(domain),一般用於描述進程,該域內的的進程,受該條TE語句的限制。用type關鍵字,把一個自定義的域與原有的域相關聯
最簡單地定義一個新域的方式爲:
  1. type shell, domain
上面這句話的意思是,賦予shell給domain屬性,同時,shell與屬於domain這個集合裏。如果有一個allow domain xxxxx 的語句,同樣地也給了shell xxxxx的屬性

target_type:
指定進程需要操作的客體(文件,文件夾等)類型(安全上下文),同樣是用type與一些已有的類型,屬性相關聯
以上面的ttyMT_device爲例:
  1. //定義一個類型,屬於dev_type屬性
  2. type ttyMT_device, dev_type;
  3. //屬性dev_type在external/sepolicyattributes的定義如下
  4. attribute dev_type;
attribute關鍵字定義一個屬性,type可以與一個或多個屬性關聯,如
  1. type usb_device, dev_type, mlstrustedobject;
另外,還有一個關鍵字typeattribute,type有兩個作用,定義(聲明)並關聯某個屬性。可以把這兩個作用分開,type定義,typeattribute進行關聯
  1. #定義httpd_user_content_t,並關聯兩個屬性
  2. type httpd_user_content_t, file_type, httpdcontent;
  3. 分成兩條語句進行表述:
  4. #定義httpd_user_content_t
  5. type httpd_user_content_t;
  6. #關聯屬性
  7. typeattribute httpd_user_content_t file_type, httpdcontent;
這些類型(安全上下文)會顯示地與一個“文件”想關聯,如:
file_contexts裏面顯式定義了哪些文件屬於ttyMT_device類型,即用ls -Z顯示出來文件的安全上下文
  1. /dev/ttyMT.* u:object_r:ttyMT_device:s0
虛擬文件系統的標識方式與普通的文件系統文件標識方式不一樣,用genfscon來配置。
  1. genfscon的語法是:
  2. genfscon fs_type pathprefix [-file_type] context
把/proc/mtk_demo/demo_file文件的安全上下文設置成demo_context
  1. genfscon proc /mtk_demo/demo_file u:object_r:demo_context:s0

網絡對象上下文
  1. 1:定義端口的上下文
  2. portcon tcp 80 system_u:object_r:http_port_t
  3. portcon tcp 8080 system_u:object_r:http_port_t
  4. 2:定義網絡接口的上下文:
  5. netifcon eth0 system_u:object_r:netif_eth0_t system_u:object_r:netmsg_eth0_t
  6. 3:定義節點的上下文
  7. nodecon 10.33.10.66 255.255.255.255 system_u:object_r:node_zeus_t;
  8. nodecon 10.33.10.0 255.255.255.0 system_u:object_r:node_any_t
        
然後你會有一個疑問,這麼多屬性,這些屬性有什麼作用,這些屬性會有一個地方顯式地說明這個屬性擁有什麼權限,在external/sepolicy/domain裏就有非常詳細的描述。另個在external/sepolicy/attributes裏定義了很多屬性,下面截取了一些常見的定義
  1. # All types used for devices.
  2. attribute dev_type;
  3. # All types used for processes.
  4. attribute domain;
  5. # All types used for filesystems.
  6. attribute fs_type;
  7. # All types used for files that can exist on a labeled fs.
  8. # Do not use for pseudo file types.
  9. attribute file_type;
  10. # All types used for domain entry points.
  11. attribute exec_type;
  12. # All types used for property service
  13. attribute property_type;
  14. # All service_manager types created by system_server
  15. attribute system_server_service;
  16. # All domains that can override MLS restrictions.
  17. # i.e. processes that can read up and write down.
  18. attribute mlstrustedsubject;
  19. # All types that can override MLS restrictions.
  20. # i.e. files that can be read by lower and written by higher
  21. attribute mlstrustedobject;
  22. # All domains used for apps.
  23. attribute appdomain;
  24. # All domains used for apps with network access.
  25. attribute netdomain;
  26. # All domains used for binder service domains.
  27. attribute binderservicedomain;

class:
客體的具體類別。用class來定義一個客體類別,具體定義方式 如下
  1. [external/sepolicy/security_classes示例]
  2. # file-related classes
  3. class filesystem
  4. class file #代表普通文件
  5. class dir #代表目錄
  6. class fd #代表文件描述符
  7. class lnk_file #代表鏈接文件
  8. class chr_file #代表字符設備文件
  9. ......
  10. # network-related classes
  11. class socket #socket
  12. class tcp_socket
  13. class udp_socket
  14. ......
  15. class binder #Android平臺特有的binder
  16. class zygote #Android平臺特有的zygote

perm_set:
具體的操作,系統的定義在external/sepolicy/access_vectors。有兩種定義方法。
用common命令定義:
  1. 格式爲:common common_name { permission_name ... }
  2. common定義的perm set能被另外一種perm set命令class所繼承
  3. 如:
  4. common file {
  5. ioctl read write create getattr setattr lock relabelfrom relabelto
  6. append unlink link rename execute swapon quotaon mounton
用class命令定義:
  1. class class_name [ inherits common_name ] { permission_name ... }
  2. inherits表示繼承了某個common定義的權限
  3. 注意,class命令它不能被其他class繼承
  4. 繼承一個common,如繼承了file common
  5. class dir
  6. inherits file
  7. {
  8. add_name
  9. remove_name
  10. reparent
  11. search
  12. rmdir
  13. open
  14. audit_access
  15. execmod
  16. }
  17. 不繼承任何common,如
  18. class binder
  19. {
  20. impersonate
  21. call
  22. set_context_mgr
  23. transfer
  24. }

  1. 然後是一些特殊的配置文件:
  2. a. external/sepolicy/attributes -> 所有定義的attributes都在這個文件
  3. b. external/sepolicy/access_vectors -> 對應了每一個class可以被允許執行的命令
  4. c. external/sepolicy/roles -> Android中只定義了一個role,名字就是r,將rattribute domain關聯起來
  5. d. external/sepolicy/users -> 其實是將userroles進行了關聯,設置了user的安全級別,s0爲最低級是默認的級別,mls_systemHigh是最高的級別
  6. e. external/sepolicy/security_classes -> 指的是上文命令中的class,個人認爲這個class的內容是指在android運行過程中,程序或者系統可能用到的操作的模塊
  7. f. external/sepolicy/te_macros -> 系統定義的宏全在te_macros文件
  8. g. external/sepolicy/***.te -> 一些配置的文件,包含了各種運行的規則
                                                                                                    ----------------引用於《android中SELINUX規則分析和語法簡介

二. TE的正則表達式和集合
TE文件支持正則表達式,從下面可以看到,通配符是常用的通配符,可以度娘
  1. /sys/devices/system/cpu(/.*)? u:object_r:sysfs_devices_system_cpu:s0
  2. /sys/power/wake_lock -- u:object_r:sysfs_wake_lock:s0
  3. /sys/power/wake_unlock -- u:object_r:sysfs_wake_lock:s0
  4. /sys/kernel/uevent_helper -- u:object_r:usermodehelper:s0
  5. /sys/module/lowmemorykiller(/.*)? -- u:object_r:sysfs_lowmemorykiller:s0
  6. #############################
  7. # asec containers
  8. /mnt/asec(/.*)? u:object_r:asec_apk_file:s0
  9. /mnt/asec/[^/]+/[^/]+\.zip u:object_r:asec_public_file:s0
需要注意的是上面的"--",這裏的“--”表示二進制文件,類似的還有
  1. #‘-b’ - Block Device ‘-c’ - Character Device
  2. #‘-d’ - Directory ‘-p’ - Named Pipe
  3. #‘-l’ - Symbolic Link ‘-s’ - Socket
  4. #‘--’ - Ordinary file
TE表達式裏可以用“{}”來表示一個集合,如:
  1. /*
  2. 允許user_t對bin_t類型的文件和文件夾執行read,getattr操作
  3. */
  4. allow user_t bin_t : { file dir } { read getattr };
  5. /*
  6. 允許domain對exec_type,sbin_t類型的文件執行execute的動作
  7. */
  8. allow domain { exec_type sbin_t } : file execute;
可以在集合裏使用“*”,“-” 和 “~” 三個通配符
  1. /*
  2. 允許user_t對bin_t類型的文件和文件夾執行所有操作
  3. */
  4. allow user_t bin_t : { file dir } *;
  5. /*
  6. 允許user_t對bin_t類型的文件和文件夾執行除了read,getattr以外的所有操作
  7. */
  8. allow user_t bin_t : { file dir } ~{ read getattr };
  9. /*
  10. 允許domain對exec_type類型的文件執行execute的動作,除了sbin_t以外
  11. */
  12. allow domain { exec_type -sbin_t } : file execute;

三. TE的類型轉換規則
爲什麼要轉換類型
init進程擁有系統的最高權限,如果由Init進程fork,execu出來的進程默認是與init相同的權限,這肯定是不安全的。另一個場景是,由init生成的文件,默認也是init的讀寫權限,不方便其他低權限的文件進行訪問。

類型轉換有兩種類型轉換:
1. 主體的域的轉換
2. 客體的轉換

域的轉換
type_transition的完整格式爲:
  1. type_transition source_type target_type : class default_type;
  2. 舉個例子
  3. type_transition init_t apache_exec_t : process apache_t;
type_transition init_t apache_exec_t : process apache_t;
 init_t 進程執行type爲apache_exec_t的可執行文件時,新的進程轉換到apache_t域
但是上面只是告訴了轉換的過程,卻沒有說明,有轉換的權限,如果要上面的轉換成功,還需要下面的語句:
  1. #首先,你得讓init_t域中的進程能夠執行type爲apache_exec_t的文件
  2. allow init_t apache_exec_t : file execute;
  3. #然後,你還得告訴SELiux,允許init_t做DT切換以進入apache_t域
  4. allow init_t apache_t : process transition;
  5. #最後,你還得告訴SELinux,切換入口(對應爲entrypoint權限)爲執行pache_exec_t類型的文件
  6. allow apache_t apache_exec_t : file entrypoint;

客體的轉換
例子:
  1. type_transition passwd_t tmp_t : file passwd_tmp_t;
passwd_t在tmp_t目錄下創建文件時,該文件的類型轉化爲passwd_tmp_t。這裏默認隱含了一個tmp_t類型dir,因爲file的容器只能是個dir。同樣的,如果要上面的語句運行成功,與需要有相應的權限說明:
  1. 對應的必須有兩個前提條件:
  2. * The source domain needs permission to add file entries into the directory
  3. 這個process 必須有在這個目錄下添加文件的權限.
  4. * The source domain needs permission to create file entries
  5. 這個process 必須有在這個目錄下創建以這個Security Context Label 的文件權限.
如果每個轉換之前都需要這樣繁鎖地權限聲音實在很麻煩。TE裏允許把這些相同的,重複使用的語句定義成一個宏,類似於函數一樣。

四. TE的宏
如果把上面domain轉換的例子定義成一個宏,應該定義如下:
  1. #定義domain_auto_trans宏,$1,$2等等代表宏的第一個,第二個....參數
  2. define(`domain_auto_trans', `
  3. # 先allow相關權限,domain_trans宏定義在後面
  4. domain_trans($1,$2,$3)
  5. # 然後設置type_transition
  6. type_transition $1 $2:process $3;
  7. ')
  8. #定義domain_trans宏。
  9. define(`domain_trans', `
  10. # SEAndroid在上述三個最小權限上,還添加了自己的一些權限
  11. allow $1 $2:file { getattr open read execute };
  12. allow $1 $3:process transition;
  13. allow $3 $2:file { entrypoint read execute };
  14. allow $3 $1:process sigchld;
  15. dontaudit $1 $3:process noatsecure;
  16. allow $1 $3:process { siginh rlimitinh };
  17. ')
上面的宏定義在external/sepolicy/te_macros裏。客體的轉換定義如下:
  1. #####################################
  2. # file_type_auto_trans(domain, dir_type, file_type)
  3. # Automatically label new files with file_type when
  4. # they are created by domain in directories labeled dir_type.
  5. #
  6. define(`file_type_auto_trans', `
  7. # Allow the necessary permissions.
  8. file_type_trans($1, $2, $3)
  9. # Make the transition occur by default.
  10. type_transition $1 $2:dir $3;
  11. type_transition $1 $2:notdevfile_class_set $3;
  12. ')
  13. define(`file_type_trans', `
  14. # Allow the domain to add entries to the directory.
  15. allow $1 $2:dir ra_dir_perms;
  16. # Allow the domain to create the file.
  17. allow $1 $3:notdevfile_class_set create_file_perms;
  18. allow $1 $3:dir create_dir_perms;
  19. ')

TE的集合也可以定義成一個宏代替,如讀寫文件操作集的宏:
  1. define(`x_file_perms', `{ getattr execute execute_no_trans }')
  2. define(`r_file_perms', `{ getattr open read ioctl lock }')
  3. define(`w_file_perms', `{ open append write }')
  4. define(`rx_file_perms', `{ r_file_perms x_file_perms }')
  5. define(`ra_file_perms', `{ r_file_perms append }')
  6. define(`rw_file_perms', `{ r_file_perms w_file_perms }')
  7. define(`rwx_file_perms', `{ rw_file_perms x_file_perms }')
  8. define(`create_file_perms', `{ create rename setattr unlink rw_file_perms }')
使用方式是:
  1. allow demo demo_device:chr_file rw_file_perms;


 參考文章:
  1. /***********************************
  2. * Author:劉江明
  3. * Environment:MTK Android 6.0
  4. * Date:2016年11月05日
  5. ***********************************/

一. 基本語法
很多te文件集中在\external\sepolicy文件夾下,MTK也有很多自定義的在\device\mediatek\common\sepolicy。它的最基本樣式是      
  1. allow factory powerctl_prop:property_service set;
  2. allow factory ttyGS_device:chr_file { read write open ioctl};
  3. allow factory ttyMT_device:chr_file { read write open ioctl};
  4. allow factory irtx_device:chr_file { read write ioctl open };
  5. allow factory devpts:chr_file { read write getattr ioctl };
這些allow語句就是最基本的te語句了,相似的te語句的會被歸類在一個的te文件下面。如上面的語句是作用於factory,則會在factory.te文件裏。\external\sepolicy集中了很多系統定義的te文件 
文件名 歸類
mac_permissions.xml App進程
seapp_contexts App數據文件
file_contexts 系統文件
property_contexts 系統屬性
最基本的語法爲:   
  1. /*
  2. rule_name:規則名,分別有allow,dontaudit,neverallow等
  3. source_type:主要作用是用來填寫一個域(domain)
  4. target_type:類型
  5. class:類別,主要有File,Dir,Socket,SEAndroid還有Binder等
  6. perm_set:動作集
  7. */
  8. rule_name source_type target_type:class perm_set
我們 從上面拿一個實例下來分析一下:
  1. /*
  2. 用中文來表述是:允許factory域裏的進程或服務
  3. 對類型爲ttyMT_device的類別爲文件(file)
  4. 執行open,read,write,ioctl權限
  5. */
  6. allow factory ttyMT_device:chr_file { read write open ioctl};

te表達式基本上就是這樣:
rule_name:規則名稱,除了有allow還有dontaudit,auditallow和neverallow
source_type:源類型,對應一個很重要的概念--------域(domain)
tartget_type:目標的類型,即安全上下文,SELinux一個重要的判斷對象
class:類別,目標(客體)是哪種類別,主要有File,Dir,Socket,SEAndroid還有Binder等,在這些基礎上又細分出設備字符類型(chr_file),鏈接文件(lnk_file)等。可以通過ls -l查看文件類型
perm_set:動作集

從上到下按順序介紹一下:
rule_name:
 allow:允許某個進程執行某個動作
auditallow:audit含義就是記錄某項操作。默認SELinux只記錄那些權限檢查失敗的操作。 auditallow則使得權限檢查成功的操作也被記錄。注意,allowaudit只是允許記錄,它和賦予權限沒關係。賦予權限必須且只能使用allow語句。
dontaudit:對那些權限檢查失敗的操作不做記錄。
neverallow:沒有被allow到的動作默認就不允許執行的。neverallow只是顯式地寫出某個動作不被允許,如果添加了該動作的allow,則會編譯錯誤

source_type:
指定一個“域”(domain),一般用於描述進程,該域內的的進程,受該條TE語句的限制。用type關鍵字,把一個自定義的域與原有的域相關聯
最簡單地定義一個新域的方式爲:
  1. type shell, domain
上面這句話的意思是,賦予shell給domain屬性,同時,shell與屬於domain這個集合裏。如果有一個allow domain xxxxx 的語句,同樣地也給了shell xxxxx的屬性

target_type:
指定進程需要操作的客體(文件,文件夾等)類型(安全上下文),同樣是用type與一些已有的類型,屬性相關聯
以上面的ttyMT_device爲例:
  1. //定義一個類型,屬於dev_type屬性
  2. type ttyMT_device, dev_type;
  3. //屬性dev_type在external/sepolicyattributes的定義如下
  4. attribute dev_type;
attribute關鍵字定義一個屬性,type可以與一個或多個屬性關聯,如
  1. type usb_device, dev_type, mlstrustedobject;
另外,還有一個關鍵字typeattribute,type有兩個作用,定義(聲明)並關聯某個屬性。可以把這兩個作用分開,type定義,typeattribute進行關聯
  1. #定義httpd_user_content_t,並關聯兩個屬性
  2. type httpd_user_content_t, file_type, httpdcontent;
  3. 分成兩條語句進行表述:
  4. #定義httpd_user_content_t
  5. type httpd_user_content_t;
  6. #關聯屬性
  7. typeattribute httpd_user_content_t file_type, httpdcontent;
這些類型(安全上下文)會顯示地與一個“文件”想關聯,如:
file_contexts裏面顯式定義了哪些文件屬於ttyMT_device類型,即用ls -Z顯示出來文件的安全上下文
  1. /dev/ttyMT.* u:object_r:ttyMT_device:s0
虛擬文件系統的標識方式與普通的文件系統文件標識方式不一樣,用genfscon來配置。
  1. genfscon的語法是:
  2. genfscon fs_type pathprefix [-file_type] context
把/proc/mtk_demo/demo_file文件的安全上下文設置成demo_context
  1. genfscon proc /mtk_demo/demo_file u:object_r:demo_context:s0

網絡對象上下文
  1. 1:定義端口的上下文
  2. portcon tcp 80 system_u:object_r:http_port_t
  3. portcon tcp 8080 system_u:object_r:http_port_t
  4. 2:定義網絡接口的上下文:
  5. netifcon eth0 system_u:object_r:netif_eth0_t system_u:object_r:netmsg_eth0_t
  6. 3:定義節點的上下文
  7. nodecon 10.33.10.66 255.255.255.255 system_u:object_r:node_zeus_t;
  8. nodecon 10.33.10.0 255.255.255.0 system_u:object_r:node_any_t
        
然後你會有一個疑問,這麼多屬性,這些屬性有什麼作用,這些屬性會有一個地方顯式地說明這個屬性擁有什麼權限,在external/sepolicy/domain裏就有非常詳細的描述。另個在external/sepolicy/attributes裏定義了很多屬性,下面截取了一些常見的定義
  1. # All types used for devices.
  2. attribute dev_type;
  3. # All types used for processes.
  4. attribute domain;
  5. # All types used for filesystems.
  6. attribute fs_type;
  7. # All types used for files that can exist on a labeled fs.
  8. # Do not use for pseudo file types.
  9. attribute file_type;
  10. # All types used for domain entry points.
  11. attribute exec_type;
  12. # All types used for property service
  13. attribute property_type;
  14. # All service_manager types created by system_server
  15. attribute system_server_service;
  16. # All domains that can override MLS restrictions.
  17. # i.e. processes that can read up and write down.
  18. attribute mlstrustedsubject;
  19. # All types that can override MLS restrictions.
  20. # i.e. files that can be read by lower and written by higher
  21. attribute mlstrustedobject;
  22. # All domains used for apps.
  23. attribute appdomain;
  24. # All domains used for apps with network access.
  25. attribute netdomain;
  26. # All domains used for binder service domains.
  27. attribute binderservicedomain;

class:
客體的具體類別。用class來定義一個客體類別,具體定義方式 如下
  1. [external/sepolicy/security_classes示例]
  2. # file-related classes
  3. class filesystem
  4. class file #代表普通文件
  5. class dir #代表目錄
  6. class fd #代表文件描述符
  7. class lnk_file #代表鏈接文件
  8. class chr_file #代表字符設備文件
  9. ......
  10. # network-related classes
  11. class socket #socket
  12. class tcp_socket
  13. class udp_socket
  14. ......
  15. class binder #Android平臺特有的binder
  16. class zygote #Android平臺特有的zygote

perm_set:
具體的操作,系統的定義在external/sepolicy/access_vectors。有兩種定義方法。
用common命令定義:
  1. 格式爲:common common_name { permission_name ... }
  2. common定義的perm set能被另外一種perm set命令class所繼承
  3. 如:
  4. common file {
  5. ioctl read write create getattr setattr lock relabelfrom relabelto
  6. append unlink link rename execute swapon quotaon mounton
用class命令定義:
  1. class class_name [ inherits common_name ] { permission_name ... }
  2. inherits表示繼承了某個common定義的權限
  3. 注意,class命令它不能被其他class繼承
  4. 繼承一個common,如繼承了file common
  5. class dir
  6. inherits file
  7. {
  8. add_name
  9. remove_name
  10. reparent
  11. search
  12. rmdir
  13. open
  14. audit_access
  15. execmod
  16. }
  17. 不繼承任何common,如
  18. class binder
  19. {
  20. impersonate
  21. call
  22. set_context_mgr
  23. transfer
  24. }

  1. 然後是一些特殊的配置文件:
  2. a. external/sepolicy/attributes -> 所有定義的attributes都在這個文件
  3. b. external/sepolicy/access_vectors -> 對應了每一個class可以被允許執行的命令
  4. c. external/sepolicy/roles -> Android中只定義了一個role,名字就是r,將rattribute domain關聯起來
  5. d. external/sepolicy/users -> 其實是將userroles進行了關聯,設置了user的安全級別,s0爲最低級是默認的級別,mls_systemHigh是最高的級別
  6. e. external/sepolicy/security_classes -> 指的是上文命令中的class,個人認爲這個class的內容是指在android運行過程中,程序或者系統可能用到的操作的模塊
  7. f. external/sepolicy/te_macros -> 系統定義的宏全在te_macros文件
  8. g. external/sepolicy/***.te -> 一些配置的文件,包含了各種運行的規則
                                                                                                    ----------------引用於《android中SELINUX規則分析和語法簡介

二. TE的正則表達式和集合
TE文件支持正則表達式,從下面可以看到,通配符是常用的通配符,可以度娘
  1. /sys/devices/system/cpu(/.*)? u:object_r:sysfs_devices_system_cpu:s0
  2. /sys/power/wake_lock -- u:object_r:sysfs_wake_lock:s0
  3. /sys/power/wake_unlock -- u:object_r:sysfs_wake_lock:s0
  4. /sys/kernel/uevent_helper -- u:object_r:usermodehelper:s0
  5. /sys/module/lowmemorykiller(/.*)? -- u:object_r:sysfs_lowmemorykiller:s0
  6. #############################
  7. # asec containers
  8. /mnt/asec(/.*)? u:object_r:asec_apk_file:s0
  9. /mnt/asec/[^/]+/[^/]+\.zip u:object_r:asec_public_file:s0
需要注意的是上面的"--",這裏的“--”表示二進制文件,類似的還有
  1. #‘-b’ - Block Device ‘-c’ - Character Device
  2. #‘-d’ - Directory ‘-p’ - Named Pipe
  3. #‘-l’ - Symbolic Link ‘-s’ - Socket
  4. #‘--’ - Ordinary file
TE表達式裏可以用“{}”來表示一個集合,如:
  1. /*
  2. 允許user_t對bin_t類型的文件和文件夾執行read,getattr操作
  3. */
  4. allow user_t bin_t : { file dir } { read getattr };
  5. /*
  6. 允許domain對exec_type,sbin_t類型的文件執行execute的動作
  7. */
  8. allow domain { exec_type sbin_t } : file execute;
可以在集合裏使用“*”,“-” 和 “~” 三個通配符
  1. /*
  2. 允許user_t對bin_t類型的文件和文件夾執行所有操作
  3. */
  4. allow user_t bin_t : { file dir } *;
  5. /*
  6. 允許user_t對bin_t類型的文件和文件夾執行除了read,getattr以外的所有操作
  7. */
  8. allow user_t bin_t : { file dir } ~{ read getattr };
  9. /*
  10. 允許domain對exec_type類型的文件執行execute的動作,除了sbin_t以外
  11. */
  12. allow domain { exec_type -sbin_t } : file execute;

三. TE的類型轉換規則
爲什麼要轉換類型
init進程擁有系統的最高權限,如果由Init進程fork,execu出來的進程默認是與init相同的權限,這肯定是不安全的。另一個場景是,由init生成的文件,默認也是init的讀寫權限,不方便其他低權限的文件進行訪問。

類型轉換有兩種類型轉換:
1. 主體的域的轉換
2. 客體的轉換

域的轉換
type_transition的完整格式爲:
  1. type_transition source_type target_type : class default_type;
  2. 舉個例子
  3. type_transition init_t apache_exec_t : process apache_t;
type_transition init_t apache_exec_t : process apache_t;
 init_t 進程執行type爲apache_exec_t的可執行文件時,新的進程轉換到apache_t域
但是上面只是告訴了轉換的過程,卻沒有說明,有轉換的權限,如果要上面的轉換成功,還需要下面的語句:
  1. #首先,你得讓init_t域中的進程能夠執行type爲apache_exec_t的文件
  2. allow init_t apache_exec_t : file execute;
  3. #然後,你還得告訴SELiux,允許init_t做DT切換以進入apache_t域
  4. allow init_t apache_t : process transition;
  5. #最後,你還得告訴SELinux,切換入口(對應爲entrypoint權限)爲執行pache_exec_t類型的文件
  6. allow apache_t apache_exec_t : file entrypoint;

客體的轉換
例子:
  1. type_transition passwd_t tmp_t : file passwd_tmp_t;
passwd_t在tmp_t目錄下創建文件時,該文件的類型轉化爲passwd_tmp_t。這裏默認隱含了一個tmp_t類型dir,因爲file的容器只能是個dir。同樣的,如果要上面的語句運行成功,與需要有相應的權限說明:
  1. 對應的必須有兩個前提條件:
  2. * The source domain needs permission to add file entries into the directory
  3. 這個process 必須有在這個目錄下添加文件的權限.
  4. * The source domain needs permission to create file entries
  5. 這個process 必須有在這個目錄下創建以這個Security Context Label 的文件權限.
如果每個轉換之前都需要這樣繁鎖地權限聲音實在很麻煩。TE裏允許把這些相同的,重複使用的語句定義成一個宏,類似於函數一樣。

四. TE的宏
如果把上面domain轉換的例子定義成一個宏,應該定義如下:
  1. #定義domain_auto_trans宏,$1,$2等等代表宏的第一個,第二個....參數
  2. define(`domain_auto_trans', `
  3. # 先allow相關權限,domain_trans宏定義在後面
  4. domain_trans($1,$2,$3)
  5. # 然後設置type_transition
  6. type_transition $1 $2:process $3;
  7. ')
  8. #定義domain_trans宏。
  9. define(`domain_trans', `
  10. # SEAndroid在上述三個最小權限上,還添加了自己的一些權限
  11. allow $1 $2:file { getattr open read execute };
  12. allow $1 $3:process transition;
  13. allow $3 $2:file { entrypoint read execute };
  14. allow $3 $1:process sigchld;
  15. dontaudit $1 $3:process noatsecure;
  16. allow $1 $3:process { siginh rlimitinh };
  17. ')
上面的宏定義在external/sepolicy/te_macros裏。客體的轉換定義如下:
  1. #####################################
  2. # file_type_auto_trans(domain, dir_type, file_type)
  3. # Automatically label new files with file_type when
  4. # they are created by domain in directories labeled dir_type.
  5. #
  6. define(`file_type_auto_trans', `
  7. # Allow the necessary permissions.
  8. file_type_trans($1, $2, $3)
  9. # Make the transition occur by default.
  10. type_transition $1 $2:dir $3;
  11. type_transition $1 $2:notdevfile_class_set $3;
  12. ')
  13. define(`file_type_trans', `
  14. # Allow the domain to add entries to the directory.
  15. allow $1 $2:dir ra_dir_perms;
  16. # Allow the domain to create the file.
  17. allow $1 $3:notdevfile_class_set create_file_perms;
  18. allow $1 $3:dir create_dir_perms;
  19. ')

TE的集合也可以定義成一個宏代替,如讀寫文件操作集的宏:
  1. define(`x_file_perms', `{ getattr execute execute_no_trans }')
  2. define(`r_file_perms', `{ getattr open read ioctl lock }')
  3. define(`w_file_perms', `{ open append write }')
  4. define(`rx_file_perms', `{ r_file_perms x_file_perms }')
  5. define(`ra_file_perms', `{ r_file_perms append }')
  6. define(`rw_file_perms', `{ r_file_perms w_file_perms }')
  7. define(`rwx_file_perms', `{ rw_file_perms x_file_perms }')
  8. define(`create_file_perms', `{ create rename setattr unlink rw_file_perms }')
使用方式是:
  1. allow demo demo_device:chr_file rw_file_perms;


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