linux通過UID/GID機制對權(quán)限進行管理,將文件的權(quán)限劃分為讀、寫和執(zhí)行三種,分別用字母r、w和x表示。每一個文件有三組讀、寫和執(zhí)行權(quán)限,分別是針對“文件的所有者”、“文件所有者所屬的組”以及其它用戶。
在linux系統(tǒng)中,我們想完全操作某個文件,只需要執(zhí)行sudo chmod 777 filename 即可。這表示root用戶擁有無限大的權(quán)限,可以操作系統(tǒng)中的任何文件。
所以在安卓系統(tǒng)中,引入了SELinux用以提升系統(tǒng)安全性。
一、常用命令
SELinux模式有三種,Enforcing強制模式、Permissive寬容模式與Disabled完全禁用。
區(qū)別是Enforcing強制模式中,SELinux是起作用,而Permissive寬容模式SELinux不起作用,僅輸出權(quán)限拒絕日志。
查看SELinux模式命令:getenforce
更改SELinux模式命令:setenforce 1 設(shè)置為Enforcing
setenforce 0 設(shè)置為Permissive
安卓中快速編譯sepolicy并驗證,需要本地代碼整編過一次,已經(jīng)生成out目錄之后。(這里我遇到一個問題,這樣編過幾次之后,再去整編的時候就會報image out of space的錯誤,暫時不知道原因。)
$ mmma system/sepolicy/
$ adb push out/target/product/xxx/system/etc/selinux /system/etc/selinux
$ adb push out/target/product/xxx/vendor/etc/selinux /vendor/etc/selinux
也可單編systemimage,并刷機
$ make systemimage
$ adb reboot bootloader
$ fastboot flash system ./system.img
$ fastboot reboot
二、SELinux基本概念
1、如何配置SEpolicy
在分析安卓系統(tǒng)問題看日志時,會有同學好奇以下日志的含義:
05-25 18:51:22.421 7419 7419 W logcat : type=1400 audit(0.0:1319):
avc: denied { write } for name="syslog"
dev="mmcblk0p87" ino=31476 scontext=u:r:logpersist:s0
tcontext=u:object_r:system_data_file:s0 tclass=dir permissive=0
這是linux的審計信息,簡單的來說該日志可以理解為:logpersist想要訪問system_data_file的dir目錄,缺少了write寫權(quán)限。
這是因為SELinux權(quán)限限制了,通過配置sepolicy即可通過。
如果想要簡單配置sepolicy權(quán)限,則需要在logpersist.te文件下,設(shè)置以下allow:
allow logpersist system_data_file:dir write;
但當加上“allow”語句之后,編譯會報錯,這是因為谷歌設(shè)置了neverallow,不允許我們針對“l(fā)ogpersist”與“system_data_file”添加allow語句。
為了解決這一問題,更加詳細的了解一下SELinux。
2、了解
SEAndroid安全機制中的安全策略就是在“安全上下文”的基礎(chǔ)上進行描述的, 它通過主體和客體的安全上下文,定義主體是否有權(quán)限訪問客體。
以上述日志舉例,主體 scontext就是u:r:logpersist:s0,客體tcontext是u:object_r:system_data_file:s0。該錯誤日志表示主體沒有對客體的write權(quán)限,其中tclass=dir表示客體的類型為文件夾。
- Domain:u:r:logpersist:s0是一個“域”,它是一個進程或一組進程的標簽。
- Type:u:object_r:system_data_file:s0是一個“對象標簽”,它是一個對象或一組對象的標簽。
- Class:dir 是客體的類型。(dir是文件夾,file是文件...)
- Permission:write 是缺少的權(quán)限。
以下語句表示,允許“l(fā)ogpersist進程”對所屬“system_data_file”的文件件類型為文件夾“dir”進行“write”操作。
allow logpersist system_data_file:dir write;
3、安全上下文
安全上下文由“SELinux用戶”、“SELinux角色”、“類型”、“安全級別” 四部分組成,格式為“user:role:type:sensitivity”。
進程的安全上下文:用戶固定為 u,角色固定為 r。如:u:r:logpersist:s0
文件的安全上下文:用戶固定為 u,角色固定為 obejct_r。如:u:object_r:system_data_file:s0
安全級別:可以選擇啟用或者不啟用,通常在進程及文件的安全上下文中安全級別都設(shè)置為s0。
進程的安全上下文的類型稱為Domain,文件的安全上下文中的類型稱為Type。
三、如何應(yīng)對neverallow
在system/sepolicy/private/logpersist.te與system/sepolicy/prebuilts/api/29.0/private/logpersist.te中配置以下allow語句并編譯,會報neverallow的錯。
allow logpersist system_data_file:dir write;
這表示谷歌不允許我們使用allow語句,解除限制的最暴力方法就是將報錯處的neverallow語句刪掉,這樣確實可行,但是會過不了cts。
由于我們要訪問的目錄path為/data/syslog,將該目錄定義成自己的Type
可以自定義Type,如下:
在file.te中自定義一個type為file_type,data_file_type,core_data_file_type:(應(yīng)該只需要定義為file_type即可,我沒有測試:)
type log_data_file, file_type, data_file_type, core_data_file_type;
在file_contexts中定義安全上下文:
/data/syslog(/.*)? u:object_r:log_data_file:s0
將allow語句改為:
allow logpersist log_data_file to write;
然后在logpersist.te中單獨將自定義的log_data_file減去即可。(這里最好的是自定義一個service代替logpersist,那就要新建一個te文件了,比較麻煩)
neverallow logpersist {
file_type
userdebug_or_eng(`-misc_logd_file -coredump_file')
with_native_coverage(`-method_trace_data_file')
-log_data_file
}:file { create write append };
四:參考文獻
1:https://blog.csdn.net/weixin_42082222/article/details/85239018
2:https://blog.csdn.net/ch853199769/article/details/82498725
3:https://blog.csdn.net/weixin_42082222/article/details/85239018