Source-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: src/sys



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.




Home | Main Index | Thread Index | Old Index