SELinux policy相關問題的總結

在開發Android系統的時候或多或少遇到一些Selinux的相關的問題,在這裏進行一些總結和整理,內容大部分來源網絡.

1、瞭解SELinux基本概念,這個網上資料很多,具體參考:

http://jingpin.jikexueyuan.com/article/55398.html
http://blog.csdn.net/innost/article/details/19299937/ 
http://blog.csdn.net/luoshengyang/article/details/37613135 
http://www.2cto.com/kf/201504/390742.html 
http://www.th7.cn/system/lin/201512/147098.shtml 

2、確認Selinux的狀態

2.1 可以通過手動關閉selinux,確認問題是否是權限引起的,具體方法: 
查看SELinux狀態: 
1) /usr/sbin/sestatus -v      ##如果SELinux status參數爲enabled即爲開啓狀態 
SELinux status:                 enabled 
2) getenforce                 ##也可以用這個命令檢查 

2.2 關閉SELinux: 
臨時關閉(不用重啓機器): 
setenforce 0                  ##設置SELinux 成爲permissive模式 
                              ##setenforce 1 設置SELinux 成爲enforcing模式 

3、抓dmesg log,轉換出系統缺少的policy 

dmesg log: 
dmesg | grep rpcServer 
[ 8.132704] init: Starting service 'rpcServer'... 
[ 12.936186] type=1400 audit(1449623772.120:13): avc: denied { read } for pid=174 comm="rpcServer" name="mmcblk0p1" dev="tmpfs" ino=8105 scontext=u:r:rpcServer:s0 tcontext=u:object_r:block_device:s0 tclass=blk_file permissive=0 
比如上面這個log,你需要能清楚這句話的意思:原進程(scontext)需要目標(tcontext)進程tclass屬性的read權限 
我們可以通過ls -Z、ps -Z、ls -l等查看具體設備文件相關屬性 

4、如何添需要的權限(這個可以分3類來處理)

1)第一類比較簡單,通過audit2allow等工具轉換出對應模塊缺少的policy(.te文件) 
添加到sepolicy/rpcServer.te:
allowrpcServer block_device:blk_file read ;  分別對應上面的allow scontext tcontext:tclass   read 

2)第二類,有一些policy加進來,編譯的時候系統會報錯,原因是我們上面轉換的policy一般都是某個進程對所以的的設備文件具有相關權限,這個權限過大,會和google的安全策略(external/sepolicy下neverallow)想衝突。這種情況下,我們需要找出原進程究竟需要哪個具體的設備文件的相關權限,就可以解決 
添加: 
先在sepolicy/file_contexts定義mmcblk0p1 設備節點:/dev/block/mmcblk0p1 u:object_r:rpc_block_device:s0 
在sepolicy/rpcServer.te添加該設備節點的權限:allow rpcServer rpc_block_device:blk_file read; 

3)

原進程的屬性(root、radio、system等)與目標設備文件的屬性不匹配,這種情況下我們映射會不起作用。這樣的話,需要在init.rc 和ueventd.rc裏面修改相應的屬性:
我這邊例子是查下來問題原因: 
vmodem driver is not able openthe NVM partitions so default NVM values are expected. Issue is with permissionmis-match: 
vmodem driver context is “radio”and block device nodes are “root” 
由於mmcblk0p1是modem使用的Nvm Calculate Static,rpcServer無權限掛載,先將rpcServer和設備mmcblk0p1都設置設置成一樣的radio屬性: 
ueventd.rc文件中: 
/dev/block/mmcblk0p1 0660 radio radio 
/dev/vmodem 0660 radio radio 
init.rc和init.ptest.rc文件中,system/bin/rpcServer 的user、group的root屬性改成radio: 
chown radio radio /sys/class/misc/vmodem/modem_state 
service rpcServer /system/bin/rpcServer 
socket msmSock stream 660 system radio 
class core 
user radio 
group radio 
然後添加kernel和rpcServer對mmcblk0p1 設備的權限: 
在sepolicy/file_contexts定義mmcblk0p1 設備節點:/dev/block/mmcblk0p1 
u:object_r:rpc_block_device:s0 
在sepolicy/kernel.te:allowkernel rpc_block_device:blk_file read; 
在sepolicy/rpcServer.te:allow 
rpcServer rpc_block_device:blk_file read; 

其中上面兩種情況解決套路是一樣的,而第三種,需要根據不同的平臺,對應的設備和進程屬性來具體分析。以下是在本地添加一個服務,因selinux的原因導致無法運行,如下:

1、在init.rc 中添加:

service xxx /system/bin/xxx 
    class main 
    user root 

編譯boot後燒到機器中,發現服務xxx無法啓動,kernel log中有如下提示:
[   20.076354s][pid:1,cpu7,init]init: Service xxx does not have a SELinux domain defined. 

該提示說明沒有定義SELinux domain,導致服務xxx無法自啓動。爲了解決這個問題我們按如下方式修改或添加sepolicy文件:

修改seplicy/file_contexts文件,添加以下內容: 
/system/bin/xxx     u:object_r:xxx_exec:s0 
新增xxx.te文件,並在其中添加如下內容: 
需要爲新增的進程增加域、執行權限 
type xxx, domain; 
type xxx_exec, exec_type, file_type; 
然後啓用這個域 
init_daemon_domain(xxx) 
驗證,原則上修改SELinux的問題需要全編譯,爲了節省時間可以使用以下方法調試 
編譯bootimage 
燒錄bootimage 
執行adb remount 
執行adb shell restorecon system/bin/xxx 
重啓機器,看是否在kernel log中是否成功啓動xxx服務
 

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