Home Kernel Address Space Layout Randomization (KASLR)
Post
Cancel

Kernel Address Space Layout Randomization (KASLR)

一、KASLR

内核地址随机化

二、kaslr-seed

地址随机化种子kaslr-seed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
kaslr-seed
-----------

This property is used when booting with CONFIG_RANDOMIZE_BASE as the
entropy used to randomize the kernel image base address location. Since
it is used directly, this value is intended only for KASLR, and should
not be used for other purposes (as it may leak information about KASLR
offsets). It is parsed as a u64 value, e.g.

/ {
	chosen {
		kaslr-seed = <0xfeedbeef 0xc0def00d>;
	};
};

Note that if this property is set from UEFI (or a bootloader in EFI
mode) when EFI_RNG_PROTOCOL is supported, it will be overwritten by
the Linux EFI stub (which will populate the property itself, using
EFI_RNG_PROTOCOL).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
config RANDOMIZE_BASE
	bool "Randomize the address of the kernel image"
	select ARM64_MODULE_PLTS if MODULES
	select RELOCATABLE
	help
	  Randomizes the virtual address at which the kernel image is
	  loaded, as a security feature that deters exploit attempts
	  relying on knowledge of the location of kernel internals.

	  It is the bootloader's job to provide entropy, by passing a
	  random u64 value in /chosen/kaslr-seed at kernel entry.

	  When booting via the UEFI stub, it will invoke the firmware's
	  EFI_RNG_PROTOCOL implementation (if available) to supply entropy
	  to the kernel proper. In addition, it will randomise the physical
	  location of the kernel Image as well.
1
2
kaslr_early_init
	->|get_kaslr_seed

1 EFI_RNG_PROTOCOL

1
2
3
4
efi_entry
    ->|handle_kernel_image
        ->|efi_get_random_bytes
   ->|update_fdt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//driver/firmware/efi/libstub/arm64-stub.c
efi_status_t handle_kernel_image(efi_system_table_t *sys_table_arg, ...) 
{
    	...
    	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
		if (!nokaslr()) {
			status = efi_get_random_bytes(sys_table_arg,
						      sizeof(phys_seed),
						      (u8 *)&phys_seed);
			if (status == EFI_NOT_FOUND) {
				pr_efi(sys_table_arg, "EFI_RNG_PROTOCOL unavailable, no randomness supplied\n");
			} else if (status != EFI_SUCCESS) {
				pr_efi_err(sys_table_arg, "efi_get_random_bytes() failed\n");
				return status;
			}
		} else {
			pr_efi(sys_table_arg, "KASLR disabled on kernel command line\n");
		}
	}
   	...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
efi_status_t efi_get_random_bytes(efi_system_table_t *sys_table_arg,
				  unsigned long size, u8 *out)
{
	efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
	efi_status_t status;
	struct efi_rng_protocol *rng;

	status = efi_call_early(locate_protocol, &rng_proto, NULL,
				(void **)&rng);
	if (status != EFI_SUCCESS)
		return status;

	return rng->get_rng(rng, NULL, size, out);
}

1> locate_protocol

https://blog.csdn.net/yhb1047818384/article/details/86513351

2> head.S

https://zhuanlan.zhihu.com/p/99557658

This post is licensed under CC BY 4.0 by the author.