實作 SELinux

SELinux 設定為預設拒絕,這意味著它在核心中具有鉤子的每個存取都必須得到策略的明確允許。這意味著策略文件由大量有關規則、類型、類別、權限等的資訊組成。對 SELinux 的全面考慮超出了本文檔的範圍,但在推出新的 Android 裝置時,了解如何編寫策略規則現在至關重要。已經有大量有關 SELinux 的資訊。請參閱支援文件以取得建議的資源。

關鍵文件

若要啟用 SELinux,請整合最新的 Android 內核,然後合併在system/sepolicy目錄中找到的檔案。編譯後,這些檔案包含 SELinux 核心安全策略並覆蓋上游 Android 作業系統。

一般來說,您不應直接修改system/sepolicy檔案。相反,請在/device/ manufacturer / device-name /sepolicy目錄中新增或編輯您自己的特定於裝置的策略檔案。在 Android 8.0 及更高版本中,您對這些檔案所做的變更應該僅影響供應商目錄中的策略。有關 Android 8.0 及更高版本中公共 sepolicy 分離的更多詳細信息,請參閱在 Android 8.0+ 中自訂 SEPolicy 。無論 Android 版本如何,您仍然需要修改這些檔案:

政策文件

*.te結尾的文件是 SELinux 策略來源文件,它定義域及其標籤。您可能需要在/device/ manufacturer / device-name /sepolicy中建立新的策略文件,但您應盡可能嘗試更新現有文件。

上下文文件

上下文檔案是您為物件指定標籤的位置。

  • file_contexts為檔案指派標籤,並由各種使用者空間元件使用。建立新策略時,建立或更新此文件以向文件指派新標籤。若要套用新的file_contexts ,請重建檔案系統映像或在要重新標記的檔案上執行restorecon 。升級時,對file_contexts的變更將作為升級的一部分自動套用至系統和使用者資料分割區。透過將restorecon_recursive呼叫新增至您的init.d 檔案中,也可以在升級到其他分割區時自動套用變更。分割區掛載為可讀寫後的board檔。
  • genfs_contexts為檔案系統指派標籤,例如不支援擴充屬性的procvfat 。此配置作為核心策略的一部分加載,但變更可能不會對核心 inode 生效,需要重新啟動或卸載並重新安裝檔案系統才能完全套用變更。也可以將特定標籤指派給特定安裝,例如使用context=mount選項的vfat
  • property_contexts為 Android 系統屬性指派標籤,以控制哪些程序可以設定它們。此配置由init進程在啟動期間讀取。
  • service_contexts為 Android Binder 服務指派標籤,以控制哪些程序可以新增(註冊)和尋找(查找)服務的 Binder 參考。此配置由servicemanager進程在啟動期間讀取。
  • seapp_contexts為應用程式進程和/data/data目錄指派標籤。此配置由zygote進程在每次應用程式啟動時讀取,並由installd在啟動期間讀取。
  • mac_permissions.xml根據應用程式的簽章和(可選)套件名稱為應用程式指派一個seinfo標記。然後可以將seinfo標籤用作seapp_contexts檔案中的鍵,以將特定標籤指派給具有該seinfo標籤的所有應用程式。此配置由system_server在啟動期間讀取。
  • keystore2_key_contexts將標籤指派給 Keystore 2.0 命名空間。這些命名空間由 keystore2 守護程序強制執行。 Keystore 總是提供基於 UID/AID 的命名空間。 Keystore 2.0 也強制執行 sepolicy 定義的命名空間。可以在此處找到該文件的格式和約定的詳細說明。

BoardConfig.mk 產生文件

編輯或新增策略和上下文檔案後,更新/device/ manufacturer / device-name /BoardConfig.mk以引用sepolicy子目錄和每個新策略檔案。有關BOARD_SEPOLICY變數的詳細信息,請參閱system/sepolicy/README文件

BOARD_SEPOLICY_DIRS += \
        <root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

重建後,您的裝置將啟用 SELinux。現在,您可以自訂 SELinux 策略以適應您自己對 Android 作業系統的新增(如自訂中所述),或驗證現有設定(如驗證中所述)。

當新的策略檔案和 BoardConfig.mk 更新就位時,新的策略設定將自動建置到最終的核心策略檔案中。有關如何在設備上建置 sepolicy 的更多信息,請參閱建置 sepolicy

執行

開始使用 SELinux:

  1. 在核心中啟用 SELinux: CONFIG_SECURITY_SELINUX=y
  2. 更改 kernel_cmdline 或 bootconfig 參數,以便:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    這僅用於設備策略的初始開發。擁有初始引導策略後,請刪除此參數,以便您的裝置強制執行,否則 CTS 將失敗。
  3. 以寬容方式啟動系統並查看啟動時遇到的拒絕情況:
    在 Ubuntu 14.04 或更高版本:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    在 Ubuntu 12.04 上:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. 評估輸出中是否有類似init: Warning! Service name needs a SELinux domain defined; please fix!請參閱驗證以取得說明和工具。
  5. 識別設備和其他需要標記的新文件。
  6. 為您的物件使用現有的或新的標籤。查看*_contexts檔案以了解之前如何標記事物,並使用標籤含義的知識來分配新的標籤。理想情況下,這將是符合政策的現有標籤,但有時需要新標籤,並且需要存取該標籤的規則。將標籤新增至適當的上下文文件。
  7. 識別應該有自己的安全域的域/進程。您可能需要為每個策略編寫一個全新的策略。例如,從init產生的所有服務都應該有自己的。以下命令有助於顯示那些仍在運行的服務(但所有服務都需要這樣的處理):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. 回顧一下init. device .rc來識別任何沒有域類型的域。在開發過程的早期為他們提供一個網域,以避免向init添加規則或以其他方式將init訪問與他們自己的策略中的訪問混淆。
  9. 設定BOARD_CONFIG.mk以使用BOARD_SEPOLICY_*變數。有關設定的詳細信息,請參閱system/sepolicy中的自述文件
  10. 檢查 init. device .rc 和fstab。 device文件,並確保每次使用mount都對應於正確標記的文件系統或指定了context= mount選項。
  11. 仔細檢查每個拒絕並建立 SELinux 策略來正確處理每個拒絕。請參閱自訂中的範例。

您應該從 AOSP 中的策略開始,然後根據它們進行自訂。有關策略策略的更多資訊以及對其中一些步驟的詳細了解,請參閱編寫 SELinux 策略

用例

以下是在建立您自己的軟體和相關 SELinux 策略時需要考慮的具體漏洞範例:

符號連結- 由於符號連結顯示為文件,因此它們通常被作為文件讀取,這可能會導致漏洞。例如,某些特權元件(例如init )會變更某些檔案的權限,有時會過度開啟。

然後,攻擊者可能會用他們控制的程式碼的符號連結替換這些文件,從而允許攻擊者覆蓋任意文件。但是,如果您知道您的應用程式永遠不會遍歷符號鏈接,則可以使用 SELinux 禁止它這樣做。

系統檔案- 考慮只能由系統伺服器修改的系統檔案類別。儘管如此,由於netdinitvold以 root 身份運行,因此它們可以存取這些系統檔案。因此,如果netd受到損害,它可能會損害這些文件,甚至可能損害系統伺服器本身。

使用 SELinux,您可以將這些檔案識別為系統伺服器資料檔案。因此,唯一對其具有讀取/寫入存取權限的網域是系統伺服器。即使netd受到威脅,儘管它以 root 身份運行,但它也無法將網域切換到系統伺服器網域並存取這些系統檔案。

應用程式資料- 另一個範例是必須以 root 身分執行但不應存取應用程式資料的函數類別。這非常有用,因為可以做出廣泛的斷言,例如禁止與應用程式資料無關的某些網域存取網際網路。

setattr - 對於chmodchown等指令,您可以識別關聯域可以執行setattr檔案集。除此之外的任何內容都可能被禁止進行這些更改,即使是 root。因此,應用程式可能會針對標記為app_data_files檔案執行chmodchown ,但不會針對shell_data_filessystem_data_files執行。