天天看點

Android系統10 RK3399 init程序啟動(二十七) SeAndroid編譯規則目錄

說明

系統:Android10.0

裝置: FireFly RK3399 (ROC-RK3399-PC-PLUS)

前言

本章節重點介紹在Android源碼中, 涉及selinux政策檔案所在目錄和檔案,以及編譯規則

一, selinux政策所在目錄

system/sepolicy/ Android核心公共的政策檔案,上下文檔案
external/selinux 外部 SELinux 項目,用于建構主機環境中編譯 SELinux 政策和标簽所需的各種工具,如提供libselinux庫函數,checkpolicy編譯器(policy.conf編譯成cil檔案),secilc編譯器(cil檔案編譯成二進制)
BOARD_SEPOLICY_DIRS 闆級/供應商定制或擴充的政策檔案

system/sepolicy/:Android核心公共的政策檔案,上下文檔案

tree -L 1 system/sepolicy/

system/sepolicy/

├── Android.bp

├── Android.mk:大部分的編譯目标的規則檔案,會include目前目錄各個mk檔案,如file_contexts.mk等

├── apex

├── build : 提供編譯腳本, 腳本包含了各種編譯指令,如build_cil用于編譯cil檔案

├── CleanSpec.mk

├── definitions.mk :隻定義了transform-policy-to-conf一個函數,将政策檔案轉成conf檔案,生成xx_policy.conf,

本質上是調用m4指令對檔案中的宏進行處理。

├── file_contexts.mk:編譯目标檔案plat_property_context

├── hwservice_contexts.mk

├── mac_permissions.mk

├── policy_version.mk : 指定目前系統API, 如30

├── prebuilts: 提供舊版本的私有和共有政策, 保證系統向下相容,

diff -Nur system/sepolicy/prebuilts/api/29.0/private/   system/sepolicy/private/ 是一樣的。

├── private : 平台私有政策,非平台政策是不能引用和擴充(也可以了解為供應商忽略/不要動)。

├── property_contexts.mk : 編譯目标檔案plat_property_context以及vendor_property_contexts的規則

在out/target/product/rk3399_roc_pc_plus/obj/ETC/plat_property_contexts_intermediates/plat_property_contexts裡面會清楚的标明是由那些檔案編譯出來的。

├── public: 平台公開政策,非平台政策是可以引用和擴充的。

├── README

├── reqd_mask: 包含了上下文中role,user的定義,裡面大部分檔案都是一些模闆,内容是空的。

├── mls

├── property_contexts

├── reqd_mask.te

├── roles

├── roles_decl

├── ......

└── users

├── seapp_contexts.mk

├── service_contexts.mk

├── tests: 測試腳本

├── tools:提供腳本和指令如checkfc檢查上下文檔案文法,sepolicy-check指令用于合并主 seapp_contexts 配置和特定裝置配置的工具,同時檢查配置的有效性

└── vendor: 非平台政策檔案,供應商可以使用的政策和上下文檔案

external/selinux:外部 SELinux 項目,用于建構主機環境中編譯 SELinux 政策和标簽所需的各種工具,如提供libselinux庫函數,checkpolicy編譯器(policy.conf編譯成cil檔案),secilc編譯器(cil檔案編譯成二進制),getenfore/setenfore指令

tree -L 1 external/selinux/

external/selinux/

├── Android.bp

├── checkpolicy : policy.conf編譯成cil檔案

├── CleanSpec.mk

├── dbus

├── gui

├── libselinux : 提供libselinux庫函數, getenfore/setenfore指令

├── libsemanage

├── libsepol: 提供檢查上下文文法的工具和庫函數。

├── Makefile

├── mcstrans

├── MODULE_LICENSE_GPL

├── NOTICE

├── OWNERS

├── policycoreutils: 提供load_policy,chcon等指令

├── prebuilts : 提供audit2allow,sediff等指令

├── python

├── README

├── README.android

├── restorecond

├── sandbox

├── scripts

├── secilc : cil檔案編譯成二進制

└── semodule-utils

 BOARD_SEPOLICY_DIRS : 闆級/供應商定制或擴充的政策檔案,

一般在device/manufacturer/device-name/BoardConfig.mk中指定, 格式為:

BOARD_SEPOLICY_DIRS += device/$SoC/common/sepolicy

BOARD_SEPOLICY_DIRS += device/$SoC/$DEVICE/sepolicy

當然也有BOARD_ODM_SEPOLICY_DIRS和BOARD_ODM_SEPOLICY_DIRS分别指定odm和product分區的政策檔案。

rk3399對應的vendor seplicy檔案目錄為device/rockchip/common/sepolicy,各個産品引用如下

device/rockchip/rk3399/rk3399_roc_pc_plus/rk3399_roc_pc_plus.mk +22

include device/rockchip/common/BoardConfig.mk

# Sepolicy

PRODUCT_SEPOLICY_SPLIT := false

BOARD_SEPOLICY_DIRS ?= \

    device/rockchip/common/sepolicy/vendor

BOARD_PLAT_PUBLIC_SEPOLICY_DIR ?= device/rockchip/common/sepolicy/public

BOARD_PLAT_PRIVATE_SEPOLICY_DIR ?= \

    device/rockchip/common/sepolicy/private \

    device/rockchip/$(TARGET_BOARD_PLATFORM)/sepolicy (實際不存在)

二, Android Selinux總體編譯邏輯

Android編譯的核心規則都是在system/sepolicy/Android.mk定義,可參考官網:

​​建構 SELinux 政策  |  Android 開源項目  |  Android Open Source Project​​

總體編譯步驟如下所說:

# build process for device:

# 1) convert policies to CIL: 将政策轉換為 SELinux 通用中間語言 (CIL) 格式

#    - private + public platform policy to CIL

#    - mapping file to CIL (should already be in CIL form)

#    - non-platform public policy to CIL

#    - non-platform public + private policy to CIL

# 2) attributize policy:公共政策屬性化,并将公共政策作為供應商政策的一部分進行版本控制。

#    - run script which takes non-platform public and non-platform combined

#      private + public policy and produces attributized and versioned

#      non-platform policy

# 3) combine policy files : 合并政策檔案

#    - combine mapping, platform and non-platform policy.

#    - compile output binary policy file

最核心的過程就是:

te政策檔案

----transform-policy-to-conf(m4宏處理)---> 得到conf宏展開并合并檔案

----checkpolicy編譯conf檔案---------------->得到cil通用中間語言檔案 

----secilc工具編譯cil檔案---------------------> 得到目标檔案precompiled_sepolicy二進制

 谷歌官網建構sepolicy政策檔案的圖示:

Android系統10 RK3399 init程式啟動(二十七) SeAndroid編譯規則目錄

Android.mk中指定的編譯源檔案: 

Android系統10 RK3399 init程式啟動(二十七) SeAndroid編譯規則目錄

詳細過程請參考大神: ​​Android P SELinux (二) 開機初始化與政策檔案編譯過程_headwind_的部落格-CSDN部落格​​ 

Android系統10 RK3399 init程式啟動(二十七) SeAndroid編譯規則目錄

Android.mk中比較常見的一個規則:

define build_policy

$(foreach type, $(1), $(foreach file, $(addsuffix /$(type), $(2)), $(sort $(wildcard $(file)))))

endef

參數2,表示一個目标目錄

參數1, 表示在目标目錄下查找的檔案名

調用:

$(call build_policy, file_contexts, $(PLAT_PRIVATE_POLICY))

表示從PLAT_PRIVATE_POLICY目錄中找出所有的file_contexts檔案

繼續閱讀