selinux 記錄

SEPolicy 語言:
    Linux中有兩種東西,一種死的(Inactive),一種活的(Active)。死的東西就是文件(Linux哲學,萬物皆文件。注意,萬不可狹義解釋爲File),而活的東西就是進程。此處的 死 和 活 是一種比喻,映射到軟件層面的意思是:進程能發起動作,例如它能打開文件並操作它。而文件只能被進程操作。

    根據 SELinux 規範,完整的 Secure Context 字符串爲:user:role:type[:range]

進程的 Secure Context:
    在 SELinux 中,每種東西都會被賦予一個安全屬性,官方說法叫做 Security Context,Security Context是一個字符串,主要由三個部分組成,例如 SEAndroid 中,進程的 Security Context 可通過 ps -Z 命令查看:

    上面的最左邊的一列就是進程的 Security Context,以第一個進程 wpa_supplicant 爲例
        u:r:hal_wifi_supplicant_default:s0
    其中 
    - u 爲 user 的意思,SEAndroid 中定義了一個 SELinux 用戶,值爲 u 
    - r 爲 role 的意思,role 是角色之意,它是 SELinux 中一個比較高層次,更方便的權限管理思路。簡單點說,一個 u 可以屬於多個 role,不同的 role 具有不同的權限。 
    - hal_wifi_supplicant_default 代表該進程所屬的 Domain 爲 hal_wifi_supplicant_default。MAC(Mandatory Access Control)強制訪問控制 的基礎管理思路其實是 Type Enforcement Access Control(簡稱TEAC,一般用TE表示),對進程來說,Type 就是 Domain,比如 hal_wifi_supplicant_default 需要什麼權限,都需要通過 allow 語句在 te 文件中進行說明。 
    - s0 是 SELinux 爲了滿足軍用和教育行業而設計的 Multi-Level Security(MLS)機制有關。簡單點說,MLS 將系統的進程和文件進行了分級,不同級別的資源需要對應級別的進程才能訪問

文件的 Secure Context:
    文件的 Secure Context 可以通過 ls -Z 來查看,如下

    ls libOMX_Core.so -Z
    u:object_r:vendor_file:s0 libOMX_Core.so

    u:同樣是 user 之意,它代表創建這個文件的 SELinux user
    object_r:文件是死的東西,它沒法扮演角色,所以在 SELinux 中,死的東西都用 object_r 來表示它的 role
    vendor_file:type,和進程的 Domain 是一個意思,它表示 libOMX_Core.so 文件所屬的 Type 是 vendor_file
    s0:MLS 的等級


根據 SELinux 規範,完整的 SELinux 策略規則語句格式爲:
    allow domains types:classes permissions;

    - Domain - 一個進程或一組進程的標籤。也稱爲域類型,因爲它只是指進程的類型。
    - Type - 一個對象(例如,文件、套接字)或一組對象的標籤。
    - Class - 要訪問的對象(例如,文件、套接字)的類型。
    - Permission - 要執行的操作(例如,讀取、寫入)。

    = allow : 允許主體對客體進行操作
    = neverallow :拒絕主體對客體進行操作
    = dontaudit : 表示不記錄某條違反規則的決策信息
    = auditallow :記錄某項決策信息,通常 SElinux 只記錄失敗的信息,應用這條規則後會記錄成功的決策信息。

    使用政策規則時將遵循的結構示例:

    語句:
    allow appdomain app_data_file:file rw_file_perms;

    這表示所有應用域都可以讀取和寫入帶有 app_data_file 標籤的文件
    
    
SELinux 權限不足 avc-denied 問題解決:
    目前所有的 SELinux 權限檢測失敗,在 Kernel Log 或者 Android Log 中都有對應的 avc-denied Log 與之對應。反過來,有 avc-denied Log,並非就會直接失敗,還需要確認當時 SELinux 的模式, 是 Enforcing 還是 Permissve。

    如果是 Enforcing 模式,就要檢測對應的進程訪問權限資源是否正常?是否有必要添加? 如果有必要添加,可以找下面的方式生成需要的 sepolicy 規則並添加到對應 te 文件。

    使用 audit2allow 簡化方法 
    從 logcat 或串口中提取相應的 avc-denied log,下面的語句爲提取所有的 avc- denied log
    $ adb shell "cat /proc/kmsg | grep avc" > avc_log.txt 
    使用 audit2allow 工具生成對應的 policy 規則
    // audio2allow 使用必須先 source build/envsetup.sh,導入環境變量
    $ audit2allow -i avc_log.txt -p $OUT/vendor/etc/selinux/precompiled_sepolicy
    將對應的policy 添加到 te 文件中
        = 一般添加在 /device/<company>/common/sepolicy 或者 /device/<company>/$DEVICE/sepolicy 目錄下

    BOARD_SEPOLICY_DIRS += device/$SoC/common/sepolicy 通過這個命令添加廠家自定義的 sepolicy 規則


--------------------------------------------------------------------------------    
file_contexts //系統中所有file_contexts安全上下文
seapp_contexts //app安全上下文
property_contexts //屬性的安全上下文
service_contexts    //service文件安全上下文
genfs_contexts //虛擬文件系統安全上下文
以上文件system/sepolicy中都有對應的內容

在Android8.0以上,SELinux策略分離成平臺(platform)和非平臺(non-platform)兩部分,
而平臺策略爲了給非平臺作者導出特定的類型和屬性,又分爲平臺私有(platform private)和平臺公有(platform public)部分。

1.平臺公有策略(platform public seoplicy)平臺共有策略全部定義在/system/sepolicy/public下,public下的type和attribute可以被non-platform中的策略所使用,也就是說,設備製造商的sepolicy作者在non-platform下可以對platform public sepolicy的策略進行擴展。
2.平臺私有策略(platform private seoplicy)與公有策略相反,被聲明爲私有策略的type或attribute對non-platform的策略作者是不可見的。
-------------------------------------------------------------------------------


怎麼抓取SELinux Log?
1.adb shell dmesg----抓kernel log
(特別說明:adb shell "cat /proc/kmsg | grep avc" > avc_log.txt  可以直接提出avc的log)
2.adb logcat –b events
關鍵字:
avc: denied
修改之後,怎麼快速驗證?
方法一:
mmm system/sepolicy
生成out目錄下,注意有兩個目錄:
system/etc/sepolicy---Android 原生的,建議不動。如果修改,會影響CTS
vendor/etc/sepolicy---第三方廠家修改。
特別說明:system/sepolicy/Android.mk中定義了一些屬性
BOARD_SEPOLICY_DIRS  ##此宏涉及到的目錄,會編譯到vendor/etc/sepolicy下
PLAT_PUBLIC_POLICY ##此宏涉及到的目錄,會當成system/sepolicy/public
PLAT_PRIVATE_POLICY##此宏涉及到的目錄,會當成system/sepolicy/private
另外,單獨編譯後,會發現都會有對應的生成目錄
    /out/target/product/xxx/vendor/etc/selinux/
        vendor_file_contexts
        vendor_property_contexts
        vendor_sepolicy.cli   //allow語句會生成到這裏面

方法二:
make sepolicy
怎麼從log中提取有效信息?
舉例1
    <36>[  103.972283] c0    484 type=1400 audit(1536907169.826:34): avc: denied { read } for pid=2591 comm="roid.qh_engmode" name="printk" dev="proc" ino=35544 scontext=u:r:radio:s0 tcontext=u:object_r:proc:s0 tclass=file permissive=0
普通提取:
allow radio proc:file read;
關鍵字:
avc: denied { read }  scontext=u:r:radio:s0 tcontext=u:object_r:proc:s0  tclass=file
格式:allow scontext tcontext:tclass {read}

深入提取:

1.觀察原生:

#參考資料:
https://www.jianshu.com/p/e95cd0c17adc

解決avc-denied之設置SELinux策略
https://blog.csdn.net/eliot_shao/article/details/51859083

1). 簡化方法
1.1 提取所有的avc LOG. 如 adb shell “cat /proc/kmsg | grep avc” > avc_log.txt 
1.2 使用 audit2allow tool 直接生成policy. audit2allow -i avc_log.txt 即可自動輸出生成的policy 
1.3 將對應的policy 添加到selinux policy 規則中,對應MTK Solution, 您可以將它們添加在KK: mediatek/custom/common/sepolicy, L: device/mediatek/common/sepolicy 下面,如

  allow zygote resource_cache_data_file:dir rw_dir_perms;
  allow zygote resource_cache_data_file:file create_file_perms;
  ===> mediatek/custom/common/sepolicy/zygote.te (KK)
  ===> device/mediatek/common/sepolicy/zygote.te (L)

注意audit2allow 它自動機械的幫您將LOG 轉換成policy, 而無法知道你操作的真實意圖,有可能出現權限放大問題,經常出現policy 無法編譯通過的情況。


 

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