目錄
- 前言
- 一、 通用AV規則語法
- 1.1 allow source target:class permissions;
- 1.2 neverallow source target:class permissions;
- 二、type
- 三、attribute
- 四、typeattribute
- 五、alias
- 六、typealias
- 七、init_daemon_domain
- 7.1 `init_daemon_domain` 宏概述
- 7.2 宏展開與實現
- 7.2.1 展開后規則詳解
- 7.2.2 總結
- 八、xxx_contexts
- 8.1 **什么是安全上下文?**
- 8.2 **常見的 xxx_contexts 文件及其功能**
- (1) **file_contexts**
- (2) **property_contexts**
- (3) **service_contexts**
- (4) **seapp_contexts**
- (5) **hwservice_contexts**
- (6) **vndservice_contexts**
- (7) **genfs_contexts**
- (8) **fs_use_xxx**
- 8.3 **如何使用和修改 xxx_contexts 文件**
- 8.4 **Android SELinux 上下文文件的模塊化**
- 九、其他
- domain
- coredomain
- init_daemon_domain()
- coredomain和init_daemon_domain()
- SELinux安全上下文
- SELinux文件屬性
- SELinux權限
前言
關于安卓Selinux之前寫過一篇文章,安卓SELinux策略,最近這方面的工作比較多,完成之后準備再寫一篇,不過這篇文章將重點描述SELinux的語法規則
一、 通用AV規則語法
? 規則名稱: allow,dontaudit,auditallow和neverallow? 源類型:授予訪問的類型,通常是進程的域類型? 目標類型:客體的類型,它被授權可以訪問的類型? 客體類別:客體的類別? 許可:表示主體對客體訪問時允許的操作類型(也叫做訪問向量)。一個簡單的AV規則有一個源類型,目標類型,客體類別和許可。
1.1 allow source target:class permissions;
allow規則中可以看到許多AV規則,如:
allow user_t bin_t : file execute;
這個allow規則的源類型為user_t,目標類型為bin_t,客體類別file,許可execute,這個規則可以解讀為"允許user_t執行類型為bin_t的文件"
上面的規則示例中,直接引用了源類型(user_t)
和目標類型(bin_t)
,其實在源類型或目標類型中要引用多個類型也是很方便的,其中一個方法就是使用屬性,在AV規則中能使用類型的地方都可以使用屬性(類型組)。
例如,假設我們定義了一個屬性(exec_type)
,打算將其與所有的普通用戶程序(通過域類型user_t標記)
都可以執行的文件類型關聯,那么就可以將上面的例子改為引用屬性exec_type
,而不用再明確地指定類型bin_t
了,如:
allow user_t exec_type : file execute;
1.2 neverallow source target:class permissions;
這個規則來指定永遠不會被allow規則執行的訪問
neverallow user_t shadow_t : file write;
這條neverallow規則可以有效地阻止我們在策略中添加一條允許user_t對類型為shadow_t的文件進行寫操作的規則,如果添加了這樣的規則在編譯時就會報錯,這條規則不會移除訪問權,它只是會產生編譯錯誤。我們在編寫策略時,neverallow規則往往放在allow規則前面,首先聲明哪些訪問是明確地被拒絕的,然后再聲明哪些訪問是可以接受的,這樣就可以預防我們人為出錯了。
二、type
- 作用:
類型聲明
- 語法:
type 類型名稱 [alias 別名集] [,屬性集];
- 定義:type 是 SELinux 策略中最基本的類型聲明,用于定義一個具體的 SELinux 類型(type),表示資源(如文件、進程、屬性)或主體(如進程域)的安全上下文。
每個 type 是一個獨立的標簽,用于標識特定資源或進程的 SELinux 上下文,供權限規則使用。
注意
:
- 別名集:如果指定的不止一個別名標識符,要在一對大括號中用空格將各個別名區別開來,如:alias {aliasa_t aliasb_t}。
- 屬性集:是一個或多個預先聲明的屬性標識符,如果同時指定多個屬性標識符,屬性之間使用逗號進行分隔,如:type bin_t, file_type, exec_type;
- 類型聲明在整個策略中,以及基礎載入模塊和非基礎載入模塊中都是有效的。但在有條件的語句中無效。
示例:
type serial_device, dev_type;
定義 serial_device 類型,表示串口設備(如 /dev/ttyS0),并關聯 dev_type 屬性(表示設備類型)。
三、attribute
- 定義:
attribute 是 SELinux 中的屬性聲明,用于定義一個類型集合(group),可以將多個 type 歸類到一個抽象標簽下,簡化權限規則的編寫。它本身不直接與資源或進程關聯,而是為 type 提供分組機制。 - 作用:
允許在規則中使用單個 attribute 替代多個 type,減少重復規則。
常用于分類類似資源(如所有 sysfs 文件、所有屬性類型)。 - 語法:
attribute 屬性名稱;
注意
:
- 屬性和類型,別名都在同一個命名空間,因此不能與其他類型或別名重名。
- 屬性聲明在整個策略,基礎載入模塊和非基礎載入模塊中都有效,但在有條件的語句中無效。
示例:
attribute sysfs_odm_server;
定義 sysfs_odm_server屬性(在 attributes 文件中添加),用于標記與 odm_server相關的類型(如 sysfs 節點)。
四、typeattribute
- 定義:
typeattribute 是 SELinux 的語句,用于將一個已定義的 type 與一個或多個 attribute 關聯,將該 type 加入屬性集合。
它是連接 type 和 attribute 的橋梁。 - 作用:
允許一個 type 繼承某個 attribute 的權限規則,簡化策略管理。
當 allow 規則使用 attribute 時,所有關聯該屬性的 type 都會受到影響。 - 語法:
typeattribute 類型名 屬性名;
示例:
type odm_server, domain;
typeattribute odm_server sysfs_odm_server;
將 odm_server 類型關聯到 sysfs_odm_server 屬性,表示 odm_server 具有 sysfs_odm_server 的權限特性。
五、alias
(為確保兼容性而存在)別名是引用類型時的一個備選的名字,能夠使用類型名的地方就可以使用別名,包括TE規則,安全上下文和標記語句,別名通常用于策略改變時保證一致性,例如:一個舊策略可能引用了類型netscape_t,更新后的策略可能將類型名改為mozilla_t了,但同時提供了一個別名netscape_t以保證與舊模塊能夠正確兼容。
type mozilla_t alias netscape_t, domain;
注意別名聲明是放在屬性的前面的。
六、typealias
- 語法:
typealias 類型名稱 alias 別名名稱
- 類型名稱:要添加別名的類型的名稱,類型必須使用type語句單獨聲明,而且這里只能指定一個類型名稱。
- 別名名稱:如果同時指定多個別名,別名之間用空格分開,并使用大括號將所有別名括起來,如{aliasa_t aliasb_t}。
- typealias語句在單個策略,基礎載入模塊和非基礎載入模塊中都有效,只有在條件語句中無效。
# 這兩條語句等同于
type mozilla_t, domain;
typealias mozilla_t alias netscape_t; #下面這一條語句
type mozilla_t alias netscape_t, domain;
七、init_daemon_domain
7.1 init_daemon_domain
宏概述
- 定義:
init_daemon_domain
是 Android SELinux 策略中的一個宏,定義在system/sepolicy/public/te_macros
(或prebuilts/api/34.0/public/te_macros
)中,用于為由init
進程啟動的守護進程(daemon)配置 SELinux 域。- 它為指定的進程類型(
xx
)分配一個 SELinux 域, 由init啟動的進程,默認和init有相同的權限,所以需要用init_daemon_domain()將進程的域切換到自己的進程域,確保守護進程在安全的環境中運行。
- 作用:
- 將一個進程標記為
init
啟動的守護進程,分配一個獨立的 SELinux 域。 - 配置必要的權限,允許進程與
init
交互、訪問資源,并限制其行為以符合安全策略。 - 常用于系統服務或供應商服務。
- 將一個進程標記為
- 語法:
init_daemon_domain(<domain_name>)
<domain_name>
:要定義的 SELinux 域類型(如xx
),通常是一個type
(如odm_server
)。
7.2 宏展開與實現
init_daemon_domain
是一個宏,展開后包含一系列 SELinux 規則。其在 Android 12(system/sepolicy/public/te_macros
)中的定義:
# system/sepolicy/public/te_macros
macro init_daemon_domain(domain)type $1, domain;type $1_exec, exec_type, file_type;domain_auto_trans(init, $1_exec, $1)allow $1 self:capability { setuid setgid };allow $1 init:unix_stream_socket { connectto };allow $1 init:fd use;allow $1 self:process { execmem };allow $1 kernel:security { read_policy load_policy };allow $1 self:capability2 { logging };# Allow init to relabel the daemonallow init $1:process { transition sigchld };# Allow the daemon to relabel itselfallow $1 self:process { setcurrent };# Allow init to send signals to the daemonallow init $1:process { signal };
endmacro
7.2.1 展開后規則詳解
假設你調用 init_daemon_domain(odm_server)
,宏會展開為以下規則:
-
定義類型:
type odm_server, domain; type odm_server_exec, exec_type, file_type;
- 定義
odm_server
作為 SELinux 域類型(domain
),表示進程的運行上下文。 - 定義
odm_server_exec
作為可執行文件類型(exec_type
和file_type
),通常對應守護進程的可執行文件(如/system/bin/odm_server
)。
- 定義
-
域轉換:
domain_auto_trans(init, odm_server_exec, odm_server)
- 定義域轉換規則:當
init
進程執行odm_server_exec
文件時,進程上下文自動轉換為odm_server
域。 - 等價于:
allow init odm_server_exec:file { execute }; allow init odm_server:process { transition }; type_transition init odm_server_exec:process odm_server;
- 定義域轉換規則:當
7.2.2 總結
init_daemon_domain(odm_server)
將odm_server
定義為一個由init
啟動的守護進程域,配置其執行文件(odm_server_exec
)和基本權限,確保安全運行。- 它簡化了守護進程的 SELinux 配置,適用于系統或供應商服務。
八、xxx_contexts
在 Android 的 SELinux(Security-Enhanced Linux)中,xxx_contexts
文件是用來定義 SELinux 安全策略的上下文文件,它們指定了系統資源(如文件、進程、屬性等)的安全上下文(security context)。這些文件通常位于 /etc/selinux/targeted/contexts
目錄下,用于配置 SELinux 的安全標簽和權限規則。以下是對常見 xxx_contexts
文件的詳細解析:
8.1 什么是安全上下文?
安全上下文是 SELinux 用來標識資源(文件、進程、端口等)安全屬性的標簽,格式為:
user:role:type[:range]
- user: SELinux 用戶(如
system_u
,u
)。 - role: 角色(如
object_r
表示對象角色)。 - type: 類型,是 SELinux 類型強制訪問控制(TE)的核心(如
app_data_file
)。 - range: MLS(多級安全)或 MCS(多類安全)級別(可選,通常 Android 不使用 MLS)。
xxx_contexts
文件的作用是為不同類型的資源分配初始的安全上下文。
8.2 常見的 xxx_contexts 文件及其功能
以下是 Android SELinux 中常見的 xxx_contexts
文件及其詳細說明:
(1) file_contexts
- 作用: 定義文件系統對象的 SELinux 安全上下文,指定文件、目錄或符號鏈接的默認標簽。
- 位置: 通常位于
/etc/selinux/targeted/contexts/files/file_contexts
。 - 格式:
示例:<路徑正則表達式> <上下文>
/system/bin/sh u:object_r:shell_exec:s0 /data/data/.* u:object_r:app_data_file:s0
/system/bin/sh
的上下文被設置為u:object_r:shell_exec:s0
,表示它是可執行的 shell 文件。/data/data/.*
表示所有應用數據目錄的上下文為app_data_file
。
- 用途:
- 在系統啟動或文件創建時,
file_contexts
決定文件的初始標簽。 - 用于
restorecon
命令來修復或設置文件的安全上下文。
- 在系統啟動或文件創建時,
- 注意:
- 正則表達式匹配路徑時,優先級從上到下,匹配最具體的規則。
- Android 的
file_contexts
通常被拆分成多個文件(如/system/etc/selinux/plat_file_contexts
、/vendor/etc/selinux/vendor_file_contexts
)以支持模塊化。
(2) property_contexts
- 作用: 定義系統屬性的 SELinux 安全上下文(
property
是 Android 的鍵值對配置,如ro.build.version
)。 - 位置:
/etc/selinux/targeted/contexts/property_contexts
。 - 格式:
示例:<屬性前綴> <上下文>
ro.build.* u:object_r:build_prop:s0 persist.sys.* u:object_r:system_prop:s0
ro.build.*
表示所有以ro.build
開頭的只讀屬性使用build_prop
上下文。persist.sys.*
表示持久化系統屬性使用system_prop
上下文。
- 用途:
- 控制哪些進程可以讀取或修改特定屬性。
- 防止未經授權的進程篡改關鍵系統屬性。
- 注意:
- 屬性上下文對系統屬性的訪問控制非常嚴格,進程必須具有對應的類型和權限才能訪問。
(3) service_contexts
- 作用: 定義 Android Binder 服務(或 AIDL 服務)的 SELinux 安全上下文。
- 位置:
/etc/selinux/targeted/contexts/service_contexts
。 - 格式:
示例:<服務名稱> <上下文>
activity_service u:object_r:activity_service:s0 wifi_service u:object_r:wifi_service:s0
activity_service
是 ActivityManagerService 的 Binder 服務,上下文為activity_service
。
- 用途:
- 控制哪些進程可以調用特定的 Binder 服務。
- 確保只有授權的進程可以訪問關鍵服務(如 ActivityManager 或 Wi-Fi 服務)。
- 注意:
- 服務名稱通常由系統定義,開發者需要確保自定義服務的上下文正確配置。
(4) seapp_contexts
- 作用: 定義 Android 應用進程的 SELinux 安全上下文,決定應用的 SELinux 域(domain)。
- 位置:
/etc/selinux/targeted/contexts/seapp_contexts
。 - 格式:
示例:user=<SELinux用戶> isPrivApp=<true/false> name=<包名> domain=<域> type=<文件類型> levelFrom=<級別來源>
user=system isPrivApp=true domain=system_app type=system_data_file user=_app seInfo=platform domain=platform_app type=app_data_file
user=system
表示系統應用的 SELinux 用戶為system
,域為system_app
。user=_app
表示普通應用的域為platform_app
(如果是平臺簽名應用)。
- 用途:
- 根據應用的 UID、簽名、包名等分配不同的 SELinux 域。
- 控制應用的權限范圍(如系統應用、平臺應用、普通應用)。
- 注意:
seapp_contexts
是動態分配上下文的關鍵,決定了應用的隔離級別。- 支持的字段包括
isPrivApp
(是否預裝)、seInfo
(簽名信息)、name
(包名)等。
(5) hwservice_contexts
- 作用: 定義硬件抽象層(HAL)服務的 SELinux 安全上下文。
- 位置:
/etc/selinux/targeted/contexts/hwservice_contexts
。 - 格式:
示例:<HAL服務名稱> <上下文>
android.hardware.wifi@1.0-service u:object_r:hal_wifi_default:s0
- 用途:
- 控制對硬件服務的訪問,特別是在 Android 8.0+ 的 Treble 架構中。
- 確保 HAL 服務運行在獨立的 SELinux 域中,防止越權訪問。
- 注意:
- HAL 服務通常運行在獨立的進程中,上下文嚴格隔離。
(6) vndservice_contexts
- 作用: 定義 Vendor(供應商)特定的 Binder 服務上下文。
- 位置:
/vendor/etc/selinux/vndservice_contexts
。 - 格式: 與
service_contexts
類似。 - 用途:
- 為供應商自定義的 Binder 服務分配上下文。
- 通常由設備制造商(OEM)定義。
- 注意:
- 與
service_contexts
類似,但專用于/vendor
分區。
- 與
(7) genfs_contexts
- 作用: 為不支持擴展屬性的文件系統(如 proc、sysfs、tmpfs)定義 SELinux 上下文。
- 位置:
/etc/selinux/targeted/contexts/genfs_contexts
。 - 格式:
示例:<文件系統類型> <路徑> <上下文>
proc /proc/sys u:object_r:proc_sys:s0 sysfs /sys/devices u:object_r:sysfs_devices:s0
- 用途:
- 為特殊文件系統(如
/proc
、/sys
)分配上下文。 - 彌補文件系統不支持擴展屬性的不足。
- 為特殊文件系統(如
- 注意:
- 僅適用于非標準文件系統,普通文件系統使用
file_contexts
。
- 僅適用于非標準文件系統,普通文件系統使用
(8) fs_use_xxx
- 作用: 定義文件系統的 SELinux 掛載方式(
fs_use_task
,fs_use_trans
,fs_use_xattr
)。 - 位置: 通常與
genfs_contexts
一起使用。 - 類型:
fs_use_xattr
: 使用擴展屬性存儲上下文(常見于 ext4)。fs_use_task
: 為任務分配上下文(常用于管道或套接字)。fs_use_trans
: 動態轉換上下文(常用于 tmpfs)。
- 用途:
- 控制文件系統如何與 SELinux 交互。
- 注意:
- 這些規則較少直接修改,通常由系統開發者配置。
8.3 如何使用和修改 xxx_contexts 文件
- 查看上下文:
- 使用
ls -Z
查看文件或目錄的上下文。 - 使用
getprop
查看屬性上下文。
- 使用
- 修改上下文:
- 使用
restorecon
重新應用file_contexts
中的上下文:restorecon /path/to/file
- 自定義上下文需要修改對應的
xxx_contexts
文件,并重新編譯系統鏡像。
- 使用
- 調試:
- 使用
audit2allow
分析 SELinux 拒絕日志(avc: denied
),生成允許規則。
- 使用
- 注意事項:
- 修改
xxx_contexts
文件需要深入了解 SELinux 策略,否則可能導致安全漏洞或系統不穩定。 - Android 的 AOSP 和 Vendor 分區分離后,需分別修改
/system
和/vendor
下的上下文文件。
- 修改
8.4 Android SELinux 上下文文件的模塊化
從 Android 8.0 開始,Google 引入了 Project Treble,SELinux 策略被模塊化,xxx_contexts
文件被拆分為:
- Platform:
/system/etc/selinux/
(AOSP 部分) - Vendor:
/vendor/etc/selinux/
(供應商部分) - ODM:
/odm/etc/selinux/
(設備制造商部分)
例如:
plat_file_contexts
:平臺相關的文件上下文。vendor_file_contexts
:供應商相關的文件上下文。
這些文件在系統啟動時由 init
合并為完整的 file_contexts
。
九、其他
參考鏈接:
domain
https://www.cnblogs.com/ly565911158/p/3622942.html
coredomain
https://www.cnblogs.com/liwugang/p/12433028.html
init_daemon_domain()
由于切換進程域的,進程都是init啟動的,默認和init是相同的權限,所以需要用init_daemon_domain()將進程的域切換到自己的進程域;
https://blog.csdn.net/shell812/article/details/58596377
coredomain和init_daemon_domain()
https://blog.51cto.com/u_2559640/2365798
SELinux安全上下文
https://blog.csdn.net/weixin_34257076/article/details/92710226
SELinux文件屬性
https://blog.csdn.net/weixin_32218919/article/details/116559662
SELinux權限
https://blog.csdn.net/jaczen/article/details/73028302