| #
1.5 |
|
21-Jan-2018 |
maxv |
Unmap the kernel from userland in SVS, and leave only the needed trampolines. As explained below, SVS should now completely mitigate Meltdown on GENERIC kernels, even though it needs some more tweaking for GENERIC_KASLR.
Until now the kernel entry points looked like:
FUNC(intr) pushq $ERR pushq $TRAPNO INTRENTRY ... handle interrupt ... INTRFASTEXIT END(intr)
With this change they are split and become:
FUNC(handle) ... handle interrupt ... INTRFASTEXIT END(handle)
TEXT_USER_BEGIN FUNC(intr) pushq $ERR pushq $TRAPNO INTRENTRY jmp handle END(intr) TEXT_USER_END
A new section is introduced, .text.user, that contains minimal kernel entry/exit points. In order to choose what to put in this section, two macros are introduced, TEXT_USER_BEGIN and TEXT_USER_END.
The section is mapped in userland with normal 4K pages.
In GENERIC, the section is 4K-page-aligned and embedded in .text, which is mapped with large pages. That is to say, when an interrupt comes in, the CPU has the user page tables loaded and executes the 'intr' functions on 4K pages; after calling SVS_ENTER (in INTRENTRY) these 4K pages become 2MB large pages, and remain so when executing in kernel mode.
In GENERIC_KASLR, the section is 4K-page-aligned and independent from the other kernel texts. The prekern just picks it up and maps it at a random address.
In GENERIC, SVS should now completely mitigate Meltdown: what we put in .text.user is not secret.
In GENERIC_KASLR, SVS would have to be improved a bit more: the 'jmp handle' instruction is actually secret, since it leaks the address of the section we are jumping into. By exploiting Meltdown on Intel, this theoretically allows a local user to reconstruct the address of the first text section. But given that our KASLR produces several texts, and that each section is not correlated with the others, the level of protection KASLR provides is still good.
|
| #
1.4 |
|
07-Jan-2018 |
maxv |
Implement a real hotpatch feature.
Define a HOTPATCH() macro, that puts a label and additional information in the new .rodata.hotpatch kernel section. In patch.c, scan the section and patch what needs to be. Now it is possible to hotpatch the content of a macro.
SMAP is switched to use this new system; this saves a call+ret in each kernel entry/exit point.
Many other operating systems do the same.
|
| #
1.3 |
|
14-Nov-2017 |
maxv |
branches: 1.3.2; Split each kernel section into sub-blocks of approximately 2MB. The newly created sections are named .origname.i, for example:
.text -> { .text .text.0 .text.1 .text.2 .text.3 .text.4 }
Each section is randomized independently by the prekern - and in a random order obviously. As a result we can get intertwined mappings, of the type:
+-------+-----------+------+---------+-----------+-------+-------+------+- | text1 | NOTMAPPED | bss0 | rodata1 | NOTMAPPED | data2 | text3 | bss1 | +-------+-----------+------+---------+-----------+-------+-------+------+-
---------+- rodata0 | ... ---------+-
The CTF section is dropped completely, because (a) when split it becomes enormous for some reason (that I don't quite understand, verily), and (b) the kernel expects only one CTF and can't handle several of them.
|
| #
1.1 |
|
09-Nov-2017 |
maxv |
Use another ld script for kaslr kernels, in which there are no alignment directives. They don't matter since the bootloader overwrites them.
But, normally we still need to make sure .data.read_mostly is aligned. Unfortunately I couldn't find any way to force sh_addralign to be 64, so I'm leaving the alignment there as a useless reminder.
|