實現 SELinux

SELinux 設置為默認拒絕,這意味著它在內核中具有掛鉤的每個訪問都必須由策略明確允許。這意味著策略文件包含大量關於規則、類型、類、權限等的信息。對 SELinux 的全面考慮超出了本文檔的範圍,但在啟動新的 Android 設備時,了解如何編寫策略規則現在至關重要。已經有大量關於 SELinux 的可用信息。見支持文檔中建議的資源。

密鑰文件

要啟用SELinux的,整合了最新的Android內核,然後整合在找到的文件系統/ sepolicy目錄。編譯後,這些文件包含 SELinux 內核安全策略並涵蓋上游 Android 操作系統。

在一般情況下,你不應該修改system/sepolicy直接文件。取而代之的是,在添加或編輯自己的設備特定策略文件/device/ manufacturer / device-name /sepolicy目錄。在 Android 8.0 及更高版本中,您對這些文件所做的更改只會影響供應商目錄中的政策。有關在Android的8.0公共sepolicy的分離和更高的更多詳細信息,請參閱定制SEPolicy中的Android 8.0+ 。無論 Android 版本如何,您仍在修改這些文件:

策略文件

文件結束與*.te是SELinux策略的源文件,它定義域和它們的標籤。您可能需要創建新的策略文件/device/ manufacturer / device-name /sepolicy ,但你應該嘗試盡可能地更新現有文件。

上下文文件

上下文文件是您為對象指定標籤的地方。

  • file_contexts受讓人標籤文件,並使用各種用戶空間組件。創建新策略時,創建或更新此文件以將新標籤分配給文件。要應用新的file_contexts ,重建文件系統映像或運行restorecon上的文件進行重新標記。在升級,改變file_contexts被自動應用到系統和用戶數據分區作為升級的一部分。變化也可自動升級上通過增加應用到其他分區restorecon_recursive調用你的初始化。 board分隔後rc文件已經被安裝讀寫。
  • genfs_contexts受讓人標籤的文件系統,如procvfat不支持擴展屬性。此配置作為內核策略的一部分加載,但更改可能不會對核心 inode 生效,需要重新啟動或卸載並重新掛載文件系統以完全應用更改。特定標籤也可以被分配給特定的安裝件,諸如vfat使用context=mount選項。
  • property_contexts受讓人標籤Android系統屬性來控制哪些流程可以進行設置。這種結構是通過讀init啟動過程中的過程。
  • service_contexts受讓人標籤到Android粘結劑服務控制程序可以添加什麼(註冊)和查找(查找)該服務的粘結劑參考。這種結構是由閱讀servicemanager啟動過程中的過程。
  • seapp_contexts受讓人標籤應用程序和/data/data目錄。這種結構是通過讀zygote每個應用程序啟動和處理installd啟動過程中。
  • mac_permissions.xml分配seinfo標籤根據其簽名和可選的包名的應用程序。該seinfo然後標籤可以用作一個關鍵seapp_contexts文件分配一個特定的標籤,所有的應用程序與seinfo標籤。這種結構是通過讀取system_server啟動過程中。

BoardConfig.mk 生成文件

編輯或添加的政策和背景文件後,更新/device/ manufacturer / device-name /BoardConfig.mk的makefile引用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_*變量。見READMEsystem/sepolicy用於設置此功能的詳細信息。
  10. 檢查初始化。 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,也可以禁止這些更改之外的任何內容。因此,一個應用程序可能運行chmodchown對付那些標註app_data_files但不shell_data_filessystem_data_files