Module Name: src Committed By: maxv Date: Wed Nov 15 18:02:37 UTC 2017
Modified Files: src/sys/arch/amd64/conf: Makefile.amd64 src/sys/arch/amd64/stand/prekern: elf.c mm.c prekern.h src/sys/arch/x86/x86: pmap.c src/sys/lib/libsa: loadfile_elf32.c Log Message: Support large pages on KASLR kernels, in a way that does not reduce randomness, but on the contrary that increases it. The size of the kernel sub-blocks is changed to be 1MB. This produces a kernel with sections that are always < 2MB in size, that can fit a large page. Each section is put in a 2MB physical chunk. In this chunk, there is a padding of approximately 1MB. The prekern uses a random offset aligned to sh_addralign, to shift the section in physical memory. For example, physical memory layout created by the bootloader for .text.4 and .rodata.0: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ |+---------------+ |+---------------+ | || .text.4 | PAD || .rodata.0 | PAD | |+---------------+ |+---------------+ | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ PA PA+2MB PA+4MB Then, physical memory layout, after having been shifted by the prekern: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ | P +---------------+ | +---------------+ | | A | .text.4 | PAD | PAD | .rodata.0 | PAD | | D +---------------+ | +---------------+ | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ PA PA+2MB PA+4MB The kernel maps these 2MB physical chunks with 2MB large pages. Therefore, randomness is enforced at both the virtual and physical levels, and the resulting entropy is higher than that of our current implementaion until now. The padding around the section is filled by the prekern. Not to consume too much memory, the sections that are smaller than PAGE_SIZE are mapped with normal pages - because there is no point in optimizing them. In these normal pages, the same shift is applied. This change has two additional advantages: (a) the cache attacks based on the TLB are mostly mitigated, because even if you are able to determine that a given page-aligned range is mapped as executable you don't know where exactly within that range the section actually begins, and (b) given that we are slightly randomizing the physical layout we are making some rare physical attacks more difficult to conduct. NOTE: after this change you need to update GENERIC_KASLR / prekern / bootloader. To generate a diff of this commit: cvs rdiff -u -r1.63 -r1.64 src/sys/arch/amd64/conf/Makefile.amd64 cvs rdiff -u -r1.13 -r1.14 src/sys/arch/amd64/stand/prekern/elf.c \ src/sys/arch/amd64/stand/prekern/mm.c cvs rdiff -u -r1.12 -r1.13 src/sys/arch/amd64/stand/prekern/prekern.h cvs rdiff -u -r1.264 -r1.265 src/sys/arch/x86/x86/pmap.c cvs rdiff -u -r1.50 -r1.51 src/sys/lib/libsa/loadfile_elf32.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.