android中SELINUX规则分析和语法简介
1. SELINUX是可以理解為一種android上面的安全機制,是有美國國家安全局和一些公司設計的一個針對linux的安全加強系統(tǒng)
我們可以通過配置SELINUX的相關policy,來定制自己的手機的一些權限,比如,我們可以完全讓root用戶沒有任何的權限和user一樣
2. 在android里面,有兩個類型,一種是文件,一種是進程。
針對這兩種類型,我們可以先來看看他們的不同。
在android上面,adb shell之后進入手機,ps -Z可以查看當前進程所擁有的selinux的權限。
舉例:
?
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
在這個例子中,我們可以進行分析。
在android中,只定義了一個user即為u. 另外,如果是進程的話,都會統(tǒng)一定義為r,如果是文件的話,會被定義為object_r. 第三個是這個進程type,在andorid里面,定義了100多個type.按照目前我的理解,這個是進程所屬的>類型。第四個是s0,這個是一個安全的等級。但是暫時還沒有接觸到配置這個的地方。
另外就是文件,文件想要查看相關SELINUX權限的話,需要去執(zhí)行l(wèi)s -Z
?
|
1 2 3 4 5 6 7 8 |
|
在這個例子中,結合上面的分析,我們知道了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
然后將規(guī)則添加到了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. )
然后理解了這個之后,我們可以看到其實很多的廠商也是有自己的配置規(guī)則在device/***/***/sepolicy下面的.
4. selinux的配置規(guī)則:
首先要了解sepolicy的結構:
a. App進程 -> mac_permissions.xml
b. App數(shù)據(jù)文件 -> seapp_contexts
c. 系統(tǒng)文件 -> file_contexts
d. 系統(tǒng)屬性 -> property_contexts
在te文件中,我們一般遇到的語法是這樣的:
rule_name source_type target_type:class perm_set
解讀為: 為source_type設置一個rule_name的規(guī)則,規(guī)則是對target_type的class 進行 perm_set的操作。
然后是一些特殊的配置文件:
a. external/sepolicy/attributes -> 所有定義的attributes都在這個文件
b. external/sepolicy/access_vectors -> 對應了每一個class可以被允許執(zhí)行的命令
c. external/sepolicy/roles ->Android中只定義了一個role,名字就是r,將r和attribute domain關聯(lián)起來
d. external/sepolicy/users -> 其實是將user與roles進行了關聯(lián),設置了user的安全級別,s0為最低級是默認的級別,mls_systemHigh是最高的級別
e. external/sepolicy/security_classes -> 指的是上文命令中的class,個人認為這個class的內容是指在android運行過程中,程序或者系統(tǒng)可能用到的操作的模塊
f. external/sepolicy/te_macros -> 系統(tǒng)定義的宏全在te_macros文件
g. external/sepolicy/***.te -> 一些配置的文件,包含了各種運行的規(guī)則
另外,selinux有兩種工作模式:
“permissive”:所有操作都被允許(即沒有MAC),但是如果有違反權限的話,會記錄日志
“enforcing”:所有操作都會進行權限檢查
最后,type的命令如下:
type type_id [alias alias_id,] [attribute_id] # 將type_id(別名為alias)關聯(lián)到attribute. 這樣的話,方便用attribute來管理不同的type中包含相同的屬性的部分。
class命令的格式為:
class class_name [ inherits common_name ] { permission_name ... }
inherits表示繼承了common定義的權限,然后自己額外實現(xiàn)了permission_name的權限
在te文件中常見的四種命名的規(guī)則:
allow:賦予某項權限。
allowaudit:audit含義就是記錄某項操作。默認情況下是SELinux只記錄那些權限檢查失敗的操作。allowaudit則使得權限檢查成功的操作也被記錄。注意,allowaudit只是允許記錄,它和賦予權限沒關系。賦予權限必須且只能使
用allow語句。
dontaudit:對那些權限檢查失敗的操作不做記錄。
neverallow:前面講過,用來檢查安全策略文件中是否有違反該項規(guī)則的allow語句。如例子5所示:
舉例:
?
| 1 |
|
將init關聯(lián)到domain,即將domain設置為init類型的屬性
?
| 1 |
|
允許init類型對unlabeled類型的filesystem進行mount的操作
?
| 1 |
|
允許init類型對fotad類型的unix_stream_socket 進行bind和create的操作
?
|
1 2 |
|
首先appdomain是定義在te_macros里面的一個宏,很多的app規(guī)則會使用類似app_domain(shell)的命令將其添加進去
這兩句話的意思是:1. 允許app去對anr_data_file類型的目錄進行查找的操作
2. 允許app對anr_data_file類型的file進行打開和添加操作 其實就是規(guī)定了出現(xiàn)anr時候,app往/data/anr/里面寫入的權限限制
?
| 1 |
|
絕對不允許app(除了有unconfineddomain屬性的app)對kmem_device類型的字符設備進行讀寫的操作
?
| 1 |
|
絕對不允許除了unconfineddomain以外的app對self類型的capability2進行任何的操作
?
| 1 |
|
聲明一個httpd_user_content_t的類型,具有file_type和httpdcontent的屬性
?
|
1 2 |
|
聲明一個httpd_user_content_t的類型
定義httpd_user_content_t具有file_type, httpdcontent的屬性
?
| 1 |
|
所有可以設置類型的地方其實都可以設置為屬性。
比如這個例子,我們允許所有具有app屬性的內容可以去對self屬性的rawip_socket進行create的操作
?
| 1 |
|
允許user_t和domain屬性的類對bin_t, file_type, sbin_t類型的file進行可執(zhí)行的操作
?
|
1 2 |
|
這兩條語句的表述其實是一致的,其實self指的是目標的類型和發(fā)起人的類型是一致的
所以不能聲明一個類型或者屬性叫做self
?
| 1 |
|
允許user_t對bin_t類型的file進行除了write setattr ioctl相關的操作
?
| 1 |
|
當一個類型為system的類別去進行wifi_data_file類型的sock_file訪問時,類型默認切換到system_wpa_socket
如果下面這條語句想要執(zhí)行成功
type_transition init_t apache_exec_t:process apache_t;
至少首先聲明下面的三條規(guī)則:
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的語法規(guī)則是一樣的, type_change規(guī)則的影響不會在內核中生效,而是依賴于用戶空間應用程序,如login或sshd
Android SeLinux權限問題和解決方法
1. 確認 seLinux導致權限問題
1.1 標志性log 格式:
avc: denied { 操作權限} for pid=7201comm=“進程名” scontext=u:r:源類型:s0 tcontext=u:r:目標類型:s0 tclass=訪問類別 permissive=0
1.2 舉例:
Kenel log:
avc: denied { execheap } for pid=7201 comm="com.baidu.input" scontext=u:r:untrusted_app:s0tcontext=u:r:untrusted_app:s0tclass=processpermissive=0
Logcat log:
com.baidu.input:
type=1400audit(0.0:29): avc: denied { execheap } for
scontext=u:r:untrusted_app:s0tcontext=u:r:untrusted_app:s0tclass=processpermissive=0
1.3 方法1:adb在線修改
關閉 seLinux:
打開seLinux:
Enforcing:seLinux已經(jīng)打開;
Permissive:seLinux已經(jīng)關閉;
1.4 方法2: 從kernel中徹底關閉 (用于開機初始化時的seLinux權限問題,要重編bootimage)
修改LINUX/android/kernel/arch/arm64/configs/XXXdefconfig文件(找相應config文件)
去掉CONFIG_SECURITY_SELINUX=y 的配置項
2. 在sepolicy中添加相應權限
2.1 修改依據(jù):
log 信息:
avc: denied { 操作權限 } for pid=7201 comm=“進程名” scontext=u:r:源類型:s0 tcontext=u:r:目標類型:s0
tclass=訪問類別 permissive=0
2.2 修改步驟:
找相應的“源類型.te ”文件
有兩個位置可能存在相應的te文件:
位置一:LINUX/android/external/sepolicy
位置二:LINUX/android/device/qcom/sepolicy/common
2.3 按如下格式在該文件中添加:
allow 源類型 目標類型:訪問類別 {權限};
2.4 舉例
Kernel Log:
avc: denied { execheap } for pid=7201
comm="com.baidu.input"
scontext=u:r:untrusted_app:s0tcontext=u:r:untrusted_app:s0tclass=processpermissive=0
修改:
在LINUX/android/external/sepolicy/untrusted_app.te 中添加:
allow untrusted_app untrusted_app:process { execheap };
備注:
在這個例子中,由于源類型和目標類型都是untreated_app, 所以也可以寫成:
allow untrusted_app self:process { execheap };
3. 添加權限后的neverallowed沖突
3.1 編譯報錯:
libsepol.check_assertion_helper: neverallow on line xxx ofexternal/sepolicy/domain.te ……
3.2 原因:
新添加的sepolicy項目違反了domain.te 中規(guī)定的的總策略原則。所以該條權限策略不能添加,如果強行添加的話有CTS測試失敗的風險。
3.3 解決方法:
1.從運行l(wèi)og中找到要訪問的目標名稱,一般是name字段后的名稱
avc: denied { read write } for pid=303 comm="mediaserver" name="tfa9890"dev="tmpfs" ino=3880 scontext=u:r:mediaserver:s0tcontext=u:object_r:device:s0tclass=chr_file permissive=0
2.找到相應的*_contexts文件。
一般有file_contexts,genfs_contexts, property_contexts, service_contexts 等文件
3.在contexts文件中指定要訪問的目標為一個“源類型 ”有權限訪問的“目標類型”
如:在file_contexts中添加: /dev/tfa9890u:object_r:audio_device:s0
3.4 舉例
添加權限:
在mediaserver.te中添加allow mediaserver device:chr_file { read write open};
編譯報錯:
libsepol.check_assertion_helper:
neverallow on line 258 ofexternal/sepolicy/domain.te (or line 5252 of
policy.conf) violated byallow mediaserver device:chr_file { read write
open};
違反了domain.te 258的:
neverallow {domain –unconfineddomain –ueventd } device:chr_file { open read write}
運行Log:
avc: denied { read write } for pid=303
comm="mediaserver"name="tfa9890" dev="tmpfs" ino=3880
scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0tclass=chr_file
permissive=0
修改步驟:
1.目標名稱是: tfa9890, 其在系統(tǒng)中的路徑是: /dev/tfa9890, 是audio相關的設備文件
2.源類型是mediaserver, 在mediaserver.te 文件中發(fā)現(xiàn)其具有 audio_device 目標類型的權限
3.所以在file_contexts 中添加 “/dev/tfa9890 u:object_r:audio_device:s0” 可以解決問題0
userdebug_or_eng關鍵字可以限定版本,例如:
userdebug_or_eng(`
allow system_app sysfs_battery_supply:dir search;
allow system_app sysfs_battery_supply:file {read open getattr};
allow system_app sysfs_usb_supply:dir search;
allow system_app sysfs_usb_supply:file {read open getattr};
allow system_app sysfs:file {read write open getattr};
allow system_app sysfs_leds:dir search;
allow system_app sysfs_leds:file write;
allow system_app system_data_file:file {write create setattr};
allow system_app system_data_file:dir {write add_name};
allow system_app vendor_audioftm_exec:file {getattr execute read open execute_no_trans};
allow system_app vendor_default_prop:file {read open getattr};
allow system_app proc_asound:dir search;
allow system_app proc_audiod:file {read write open getattr execute};
allow system_app audio_device:chr_file { read write open ioctl };
allow system_app audio_device:dir { search };
allow system_app proc:file { read open getattr };
allow system_app vendor_file:file {read open};
allow system_app sysfs_graphics:file rw_file_perms;
allow system_app sysfs_graphics:dir search;
allow system_app vendor_gles_data_file:dir search;
allow system_app vendor_camera_prop:file { read open getattr };
')
userdebug_or_eng(`permissive ft_diag;') //打開ft_diag在userdebug或者eng版本上的所有關于se_Android的權限
內置一個腳本,調用該腳本時不成功,需要在file_contexts中定義該腳本的類型,然后在其他程序的te文件中加入對該腳本的執(zhí)行權限。
1. device/xxx/common/sepolicy/file_contexts 添加
/system/bin/preinstall.sh u:object_r:preinstall_exec:s0
要添加該腳本對其他的權限
2.創(chuàng)建device/amlogic/common/sepolicy/preinstall.te
type preinstall, domain;
type preinstall_exec, exec_type, file_type;
3.init.rc添加腳本運行服務
service preinstall /system/bin/preinstall.sh
user root
group root
disabled
oneshot
seclabel u:r:preinstall:s0
解決seAndroid權限,可以適用audit2allow工具
作用:可以根據(jù)avc錯誤日志自動生成需要添加te權限
目錄:external/selinux/prebuilts/bin/
適用條件:依賴libselinux.so庫,所以需要代碼全編譯完成才可以用
適用方法:將avc錯誤日志拷貝到文本文檔中,執(zhí)行命令:audit2allow –i test.txt >test.te
分析過程:
缺少什么權限: { write }權限,
誰缺少權限: scontext=u:r:kernel:s0,
對哪個文件缺少權限:tcontext=u:object_r:block_device
什么類型的文件: tclass=blk_file
解決方法:kernel.te
allow kernel block_device:blk_file write;
對于類型文件可以在system/sepolicy/public/global_macros來查看
.text-only, .text-card-text { white-space: pre }
.rich-text-paragraph { min-height: 15px }
總結
以上是生活随笔為你收集整理的android中SELINUX规则分析和语法简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 深度学习之卷积神经网络(3)卷积层实现
- 下一篇: Mac连接局域网Windows共享打印机