天天看点

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文件

继续阅读