標籤:selinux sepolicy sepolicy定製 selinux文法 sepolicy文法
#############################################
本文為極度寒冰原創,轉載請註明出處#############################################
1. SELINUX是可以理解為一種android上面的安全機制,是有美國國家安全域和一些公司設計的一個針對linux的安全加強系統
我們可以通過配置SELINUX的相關policy,來定製自己的手機的一些許可權,比如,我們可以完全讓root使用者沒有任何的許可權和user一樣
2. 在android裡面,有兩個類型,一種是檔案,一種是進程。
針對這兩種類型,我們可以先來看看他們的不同。
在android上面,adb shell之後進入手機,ps -Z可以查看當前進程所擁有的selinux的許可權。
舉例:
LABEL USER PID PPID NAMEu:r:init:s0 root 1 0 /initu:r:kernel:s0 root 2 0 kthreadd...u:r:kernel:s0 root 258 2 irq/322-HPH_R Ou:r:logd:s0 logd 259 1 /system/bin/logdu:r:healthd:s0 root 260 1 /sbin/healthdu:r:lmkd:s0 root 261 1 /system/bin/lmkdu:r:servicemanager:s0 system 262 1 /system/bin/servicemanageru:r:vold:s0 root 263 1 /system/bin/voldu:r:surfaceflinger:s0 system 264 1 /system/bin/surfaceflingeru:r:tctd:s0 root 265 1 /system/bin/tctdu:r:rfs_access:s0 system 268 1 /system/bin/rfs_accessu:r:tee:s0 system 271 1 /system/bin/qseecomdu:r:kernel:s0 root 280 2 kworker/3:1Hu:r:kernel:s0 root 290 2 kauditdu:r:rmt_storage:s0 nobody 291 1 /system/bin/rmt_storageu:r:shell:s0 shell 292 1 /system/bin/shu:r:netd:s0 root 295 1 /system/bin/netdu:r:debuggerd:s0 root 296 1 /system/bin/debuggerdu:r:tee:s0 system 297 271 /system/bin/qseecomd
在這個例子中,我們可以進行分析。
在android中,只定義了一個user即為u. 另外,如果是進程的話,都會統一定義為r,如果是檔案的話,會被定義為object_r. 第三個是這個進程type,在andorid裡面,定義了100多個type.按照目前我的理解,這個是進程所屬的>類型。第四個是s0,這個是一個安全的等級。但是暫時還沒有接觸到配置這個的地方。
另外就是檔案,檔案想要查看相關SELINUX許可權的話,需要去執行ls -Z
drwxr-x--x root sdcard_r u:object_r:rootfs:s0 storagedrwx--x--x root root u:object_r:tmpfs:s0 synthesisdr-xr-xr-x root root u:object_r:sysfs:s0 sysdrwxr-xr-x root root u:object_r:system_file:s0 systemdrwxrwxr-x system tctpersist u:object_r:tct_persist_file:s0 tctpersistlrwxrwxrwx root root u:object_r:rootfs:s0 tombstones -> /data/tombstones-rw-r--r-- root root u:object_r:rootfs:s0 ueventd.qcom.rc-rw-r--r-- root root u:object_r:rootfs:s0 ueventd.rc
在這個例子中,結合上面的分析,我們知道了object_r是代表的檔案,u是android的唯一的使用者,rootfs是這個檔案所對應的類型,s0是一個安全的等級限制。
3. 如何配置selinux
首先,按照Google的官方文檔:
需要linux核心首先是支援selinux的,另外需要android的selinux的設定檔,也就是extern/sepolicy裡面的內容。
然後就是修改BoardConfig.mk
Google的nexus的sepolicy的支援就放在了device/lge/mako/sepolicy
首先會包含廠商定製的sepolicy的檔案夾:BOARD_SEPOLICY_DIRS
然後將規則添加到了sepolicy中:BOARD_SEPOLICY_DIRS
這樣的話,我們編譯出來的image其實就是具有了selinux的功能。
其實如果沒有廠商定製的話,也是會編譯到external/sepolicy的,這樣的話,就是使用andriod所有預設的sepolicy(It defines the domains and types for the AOSP services and apps common to all devices. )
然後理解了這個之後,我們可以看到其實很多的廠商也是有自己的配置規則在device/***/***/sepolicy下面的.
4. selinux的配置規則:
首先要瞭解sepolicy的結構:
a. App進程 -> mac_permissions.xml
b. App資料檔案 -> seapp_contexts
c. 系統檔案 -> file_contexts
d. 系統屬性 -> property_contexts
在te檔案中,我們一般遇到的文法是這樣的:
rule_name source_type target_type:class perm_set
解讀為: 為source_type設定一個rule_name的規則,規則是對target_type的class 進行 perm_set的操作。
然後是一些特殊的設定檔:
a. external/sepolicy/attributes -> 所有定義的attributes都在這個檔案
b. external/sepolicy/access_vectors -> 對應了每一個class可以被允許執行的命令
c. external/sepolicy/roles -> Android中只定義了一個role,名字就是r,將r和attribute domain關聯起來
d. external/sepolicy/users -> 其實是將user與roles進行了關聯,設定了user的安全層級,s0為最低級是預設的層級,mls_systemHigh是最高的層級
e. external/sepolicy/security_classes -> 指的是上文命令中的class,個人認為這個class的內容是指在android運行過程中,程式或者系統可能用到的操作的模組
f. external/sepolicy/te_macros -> 系統定義的宏全在te_macros檔案
f. external/sepolicy/***.te -> 一些配置的檔案,包含了各種啟動並執行規則
另外,selinux有兩種工作模式:
“permissive”:所有操作都被允許(即沒有MAC),但是如果有違反許可權的話,會記錄日誌
“enforcing”:所有操作都會進行許可權檢查
最後,type的命令如下:
type type_id [alias alias_id,] [attribute_id] # 將type_id(別名為alias)關聯到attribute. 這樣的話,方便用attribute來管理不同的type中包含相同的屬性的部分。
class命令的格式為:
class class_name [ inherits common_name ] { permission_name ... }
inherits表示繼承了common定義的許可權,然後自己額外實現了permission_name的許可權
在te檔案中常見的四種命名的規則:
allow:賦予某項許可權。
allowaudit:audit含義就是記錄某項操作。預設情況下是SELinux只記錄那些許可權檢查失敗的操作。allowaudit則使得許可權檢查成功的操作也被記錄。注意,allowaudit只是允許記錄,它和賦予許可權沒關係。賦予許可權必須且只能使
用allow語句。
dontaudit:對那些許可權檢查失敗的操作不做記錄。
neverallow:前面講過,用來檢查安全性原則檔案中是否有違反該項規則的allow語句。如例子5所示:
舉例:
type init, domain;
將init關聯到domain,即將domain設定為init類型的屬性
allow init unlabeled:filesystem mount;
允許init類型對unlabeled類型的filesystem進行mount的操作
allow init fotad:unix_stream_socket { bind create };
允許init類型對fotad類型的unix_stream_socket 進行bind和create的操作
allow appdomain anr_data_file:dir search;
allow appdomain anr_data_file:file { open append };
首先appdomain是定義在te_macros裡面的一個宏,很多的app規則會使用類似app_domain(shell)的命令將其添加進去
這兩句話的意思是:1. 允許app去對anr_data_file類型的目錄進行尋找的操作
2. 允許app對anr_data_file類型的file進行開啟和添加操作 其實就是規定了出現anr時候,app往/data/anr/裡面寫入的許可權限制
neverallow { appdomain -unconfineddomain } kmem_device:chr_file { read write };
絕對不允許app(除了有unconfineddomain屬性的app)對kmem_device類型的字元裝置進行讀寫的操作
neverallow { appdomain -unconfineddomain } self:capability2 *;
絕對不允許除了unconfineddomain以外的app對self類型的capability2進行任何的操作
type httpd_user_content_t, file_type, httpdcontent;
聲明一個httpd_user_content_t的類型,具有file_type和httpdcontent的屬性
type httpd_user_content_t;
typeattribute httpd_user_content_t file_type, httpdcontent;
聲明一個httpd_user_content_t的類型
定義httpd_user_content_t具有file_type, httpdcontent的屬性
allow appdomain self:rawip_socket create_socket_perms;
所有可以設定類型的地方其實都可以設定為屬性。
比如這個例子,我們允許所有具有app屬性的內容可以去對self屬性的rawip_socket進行create的操作
allow {user_t domain} {bin_t file_type sbin_t}:file execute ;
允許user_t和domain屬性的類對bin_t, file_type, sbin_t類型的file進行可執行檔操作
allow user_t user_t:process signal;
allow user_t self:process signal;
這兩條語句的表述其實是一致的,其實self指的是目標的類型和發起人的類型是一致的
所以不能聲明一個類型或者屬性叫做self
allow user_t bin_t:file ~{ write setattr ioctl };
允許user_t對bin_t類型的file進行除了write setattr ioctl相關的操作
type_transition system wifi_data_file:sock_file system_wpa_socket;
當一個類型為system的類別去進行wifi_data_file類型的sock_file訪問時,類型預設切換到system_wpa_socket
如果下面這條語句想要執行成功
type_transition init_t apache_exec_t:process apache_t;
至少首先聲明下面的三條規則:
allow init_t apache_exec_t:file execute;
allow init_t apache_t:process transition;
allow apache_t apache_exec_t:file entrypoint;
type_transition和type_change的文法規則是一樣的, type_change規則的影響不會在核心中生效,而是依賴於使用者空間應用程式,如login或sshd
android中SELINUX規則分析和文法簡介