作者 | 趙青窕
審校 | 孫淑娟
經過數日的分析,我才明白關閉權限僅僅是關閉安卓權限中的一部分而并非所有權限,最終通過修改文件屬性后,我的服務才可以正常啟動了。經歷這件事情后,我立志要把我的經驗總結出來并分享給志同道合的朋友們。

根據我個人的工作經驗,我把安卓權限分為如下三部分:
- 設置文件的屬性
- 采用allow語句配置某一個應用訪問某一個文件的權限
- Linux系統原生的用戶,用戶組權限
第1點和第2點屬于SELinux的范疇,這兩部分是相輔相成的關系,通過設置文件屬性來配置某一文件是不是可執行文件,緊接著我們可以采用allow語句來配置該可執行文件可以訪問的文件資源及其對文件資源的操作權限;第3點屬于Linux這一類系統的共同特性,于前面兩點是完全不同的部分,用戶和用戶組及權限用來說明某一文件所屬的用戶和用戶組,及其讀寫執行權限。接下來,讓我們先認識SELinux,然后再詳細地看上面三部分。
SELinux相關命令
- 關閉SELinux權限:setenforce 0,即設置SELinux 成為permissive模式,對違反Selinux規則的行為會進行記錄,但不會阻止。
- 打開SELinux權限:setenforce 1,即設置SELinux 成為enforcing模式,對違反Selinux規則的行為會進行記錄,且會進行阻止。
- 獲取SELinux權限:getenforce
下圖1是上面三個命令的執行情況,供大家參考。

圖 1 :SELinux命令演示
- 查看SELinux權限:命令參數中增加-Z(注意此處是大寫字母)選項。
如果是查看文件,則采用圖2中紅色方框內的方式。

圖 2:查看文件權限
如果是查看進程的權限,則可以采用圖2中所說的方式。圖2中列出了不查看權限和查看權限的方式,方便大家比較。

圖 3:查看進程對應的SELinux權限
下圖4是查看屬性(property)權限的命令。

圖 4:查看property權限
配置SELinux權限
在此,我通過一個例子來說明如何配置。假如我們有一個可執行文件,我們用test_bin表示,該可執行文件需要訪問我們的驅動節點/dev/test,針對這種情況,我們需要配置4處。
1.file_contexts中對文件/dev/test進行配置,配置方法如下(先假設test_dev_node和
test_bin_exec已經定義了,后面會進行說明):
est_bin_exec已經定義了,后面會進行說明):
/dev/test u:object_r:test_dev_node:s0
test_bin(此處需要使用test_bin的絕對路徑) u:object_r:test_bin_exec:s0
該配置語句的意思就是把我們的設備節點/dev/test配置為test_dev_node類型,可執行文
件test_bin配置為test_bin_exec的類型,其余部分也有其具體含義,只是對于使用者來
說,暫時可以忽略。在具體項目配置時,替換上面配置文件中標出來的內容即可。
2.配置對應的te文件
type test_dev_node, dev_type;
type test_bin_exec, exec_type, vendor_file_type, file_type;
allow test_bin_exec test_dev_node:chr_file rw_file_prems;
上面三條語句主要完成兩種工作,分別是類型定義和allow語句,這兩部分都比較重要,
類型定義好后,我們才能對資源進行相應類型的配置,如上面對/dev/test和test_bin的配
置,而allow語句就是配置我們常說的權限問題,上面的allow語句就是設置類型為
test_bin_exec的可執行程序可以訪問test_dev_node類型的文件。我把這個過程總結為定
義類型---配置類型----設置權限。
除了上面涉及到的內容外,安卓系統中還具有property_contexts,service_contexts,
seapp_contexts等類型。不管什么類型,我們套用三步驟定義類型---配置類型----設置權限即可,并結合需要處理的文件類型,就可以完成權限配置,如屬性類文件,定義類型時,其語句格式是type xxx property_type,倘若還是不知道如何定義,可以參考安卓基線代碼中的SELinux定義,因為基線中的權限定義已經包含了盡可能全的情況。
當遇到neverallow問題時,我們就把出現問題部分按照上面三步驟定義類型---配置類型----設置權限進行重新定義,重新定義后的類型名稱不在系統的nerverallow范疇內,再次重新設置后就可規避nerverallow問題。
至此,我們已經簡單了解了SElinux問題,接下來重新思考一下文章開始的時候說的三大部分。
1.設置文件的屬性
此處就是指上面在file_contexts對文件/dev/test和test_bin進行了屬性配置,當我們關閉SELinux權限時,并不能關閉系統對文件屬性的判斷,比如當我們沒有對test_bin進行配置時,安卓系統會認為test_bin是一個普通文件。這種情況下,不管SELinux是否關閉,test_bin都無法正常運行。請記住,關閉SELinux時,安卓系統仍然會判斷文件屬性。
2.allow語句
當系統中沒有配置適當的allow語句,但配置了適當的文件屬性和用戶組屬性,讀寫權限時,此時關閉SELinux就可以正常工作。若出現這種現象,說明就是因為allow語句配置不恰當,這個時候應該趕緊抓取對應的日志,從對應的log中過濾出AVC的日志,如下是一種AVC錯誤:
avc: denied { read } for name="vendor" dev="tmpfs" ino=9241 scontext=u:r:dumpstate:s0 tcontext=u:object_r: test_dev_node:s0 tclass=chr_file permissive=0
分析如下:
- 上面日志中的中括號中表示缺少的權限,從日志看缺少read全校;
- scontext=u:r:dumpstate:s0用來表示缺少權限;
- tcontext=u:object_r: test_dev_node:s0用來表示訪問哪類文件時出現了權限問題;
- tclass=chr_file表示要訪問的文件類型。
我們把上面四部分按照下面組合即可添加對應的權限:
allow dumpstate test_dev_node:chr_file r read;
3.用戶,用戶組和讀寫權限
這類權限是Linux這一類系統中原生的內容,這類權限與SELinux完全不相關。當用戶組配置有問題時,即使關閉SELinux權限,其問題會依然存在。
那在安卓系統中,我們如何來進行該類權限的配置呢?其實在安卓中,有一類init.rc文件(文件名可以是init.rc或者init.xxx.rc),rc文件除了可以同來啟動服務等功能外,還可以在該類文件中配置用戶和用戶組讀寫權限,如下面的例子所示:
on init
chmod 0660 /dev/test
chown system system /dev/test
總結
本文先簡單介紹了SELinux,然后進行三大部分的說明。這三部分有任何一部分異常,其對應功能都無法正常工作。在配置安卓權限時,需要從這三部分來考慮,缺一不可,最重要的一點是,關閉SELinux,僅僅能屏蔽allow語句對應的權限問題。
作者介紹
趙青窕,51CTO社區編輯,從事多年驅動開發。研究興趣包含安全OS和網絡安全領域,發表過網絡相關專利。




























