Google is committed to advancing racial equity for Black communities. See how.
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

編寫SELinux政策

Android開源項目(AOSP)為所有Android設備上通用的應用程序和服務提供了堅實的基礎策略。 AOSP的貢獻者會定期完善此政策。核心策略預計將佔最終設備上策略的約90–95%,而特定於設備的自定義則將佔剩餘的5–10%。本文重點介紹這些特定於設備的自定義項,如何編寫特定於設備的策略以及在此過程中應避免的一些陷阱。

設備啟動

在編寫特定於設備的策略時,請遵循以下步驟。

以寬鬆模式運行

當設備處於許可模式時 ,拒絕記錄但未強制執行。許可模式很重要,原因有兩個:

  • 允許模式可確保策略啟動不會延遲其他早期的設備啟動任務。
  • 強制拒絕可能會掩蓋其他拒絕。例如,文件訪問通常需要目錄搜索,打開文件然後讀取文件。在強制模式下,只會發生目錄搜索拒絕。允許模式可確保看到所有拒絕。

使設備進入許可模式的最簡單方法是使用內核命令行 。可以將其添加到設備的BoardConfig.mk文件中: platform/device/<vendor>/<target>/BoardConfig.mk 。修改命令行後,執行make clean ,然後執行make clean make bootimage ,並刷新新的啟動映像。

之後,使用以下命令確認許可模式:

adb shell getenforce

在全局許可模式下,兩週時間是合理的時間。解決了大多數拒絕之後,請轉入強制模式並解決其中的錯誤。仍在產生拒絕或仍在大量開發中的服務的域可以暫時置於允許模式,但應盡快將其移回強制模式。

儘早執行

在強制模式下,拒絕被記錄並強制執行。最佳做法是儘早使設備進入執行模式。等待創建和執行特定於設備的策略通常會導致產品出現問題,並帶來糟糕的用戶體驗。儘早開始參與狗食活動,並確保在實際使用中全面測試功能。儘早啟動可確保安全考慮可指導設計決策。相反,僅基於觀察到的拒絕授予權限是不安全的方法。使用這段時間對設備執行安全審核,並針對不應允許的行為記錄錯誤。

刪除或刪除現有策略

有很多充分的理由在新設備上從頭開始創建特定於設備的策略,包括:

解決拒絕核心服務的問題

核心服務生成的拒絕通常通過文件標籤解決。例如:

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中的所有內容都將接收“ device ”標籤。在這裡簡單地接受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域中運行服務。同樣,如果將第三方應用程序的新域添加到AOSP,它們也將有權訪問scary_debug_device 。該規則過於寬鬆。大多數域都無法從使用此調試工具中受益。該規則應該已經編寫為僅允許需要訪問的域。

生產中的調試功能

調試功能不應出現在生產版本上,也不應在其策略上出現。

最簡單的選擇是僅在eng / userdebug構建上禁用SELinux時才允許調試功能,例如adb rootadb shell setenforce 0

另一種安全的選擇是將調試權限包含在userdebug_or_eng語句中。

政策規模爆炸

在野外表徵SEAndroid策略描述了設備策略自定義設置增長中的一個令人關注的趨勢。特定於設備的策略應佔設備上運行的總體策略的5–10%。 20%以上範圍內的定制幾乎肯定包含特權域和無效策略。

不必要的大策略:

  • 由於策略位於ramdisk中,並且也已加載到內核內存中,因此對內存造成了雙重打擊。
  • 需要更大的啟動映像會浪費磁盤空間。
  • 影響運行時策略查找時間。

以下示例顯示了兩個設備,其中特定於製造商的策略佔設備上策略的50%和40%。如下所示,對該策略的重寫帶來了實質性的安全改進,而功能沒有損失。 (為了進行比較,包括了AOSP設備Shamu和Flounder。)

圖1:安全審核後特定於設備的策略大小的比較。

圖1 。安全審核後特定於設備的策略大小的比較。

在這兩種情況下,該策略的大小和權限數量都大大減少了。策略大小的減小幾乎完全是由於刪除了不必要的權限,其中許多可能是audit2allow生成的規則,被隨意添加到策略中。死域也是兩個設備的問題。

授予dac_override功能

dac_override拒絕表示有問題的進程正在嘗試使用錯誤的unix用戶/組/世界權限訪問文件。正確的解決方案是幾乎永遠不要授予dac_override權限。而是更改文件或進程的UNIX權限 。某些域(例如initvoldinstalld確實需要能夠覆蓋UNIX文件權限以訪問其他進程的文件。請參閱Dan Walsh的博客 ,以獲取更深入的解釋。