for (i = 0; i < size / sizeof(hash); i++) { /* Rotate by odd number of bits and XOR. */
hash = (hash << ((sizeof(hash) * 8) - 7)) | (hash >> 7);
hash ^= ptr[i];
}
return hash;
}
/* Attempt to create a simple starting entropy. This can make it defferent for * every build but it is still not enough. Stronger entropy should * be added to make it change for every boot.
*/ staticunsignedlong __init get_boot_seed(void *fdt)
{ unsignedlong hash = 0;
/* check for overlap with /memreserve/ entries */ for (i = 0; i < fdt_num_mem_rsv(fdt); i++) { if (fdt_get_mem_rsv(fdt, i, &base, &size) < 0) continue; if (regions_overlap(start, end, base, base + size)) returntrue;
}
if (regions.reserved_mem < 0) returnfalse;
/* check for overlap with static reservations in /reserved-memory */ for (subnode = fdt_first_subnode(fdt, regions.reserved_mem);
subnode >= 0;
subnode = fdt_next_subnode(fdt, subnode)) { const fdt32_t *reg;
u64 rsv_end;
len = 0;
reg = fdt_getprop(fdt, subnode, "reg", &len); while (len >= (regions.reserved_mem_addr_cells +
regions.reserved_mem_size_cells)) {
base = fdt32_to_cpu(reg[0]); if (regions.reserved_mem_addr_cells == 2)
base = (base << 32) | fdt32_to_cpu(reg[1]);
reg += regions.reserved_mem_addr_cells;
len -= 4 * regions.reserved_mem_addr_cells;
/* * Retrieve (and wipe) the seed from the FDT
*/
seed = get_kaslr_seed(dt_ptr); if (seed)
random = rotate_xor(random, &seed, sizeof(seed)); else
pr_warn("KASLR: No safe seed for randomizing the kernel base.\n");
/* If the linear size is smaller than 64M, do not randomize */ if (linear_sz < SZ_64M) return 0;
/* check for a reserved-memory node and record its cell sizes */
regions.reserved_mem = fdt_path_offset(dt_ptr, "/reserved-memory"); if (regions.reserved_mem >= 0)
get_cell_sizes(dt_ptr, regions.reserved_mem,
®ions.reserved_mem_addr_cells,
®ions.reserved_mem_size_cells);
/* * To see if we need to relocate the kernel to a random offset * void *dt_ptr - address of the device tree * phys_addr_t size - size of the first memory block
*/
notrace void __init kaslr_early_init(void *dt_ptr, phys_addr_t size)
{ unsignedlong tlb_virt;
phys_addr_t tlb_phys; unsignedlong offset; unsignedlong kernel_sz;
/* Create kernel map to relocate in */
create_kaslr_tlb_entry(1, tlb_virt, tlb_phys);
}
/* Copy the kernel to its new location and run */
memcpy((void *)kernstart_virt_addr, (void *)_stext, kernel_sz);
flush_icache_range(kernstart_virt_addr, kernstart_virt_addr + kernel_sz);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.