iT邦幫忙

2025 iThome 鐵人賽

DAY 29
0
自我挑戰組

安豬複習系列 第 29

#28

  • 分享至 

  • xImage
  •  

SELinux in Android

intro: why Android need SELinux?

在 Android 的早期版本(Android 4.2 以前),應用與系統服務的安全隔離主要依靠:

  • Linux kernel 的 UID sandboxing(使用者隔離);
  • 應用框架層的 Permission 檢查機制;
  • Dalvik/ART 層的 應用沙箱執行環境。

這樣的設計雖能避免應用直接干擾他人,但仍有兩個問題:

  • 若某個 system service(如 mediaserver)被攻破,攻擊者可利用該服務的高權限繞過 sandbox;
  • kernel 模組與 native 進程之間缺乏細粒度控制,造成潛在提權漏洞。

於是 Google 在 Android 4.3 (2013) 開始導入 SELinux (Security-Enhanced Linux),並在 Android 5.0 (Lollipop) 之後全面啟用 「Enforcing 模式」。
SELinux 成為 Android 安全架構的關鍵基石,用以實現 Mandatory Access Control (MAC) —— 強制存取控制。

SELinux 基本概念

2.1 DAC 與 MAC 的差異

模型 名稱 控制權歸屬 特點
DAC (Discretionary Access Control) 任意存取控制 由檔案擁有者決定 如 Linux 傳統 chmod, chown
MAC (Mandatory Access Control) 強制存取控制 由系統策略統一規範 SELinux、AppArmor 等屬此類

在 Android 中,DAC 仍存在,但 SELinux 的 MAC 為「第二層強制規範」,無論 UID 權限如何,都必須通過 policy 驗證。

2.2 SELinux 的基本組成

+-----------------------------------------------------------+
|                   SELinux Policy Framework                |
+-----------------------------------------------------------+
|   policy.conf / sepolicy   →   compiled into sepolicy     |
|   type enforcement (TE)    →   決定哪些 domain 能存取何資源 |
|   file_contexts            →   檔案與型別對應              |
|   seapp_contexts           →   app 與 domain 對應         |
|   service_contexts         →   系統服務 domain 對應        |
+-----------------------------------------------------------+
|                Kernel SELinux Module (AVC)                |
|      → Security Server 決策 + Access Vector Cache         |
+-----------------------------------------------------------+

簡單來說:

  • 每個進程都屬於一個 domain (context);
  • 每個檔案、socket、binder 也有 security label;
  • 當進程試圖存取資源時,SELinux 驗證這個「主體(subject)」是否能操作「物件(object)」。

Android 上的 SELinux 架構層級

圖 1:SELinux 在 Android 系統架構中的位置

+-----------------------------------------------------------+
|                  Application Framework 層                 |
|   (PermissionManagerService, ActivityManagerService...)    |
+-----------------------------------------------------------+
|                 Native System Services 層                 |
|   (system_server, mediaserver, keystore, surfaceflinger)  |
+-----------------------------------------------------------+
|                  Binder / HAL / JNI 層                    |
|           (libbinder.so, HIDL/AIDL IPC, HAL drivers)      |
+-----------------------------------------------------------+
|                     Kernel & SELinux                      |
|        (AVC, sepolicy, security_context enforcement)      |
+-----------------------------------------------------------+

Android 的安全模型是 多層次防禦 (Defense-in-Depth):

  • Framework 層靠 Permission 系統;
  • Native 層靠 SELinux Policy;
  • Kernel 層靠 Linux Capability;
    三者互相補強,形成安全閉環。

SELinux 在 Android 啟動流程中的角色

在 init 階段,SELinux 的初始化流程如下:

  1. init.rc 啟動 → 載入 sepolicy;
  2. init 進程呼叫 selinux_init_all_handles();
  3. 載入 /vendor/etc/selinux/ 和 /system/etc/selinux/ 的 policy;
  4. 設定 enforcing=1(強制模式);
  5. 為每個啟動的進程指派安全 context。

Context 範例

u:r:system_server:s0
u:r:app_123:s0:c512,c768
u:object_r:system_data_file:s0

格式說明:
user:role:type:level

user:通常是 u;
role:角色(在 Android 幾乎都固定);
type:最關鍵,定義該進程或物件的 domain;
level:多層安全等級(Android 目前主要用於 app sandbox)。

SELinux 在 Android 中的主要策略檔案

檔案名稱 功能
sepolicy 編譯後的策略檔,供 kernel 直接使用
file_contexts 對應系統檔案與 security label
seapp_contexts 對應 App 與其 domain
service_contexts 對應 system service 名稱與 domain
property_contexts 對應 system property 的安全屬性

圖 2:策略關聯概念圖

App (UID) ─▶ seapp_contexts ─▶ app_domain
System Service ─▶ service_contexts ─▶ system_domain
File Path ─▶ file_contexts ─▶ object_type

SELinux use cases

防止進程越權

假設惡意應用想讀取相機 buffer:

app_123 (u:r:untrusted_app:s0)
→ 嘗試讀取 /dev/camera

Kernel 查詢 policy:

allow untrusted_app camera_device:chr_file read;

若 policy 無此項 → AVC (Access Vector Cache) 拒絕,logcat 顯示:

avc: denied { read } for pid=1234 comm="MyApp"
path="/dev/camera" scontext=u:r:untrusted_app:s0
tcontext=u:object_r:camera_device:s0
tclass=chr_file permissive=0

即使該 App 有 CAMERA 權限,也無法直接存取底層裝置檔案,必須透過 framework API 間接操作。

保護系統進程

mediaserver、surfaceflinger、keystore、system_server 各自有獨立 domain:

  • u:r:mediaserver:s0
  • u:r:system_server:s0
  • u:r:keystore:s0

即使其中之一被攻擊,也無法隨意干擾其他系統服務。
例如:mediaserver 無法直接讀取 /data/system/ 內的使用者設定。

SELinux 的運作模式與除錯

模式分類

模式 說明
Permissive 僅記錄違規行為,不阻擋
Enforcing 實際阻擋違規操作(Android 預設)

可透過 adb shell getenforce 查看當前狀態。

查看日誌

adb logcat -b all | grep avc

dmesg | grep avc

輸出中可看到:

  • 哪個進程;
  • 嘗試的操作;
  • 來源與目標 context;
  • 是否被拒絕。

開發者如何新增 SELinux Policy

假設開發者自訂 HAL 服務 /vendor/bin/hw/myhal:

  1. 定義 domain
type myhal, domain;
type myhal_exec, exec_type, file_type;
init_daemon_domain(myhal)
  1. 新增檔案上下文
/vendor/bin/hw/myhal    u:object_r:myhal_exec:s0
  1. 撰寫 allow 規則
allow myhal self:capability { net_bind_service };
allow myhal system_data_file:dir search;
  1. 重新編譯 sepolicy
mmm system/sepolicy
  1. 驗證執行
adb shell ps -Z | grep myhal

SELinux 與 App Sandbox、Permission 系統的關係

三層安全防護模型

+---------------------------------------+
|  應用層:Runtime Permission            |
|  (檢查使用者授權)                    |
+---------------------------------------+
|  Framework 層:PermissionManagerService |
|  (授權決策、AppOps 檢查)             |
+---------------------------------------+
|  Kernel 層:SELinux + UID sandbox     |
|  (強制阻擋底層資源存取)              |
+---------------------------------------+
防護層級 功能 例子
App sandbox (UID) 防止應用交叉讀取資料 App A 無法讀取 App B 的資料夾
Permission System 控制 API 存取 需要 CAMERA 權限才能開啟鏡頭
SELinux Policy 防止底層繞過 API 阻擋對 /dev/camera 的直接存取

這三層共同構成 Android 的安全閉環。

SELinux 對系統穩定性與維護的影響

  • 安全性提升:防止零日漏洞透過 system 進程提權;
  • 隔離錯誤影響:不同服務即使 crash 也不會擴散;
  • 維護難度增加:OEM 與驅動開發者需撰寫對應 policy;
  • 版本升級挑戰:每次 Android major update,policy 結構都需同步更新。

SELinux 在 Android 各版本的演進

Android 版本 SELinux 狀態 主要改進
4.3 初次導入 僅 Audit 模式
4.4 部分服務 Enforcing system_server 仍 permissive
5.0 全面 Enforcing 所有 system domain 強制
8.0 Treble 分區化 Policy 分離 /system /vendor policy
10 Scoped storage + Policy modularization 降低誤殺風險
12 User-space SELinux 支援 userdebug 擴展
14 精簡化 App domain 加強沙箱一致性

summary

SELinux 不僅是「額外安全層」,而是 Android 信任模型的核心之一。
它確保即使 應用或系統進程被攻擊,仍受限於 Policy 規則,無法任意操作系統資源。
對開發者而言,理解 SELinux 是設計安全 HAL、Native Daemon、Vendor Service 的必要條件。

SELinux 在 Android 安全體系中的角色

+-----------------------------------------------------------+
|                  應用層 (Permissions)                    |
|    應用請求 API → Framework 驗證                         |
+-----------------------------------------------------------+
|             系統層 (SELinux Policy / AppOps)              |
|    驗證 domain / type / context,控制 IPC、file、socket   |
+-----------------------------------------------------------+
|                 Kernel 層 (Sandbox + Capability)          |
|    UID/GID 隔離 + Kernel Security Modules                 |
+-----------------------------------------------------------+

一句話總結:
Permission 決定「誰能申請」;SELinux 決定「申請了之後能不能真的做」。


上一篇
#27
下一篇
#29
系列文
安豬複習31
  1. 27
    #26
  2. 28
    #27
  3. 29
    #28
  4. 30
    #29
  5. 31
    #30
完整目錄
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言