編寫 SELinux 政策

Android 開放原始碼計畫 (AOSP) 針對 所有 Android 裝置通用的應用程式與服務。 Android 開放原始碼計畫的貢獻者會定期修正這項政策,應有核心政策 的確有 90% 到 95% 來自裝置專屬政策的最終裝置政策 其餘 5% 到 10% 的流量本文著重介紹 裝置專屬自訂功能、如何編寫裝置專屬政策,以及 過程中有些需要避免的陷阱

裝置啟動

撰寫裝置專屬政策時,請按照下列步驟操作。

以寬容模式執行

裝置已就緒時 寬容模式 系統會記錄拒絕次數,但不會強制執行。寬鬆模式對 原因:

  • 寬容模式可確保系統啟用政策不會延遲其他早期政策 裝置新增任務
  • 如果網站受到強制執行阻斷,可能會掩蓋其他遭拒情形。舉例來說,檔案存取權 通常涉及目錄搜尋、開啟檔案,然後讀取檔案於 強制執行模式,則只會發生目錄搜尋遭拒的情形。寬容模式 模式可確保看到所有遭拒的情況。

如要將裝置設為寬鬆模式,最簡單的做法是使用 核心指令 線條。你可以將這個項目新增至裝置的 BoardConfig.mk 檔案: platform/device/<vendor>/<target>/BoardConfig.mk。 修改指令列後,執行 make clean,然後 make bootimage,並刷新新的開機映像檔。

隨後,你可以使用以下方式確認許可模式:

adb shell getenforce

轉換至全球寬鬆模式的合理時間長度, 解決大多數拒絕措施後,請回到強制執行模式 及時解決潛在問題但仍產生拒絕或服務的網域 處於較重的開發階段可以暫時進入寬容模式 這些要求會盡快重新強制執行模式

及早強制執行

在強制執行模式下,系統會記錄並強制執行拒絕動作。最好 最好能盡早讓裝置進入強制執行模式等待 建立及強制執行裝置專屬政策,通常會導致產品發生錯誤, 使用者體驗不佳及早開始參與,以便參與 Dogfood 測試 並確保在實際使用時能全面測試所有功能。正在啟動 及早確保安全性疑慮會影響設計決策。相反地,授予 僅基於觀察到的遭拒情形,並不安全,這是不安全的做法。使用這份草稿 對裝置執行安全性稽核,並依據行為回報錯誤

移除或刪除現有政策

建立裝置專屬政策的原因很多 操作,包括:

處理核心服務遭拒的問題

核心服務產生的拒絕情形通常可透過檔案標籤處理。 例如:

avc: denied { open } for pid=1003 comm=”mediaserver” path="/dev/kgsl-3d0”
dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0
tclass=chr_file permissive=1
avc: denied { read write } for pid=1003 name="kgsl-3d0" dev="tmpfs"
scontext=u:r:mediaserver:s0
tcontext=u:object_r:device:s0 tclass=chr_file permissive=1

完全標示 /dev/kgsl-3d0 即可。於 在這個範例中,tcontextdevice。代表創造的 預設結構定義,其中 /dev 中的所有項目都會收到 「 裝置」標籤。只需接受 輸出語句 audit2allow 否則會造成錯誤且過於寬鬆的規則

為解決這個問題,請為檔案加上更明確的標籤 在這個案例中 gpu_device。不需要其他權限, 媒體伺服器已具備核心政策的必要權限,可以存取 gpu_device。

其他裝置專屬檔案,應該以預先定義的類型來標示 核心政策:

一般而言,將權限授予預設標籤時發生錯誤。許多解決方案 就會禁止 neverallow 規則,但 即使未明確禁止,最佳做法是 標籤。

為新服務和地址加上標籤 遭拒

所啟動的服務必須在各自的 SELinux 網域中執行。 以下範例會將服務「foo」放入本身的 SELinux 網域,並 授予其要求的權限。

這項服務已在裝置的 init.device.rc 檔案做為:

service foo /system/bin/foo
    class core
  1. 建立新網域「foo」

    建立檔案 device/manufacturer/device-name/sepolicy/foo.te 包含下列內容:

    # foo service
    type foo, domain;
    type foo_exec, exec_type, file_type;
    
    init_daemon_domain(foo)
    

    這是 foo SELinux 網域的初始範本,也就是您 可根據該執行檔執行的特定作業來新增規則。

  2. 標籤:/system/bin/foo

    將下列指令新增至 device/manufacturer/device-name/sepolicy/file_contexts:

    /system/bin/foo   u:object_r:foo_exec:s0
    

    確保執行檔加上適當的標籤,SELinux 將會執行 正確網域

  3. 建構並刷新開機和系統映像檔。
  4. 修正網域的 SELinux 規則。

    請根據拒絕情形判斷必要權限。 audit2allow 工具提供了完善的指南,但只用來做為政策的參考依據 讓您快速開始撰寫內容不要只複製輸出內容。

切換回強制執行模式

在寬鬆模式中可以進行疑難排解,但切換回強制套用模式 並盡量停留在那裡。

常見錯誤

以下提供幾種解決常見錯誤的方法 裝置專屬政策

過度使用否定

下面的例子是鎖門前門,但沒有 視窗開啟:

allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms

這項意圖清楚明確:除了第三方應用程式外,可能讓第三方應用程式存取偵錯 裝置。

這項規則在某些方面有所缺失。排除 untrusted_app 是相當實用的工具,因為所有應用程式都可以選擇在 isolated_app 網域。同樣地,如果是適用於第三方應用程式的新網域 這些 Android 開放原始碼計畫將可存取 scary_debug_device。 規則過於寬鬆。大多數網域 使用這個偵錯工具規則應該撰寫為 存取需要存取權的網域

在實際工作環境中偵錯功能

偵錯功能不應出現在正式版本或 政策。

最簡單的替代方案是僅在 SELinux 執行 已在 eng/userdebug 版本上停用,例如 adb rootadb shell setenforce 0

另一個安全的替代方案是在 userdebug_or_eng 陳述式。

政策規模爆炸

在野外界定 SEAndroid 政策 說明瞭裝置政策自訂項目的成長趨勢。 裝置專屬政策應涵蓋整體政策的 5% 到 10% 裝置。20%以上的自訂項目幾乎可以確實包含 特殊權限網域和無效政策。

過大的政策:

  • 政策存放在記憶體中, 也會載入核心記憶體
  • 透過指定較大的開機磁碟,浪費磁碟空間。
  • 會影響執行階段政策查詢次數。

以下範例顯示兩部製造商專屬的裝置 是裝置端政策的 50% 和 40%。重新編寫政策 而且網站不會遺失任何功能。 如下所示。(為了方便比較,我們一併提供 Shamu 和 Flounder 和 Android 開放原始碼計畫的裝置)。

圖 1:安全性稽核後的裝置特定政策大小比較。

圖 1. 裝置專屬比較 並套用安全性稽核後的政策大小

不論是哪種情況,政策的大小和數量都大幅縮減 授予其權限政策數量縮減幅度幾乎是由於移除 其中有很多可能是由 未新增至政策的 audit2allow。死 網域也都發生問題。

授予 dac_override 功能

如果「 dac_override」遭拒,表示違規程序 試圖以不正確的 Unix 使用者/群組/世界權限存取檔案。 適當的解決方案幾乎永遠不會授予 dac_override 權限。 請改為使用 變更檔案或程序的 Unix 權限。有一些網域 「init」、「vold」和「installd」皆為真正需要 覆寫 Unix 檔案權限,以存取其他程序的檔案。 瀏覽 Dan Walsh 的網誌 查看更詳盡的說明