thinkphp企业网站系统,网站视觉艺术设计及色彩搭配,安顺住房和城乡建设部网站,企业局域网的规划与设计实现并没有成功#xff0c;只是记录过程#xff0c;使用4.9内核尝试开启过程 关于
控制流完整性 (CFI) 是一种安全机制#xff0c;它不允许更改已编译二进制文件的原始控制流图#xff0c;因而执行此类攻击变得异常困难。 在 Android 9 中#xff0c;我们在更多组件以及内… 实现并没有成功只是记录过程使用4.9内核尝试开启过程 关于
控制流完整性 (CFI) 是一种安全机制它不允许更改已编译二进制文件的原始控制流图因而执行此类攻击变得异常困难。 在 Android 9 中我们在更多组件以及内核中启用了 LLVM 的 CFI 实现。系统 CFI 默认处于启用状态但内核 CFI 需要您手动启用。 LLVM 的 CFI 需要使用链接时优化 (LTO) 进行编译。LTO 会一直保留对象文件的 LLVM 位码表示法直至链接时以便编译器更好地推断可以执行哪些优化。启用 LTO 可缩减最终二进制文件的大小并提高性能但会增加编译时间。在 Android 上进行测试时结合使用 LTO 和 CFI 对代码大小和性能开销的影响微乎其微在少数情况下这两者都会有所改善。 如需了解有关 CFI 以及如何处理其他前向控制检查的更多技术详情请参阅 LLVM 设计文档。
实现
Android 通用内核 4.9 和 4.14 版本中提供对内核 CFI 的支持。如果您的内核基于 4.9 或 4.14 版本且使用 Clang 进行构建那么您可以启用它。如需启用 kCFI您需要复制相关补丁程序并更新内核配置文件。
复制 kCFI 补丁程序
将以下更改添加到您的内核
启用 kCFI
复制相关更改后您需要在内核配置文件中启用 kCFI例如 /kernel/PROJECT//BRANCH/arch/arm64/configs/PROJECT_defconfig。
如需启用 kCFI请添加以下行
CONFIG_LTO_CLANGy
CONFIG_CFI_CLANGy
如需协助调试 CFI 故障请启用 CONFIG_CFI_PERMISSIVE它会输出警告(而不会导致内核崩溃)。切勿在正式版中使用宽容模式。
追踪
CONFIG_CFI_CLANG 配置在 kernel-4.9/arch/Kconfig CFI_CLANG 依赖 LTO_CLANG 和 KALLSYMS LTO_CLANG 描述是使用 clang 编译现在使用的是 gcc 编译器
//kernel-4.9/arch/Kconfig
config LTO_CLANGbool Use clang Link Time Optimization (LTO) (EXPERIMENTAL)depends on ARCH_SUPPORTS_LTO_CLANGdepends on !FTRACE_MCOUNT_RECORD || HAVE_C_RECORDMCOUNTselect LTOselect THIN_ARCHIVESselect LD_DEAD_CODE_DATA_ELIMINATIONhelpThis option enables clangs Link Time Optimization (LTO), which allowsthe compiler to optimize the kernel globally at link time. If youenable this option, the compiler generates LLVM IR instead of objectfiles, and the actual compilation from IR occurs at the LTO link step,which may take several minutes.If you select this option, you must compile the kernel with clang 5.0 (make CCclang) and GNU gold from binutils 2.27, and have theLLVMgold plug-in in LD_LIBRARY_PATH.endchoiceconfig CFIboolconfig CFI_PERMISSIVEbool Use CFI in permissive modedepends on CFIhelpWhen selected, Control Flow Integrity (CFI) violations result in awarning instead of a kernel panic. This option is useful for findingCFI violations in drivers during development.config CFI_CLANGbool Use clang Control Flow Integrity (CFI) (EXPERIMENTAL)depends on LTO_CLANGdepends on KALLSYMSselect CFIhelpThis option enables clang Control Flow Integrity (CFI), which addsruntime checking for indirect function calls.配置后在文件 out/xxx/obj/KERNAK_OBJ/.config
//out/xxx/obj/KERNAK_OBJ/.config
CONFIG_LTOy
CONFIG_ARCH_SUPPORTS_LTO_CLANGy
# CONFIG_LTO_NONE is not set
CONFIG_LTO_CLANGy
CONFIG_CFIy
CONFIG_CFI_PERMISSIVEy
CONFIG_CFI_CLANGy
CONFIG_CFI_CLANG_SHADOWy使用 make 命令编译出现报错报错 Cannot use CONFIG_LTO_CLANG: requires clang 5.0 or later位于 kernel-4.9/Makefile
//kernel-4.9/scripts/Kbuild.include
# cc-name
# Expands to either gcc or clang
cc-name $(shell $(CC) -v 21 | grep -q clang version echo clang || echo gcc)# 打印出 $(CC) /home/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-gcc
# $(cc-name) gcc# __cc-version
# Returns compiler version
__cc-version $(shell $(CONFIG_SHELL) $(srctree)/scripts/$(cc-name)-version.sh $(CC))
## $(__cc-version) 0409# __cc-ifversion
# Matches compiler name and version
# Usage: EXTRA_CFLAGS $(call cc-if-name-version, gcc, -lt, 0402, -O1)
__cc-ifversion $(shell [ $(cc-name) $(1) ] [ $(__cc-version) $(2) $(3) ] echo $(4) || echo $(5))# clang-ifversion
clang-ifversion $(call __cc-ifversion, clang, $(1), $(2), $(3), $(4))//kernel-4.9/Makefile
# Make sure were using a supported toolchain with LTO_CLANG
ifdef CONFIG_LTO_CLANGifneq ($(call clang-ifversion, -ge, 0500, y), y)echo Cannot use CONFIG_LTO_CLANG: requires clang 5.0 or later 2 exit 1endififneq ($(call gold-ifversion, -ge, 112000000, y), y)echo Cannot use CONFIG_LTO_CLANG: requires GNU gold 1.12 or later 2 exit 1endif尝试修改 $(CC) 值也是无效的
export PATH/home/prebuilts/clang/host/linux-x86/clang-4053586/bin:/home/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin:/home/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin:${PATH}export ARCHarm64
export CLANG_TRIPLEaarch64-linux-gnu-
export CROSS_COMPILE/home/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-
export CROSS_COMPILE_ARM32/home/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-
export CC/home/prebuilts/clang/host/linux-x86/clang-4053586/bin/clangmake Oout ARCHarm64 CCclang CLANG_TRIPLEaarch64-linux-gnu- CROSS_COMPILEaarch64-linux-android-发现有文件 kernel-4.9/build.config.cuttlefish.aarch64 不知道干什么用的但是这些参数确实是我们希望设置的参数
//kernel-4.9/build.config.cuttlefish.aarch64
ARCHarm64
BRANCHandroid-4.9
CLANG_TRIPLEaarch64-linux-gnu-
CROSS_COMPILEaarch64-linux-androidkernel-
DEFCONFIGcuttlefish_defconfig
EXTRA_CMDS
KERNEL_DIRcommon
POST_DEFCONFIG_CMDScheck_defconfig
CLANG_PREBUILT_BINprebuilts-master/clang/host/linux-x86/clang-r353983c/bin
LINUX_GCC_CROSS_COMPILE_PREBUILTS_BINprebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin
FILES
arch/arm64/boot/Image.gz
vmlinux
System.mapSTOP_SHIP_TRACEPRINTK1那查看 $(CC) 值如何组成export 的值就是为了替换实际上 $(CC) 还是gcc 没用起作用
//kernel-4.9/Makefile
# Cross compiling and selecting different set of gcc/bin-utils
# ---------------------------------------------------------------------------
#
# When performing cross compilation for other architectures ARCH shall be set
# to the target architecture. (See arch/* for the possibilities).
# ARCH can be set during invocation of make:
# make ARCHia64
# Another way is to have ARCH set in the environment.
# The default ARCH is the host where make is executed.# CROSS_COMPILE specify the prefix used for all executables used
# during compilation. Only gcc and related bin-utils executables
# are prefixed with $(CROSS_COMPILE).
# CROSS_COMPILE can be set on the command line
# make CROSS_COMPILEia64-linux-
# Alternatively CROSS_COMPILE can be set in the environment.
# A third alternative is to store a setting in .config so that plain
# make in the configured kernel build directory always uses that.
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
ARCH ? $(SUBARCH)
CROSS_COMPILE ? $(CONFIG_CROSS_COMPILE:%%)
CC $(CROSS_COMPILE)gcc编译后从 out/xxx/include/generated/compile.h 确认编译器信息
/* This file is auto generated, version 1 */
/* SMP PREEMPT */
#define UTS_MACHINE aarch64
#define UTS_VERSION #1 SMP PREEMPT Fri May 12 09:50:19 CST 2023
#define LINUX_COMPILE_BY username
#define LINUX_COMPILE_HOST ubuntu16
#define LINUX_COMPILER gcc version 4.9.x 20150123 (prerelease) (GCC) 假如将 $(CC) 写死呢
//kernel-4.9/Makefile
# CC $(CROSS_COMPILE)gcc
CC/home/prebuilts/clang/host/linux-x86/clang-4479392/bin/clang编译下来还是报错
参考文章 Building Linux with Clang/LLVM Compiling an Android kernel with Clang Hines-CompilingAndroidKeynote.pdf Android从零开始的内核编译