@@ -30,6 +30,34 @@ extern struct {
extern bool kaslr;
+static void log_hex(efi_system_table_t *sys_table_arg, unsigned long val)
+{
+ const char hex[16] = "0123456789abcdef";
+ char *strp, str[] = "0x0000000000000000";
+ strp = str + 18;
+
+ do {
+ *(--strp) = hex[val & 0xf];
+ } while (val >>= 4);
+
+ efi_printk(sys_table_arg, str);
+}
+
+static void dodgy_get_random_bytes(efi_system_table_t *sys_table)
+{
+ u64 seed;
+ pr_efi(sys_table, "using UNSAFE NON-RANDOM number generator\n");
+
+ asm volatile("mrs %0, cntvct_el0\n" : "=r" (seed));
+
+ pr_efi(sys_table, "Seed is ");
+ log_hex(sys_table, seed);
+ efi_printk(sys_table, "\n");
+
+ efi_rnd.virt_seed = seed;
+ efi_rnd.phys_seed = seed ^ (seed >> 16) ^ (seed >> 32) ^ (seed >> 48);
+}
+
static int efi_get_random_bytes(efi_system_table_t *sys_table)
{
efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
@@ -40,6 +68,7 @@ static int efi_get_random_bytes(efi_system_table_t *sys_table)
(void **)&rng);
if (status == EFI_NOT_FOUND) {
pr_efi(sys_table, "EFI_RNG_PROTOCOL unavailable, no randomness supplied\n");
+ dodgy_get_random_bytes(sys_table);
return EFI_SUCCESS;
}
@@ -77,6 +106,17 @@ static efi_status_t get_dram_top(efi_system_table_t *sys_table_arg, u64 *top)
return EFI_SUCCESS;
}
+static void log_kernel_address(efi_system_table_t *sys_table_arg,
+ unsigned long addr, unsigned long kaslr_addr)
+{
+ pr_efi(sys_table_arg, "KASLR reserve address is ");
+ log_hex(sys_table_arg, kaslr_addr);
+ efi_printk(sys_table_arg, "\n");
+ pr_efi(sys_table_arg, "Loading kernel to physical address ");
+ log_hex(sys_table_arg, addr);
+ efi_printk(sys_table_arg, "\n");
+}
+
efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
unsigned long *image_addr,
unsigned long *image_size,
@@ -90,6 +130,7 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
unsigned long nr_pages;
void *old_image_addr = (void *)*image_addr;
unsigned long preferred_offset;
+ unsigned long kaslr_address = 0;
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
if (kaslr) {
@@ -137,8 +178,9 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
* base. Note that this may give suboptimal results on systems
* with discontiguous DRAM regions with large holes between them.
*/
- *reserve_addr = dram_base +
+ kaslr_address = dram_base +
((dram_top - dram_base) >> 16) * (u16)efi_rnd.phys_seed;
+ *reserve_addr = kaslr_address;
status = efi_call_early(allocate_pages, EFI_ALLOCATE_MAX_ADDRESS,
EFI_LOADER_DATA, nr_pages,
@@ -179,6 +221,9 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table_arg,
}
*image_addr = *reserve_addr + TEXT_OFFSET;
}
+
+ log_kernel_address(sys_table_arg, *image_addr, kaslr_address);
+
memcpy((void *)*image_addr, old_image_addr, kernel_size);
*reserve_size = kernel_memsize;