ti-j7200 平台KASLR问题
经过调查确认821需要u-boot配合支持才能实现KASLR,目前uboot不支持KASLR
调查经过:
5.10内核ARM64 开启KASLR功能的话需要打开CONFIG_RANDOMIZE_BASE,
每次start_kernel的运行地址是要加上一个随机偏移,偏移由kaslr_early_init返回
以此达到地址随机化目的。
#ifdef CONFIG_RANDOMIZE_BASE
tst x23,
~(MIN_KIMG_ALIGN - 1) // already running
randomized?
b.ne 0f
mov x0,
x21
// pass FDT address in x0
bl
kaslr_early_init
// parse FDT for KASLR options
cbz x0,
0f
// KASLR disabled? just proceed
orr x23,
x23,
x0
// record KASLR offset
ldp x29,
x30, [sp],
#16 //
we must enable KASLR, return
ret
// to __primary_switch()
0:
#endif
add sp, sp,
#16
mov x29, #0
mov x30, #0
b start_kernel
kaslr_early_init提供偏移的方式是从DTS中获取一个随机种子seed(get_kaslr_seed)或者从CPU获取(arch_get_random_seed_long_early)
/*
* Retrieve (and wipe) the seed from the FDT
*/
seed = get_kaslr_seed(fdt);
/*
* Check if 'nokaslr' appears on the command line, and
* return 0 if that is the case.
*/
cmdline = kaslr_get_cmdline(fdt);
str = strstr(cmdline, "nokaslr");
if
(str == cmdline || (str > cmdline && *(str - 1) == ' ')) {
kaslr_status = KASLR_DISABLED_CMDLINE;
return 0;
}
/*
* Mix in any entropy obtainable architecturally if enabled
* and supported.
*/
if
(arch_get_random_seed_long_early(&raw))
seed ^= raw;
if
(!seed) {
kaslr_status = KASLR_DISABLED_NO_SEED;
return 0;
}
经过确认821 CPU没有提供RNDR随机数寄存器,参考下列AArch64 Instruction Set
Attribute Register 0,无法提供seed,所以我们的系统中只有DTS提供seed
但是DTS中提供的seed是固定的,所以每次重启偏移是固定的
进一步调查uboot实现,如下所示uboot会提供随机数sec_firmware_get_random然后更新DTS中的随机种子seed,这样就确保偏移是随机的。
但是需要CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT,目前Ti的预编译的uboot是不支持该特性的,打开该配置后编译不通过,需要配套实现
CONFIG_SYS_MEM_RESERVE_SECURE,但是目前的uboot没有提供该功能。
int fdt_fixup_kaslr(void *fdt)
{
int nodeoffset;
int err, ret = 0;
u8 rand[8];
#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT)
/* Check if random seed generation is supported */
if (sec_firmware_support_hwrng() == false) {
printf("WARNING: SEC firmware
not running, no kaslr-seed\n");
return 0;
}
ret = sec_firmware_get_random(rand,
8);
if (ret < 0) {
printf("WARNING: No random
number to set kaslr-seed\n");
return 0;
}
err = fdt_check_header(fdt);
if (err < 0) {
printf("fdt_chosen: %s\n",
fdt_strerror(err));
return 0;
}
/* find or create "/chosen" node. */
nodeoffset = fdt_find_or_add_subnode(fdt,
0, "chosen");
if (nodeoffset < 0)
return 0;
err = fdt_setprop(fdt, nodeoffset, "kaslr-seed",
rand,
sizeof(rand));
if (err < 0) {
printf("WARNING: can't set
kaslr-seed %s.\n",
fdt_strerror(err));
return 0;
}
ret = 1;
#endif
更新:
从下述看即使uboot可以编译通过,KASLR还是不能实现。
“
arm64平台实现KASLR的总体思路是通过trustzone运行一个sec firmware,sec firmware会负责生成kaslr-seed,也就是用来计算内核偏移的随机种子。其中,sec firmware的加载工作由u-boot负责执行,u-boot通过ppa(可以理解为trustzone中的一个应用,用来将sec frimware加载到trust总额中运行)将sec firmware(如teeOS.bin)加载到trustzone中运行,然后在fdt_fixup的过程中调用sec firmware生成kaslr-seed,并将这个值设置到对应的fdt。
整个实现思路的安全主旨就是通过trustzone来生成随机数,以保证随机数的安全性,进而保证内核地址的随机性。但在我们使用的平台上没有实现trustzone,ppa也不会生成和运行,因而导致虽然我们开启了必须的配置,但实际的业务逻辑并不支持KASLR的运行,所以必须在现有平台上重新构建安全地生成随机数的逻辑。“
参考:
https://blog.csdn.net/andlee/article/details/121014664
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步