2015年1月18日 星期日

SELinux for Android 簡介

最近在看 SELinux for Android 的資料,發現很少中文的解說,所以想說順便整理一篇。

在了解本篇主題以前,可以先了解一下什麼是 SELinux,我建議可以看這篇網誌,解釋得滿清楚的。

再來,這篇主要的內容會是解釋這個投影片, 這是 NSA(美國國家安全局) 對於 SELinux for Android 做的演講。好,正題開始。

SELinux 是要在原本Linux的 DAC (Discretionary Access Control) 上面,加上 MAC (Mandatory Access Control) 的架構。主要的目的是要避免誤用以導致系統損毀,要體驗的話其實很簡單,如果手邊有 root 的 Android 機器的話,可以發現就算用 root 的權限也沒有辦法去修改 system/ 下面的 init*.rc 的檔案內容,這就是因為 SELinux 在作祟擋住了寫入的權限。

platform/external/sepolicy/domain.te
# Nothing should be writing to files in the rootfs.
neverallow { domain -recovery } rootfs:file { create write setattr relabelto append unlink link rename };

上面那段 policy 的目的是在 domain 中除了 recovery 外,使用被標(labeled)成 rootfs 的 檔案(file) 都不被允許(neverallow) 這一長串 { create write setattr relabelto append unlink link rename } 裡面的事情。

再來,我們來看,rootfs 的定義:

platform/external/sepolicy/file_contexts
# Root
/          u:object_r:rootfs:s0
# Data files
/adb_keys               u:object_r:adb_keys_file:s0 #這行不是rootfs
/default\.prop          u:object_r:rootfs:s0
/fstab\..*              u:object_r:rootfs:s0
/init\..*               u:object_r:rootfs:s0
/res(/.*)?              u:object_r:rootfs:s0
/ueventd\..*            u:object_r:rootfs:s0

# Executablesˇ
/charger                u:object_r:rootfs:s0
/init                   u:object_r:rootfs:s0
/sbin(/.*)?             u:object_r:rootfs:s0

# Empty directories
/lost\+found            u:object_r:rootfs:s0
/proc                   u:object_r:rootfs:s0

# SELinux policy files
/file_contexts          u:object_r:rootfs:s0
/property_contexts      u:object_r:rootfs:s0
/seapp_contexts         u:object_r:rootfs:s0
/sepolicy               u:object_r:rootfs:s0
 
也就是說在這些檔案目錄下的東西,都不被允許 { create write setattr relabelto append unlink link rename },所以也沒有辦法在shell底下的根目錄新增檔案。而這就是SELinux的定義,可以避免誤用而導致系統損毀。

在看這些 rule 的時候,主要是看兩種檔案,一種是 *.te ,一種是 *_context。*.te 裡面記載著各種 rule;而 *_context 的目的是把檔案貼標籤 (labeling)。以上面的例子來看,rootfs 這個標籤在 domain.te 裡面,被規定了不能 { create write setattr relabelto append unlink link rename } ,而 rootfs 則是在 file_context 裡面跟真實的檔案目錄連結,只要抓到這個原則就很容易看懂這些 policy 之間的關係。

在 source code 裡面,這些檔案通常會被放在兩個地方:
  1. platform/external/sepolicy
  2. device/<vendor>/<product>/sepolicy 
  platform/external/sepolicy 可ˇ已把它看作是 AOSP 原生的 policy,基本上這些檔案最好不要修改;要修改的話,可以加在 device/<vendor>/<product>/sepolicy 裡面。在 platform/external/sepolicyREADME 有詳細說明該如何修改,說明如下:

Eg.) Suppose the following:
     BOARD_SEPOLICY_DIRS += X Y
     BOARD_SEPOLICY_REPLACE += A
     BOARD_SEPOLICY_IGNORE += X/A

     Directories X and Y contain A.

     The resulting policy is created by using Y/A only, thus X/A was
     ignored.

Example BoardConfig.mk Usage:
From the Tuna device BoardConfig.mk, device/samsung/tuna/BoardConfig.mk

BOARD_SEPOLICY_DIRS += \
        device/samsung/tuna/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te
 
最後,投影片裡面還有提到, platform/external/sepolicy 裡面大概有哪些檔案。檔案分成:
  • *.te
    • 定義一些全域的 rule: domain.te, app.te
    • 宣告 device 與 file 的 類型 (type): device.te, file.te
    • 單獨的 rule : e.g. installd.te
  • *_context
    •  file_contexts: labeling 檔案目錄
    •  property_contexts: labeling init 裡面的 property
    •  seapp_contexts:
  • mac_permissions.xml
    • 定義特定App的 seinfo,這個 seinfo 會在 seapp_contexs 裡面用到。

 有這些架構的概念以後,應該就可以順利地讀懂延伸閱讀裡面的東西。

延伸閱讀:

沒有留言 :

張貼留言