Re: [PATCH v4 00/20] x86, boot: kaslr cleanup and 64bit kaslr support

From: Kees Cook
Date: Wed Mar 23 2016 - 18:40:44 EST


On Tue, Mar 22, 2016 at 1:25 PM, Kees Cook <keescook@xxxxxxxxxxxx> wrote:
> On Tue, Mar 22, 2016 at 12:31 AM, Baoquan He <bhe@xxxxxxxxxx> wrote:
>> ***Background:
>> Previously a bug is reported that kdump didn't work when kaslr is enabled. During
>> discussing that bug fix, we found current kaslr has a limilation that it can
>> only randomize in 1GB region.
>>
>> This is because in curent kaslr implementaion only physical address of kernel
>> loading is randomized. Then calculate the delta of physical address where
>> vmlinux was linked to load and where it is finally loaded. If delta is not
>> equal to 0, namely there's a new physical address where kernel is actually
>> decompressed, relocation handling need be done. Then delta is added to offset
>> of kernel symbol relocation, this makes the address of kernel text mapping move
>> delta long. Though in principle kernel can be randomized to any physical address,
>> kernel text mapping address space is limited and only 1G, namely as follows on
>> x86_64:
>> [0xffffffff80000000, 0xffffffffc0000000)
>>
>> In one word, kernel text physical address and virtual address randomization is
>> coupled. This causes the limitation.
>>
>> Then hpa and Vivek suggested we should change this. To decouple the physical
>> address and virtual address randomization of kernel text and let them work
>> separately. Then kernel text physical address can be randomized in region
>> [16M, 64T), and kernel text virtual address can be randomized in region
>> [0xffffffff80000000, 0xffffffffc0000000).
>>
>> ***Problems we need solved:
>> - For kernel boot from startup_32 case, only 0~4G identity mapping is built.
>> If kernel will be randomly put anywhere from 16M to 64T at most, the price
>> to build all region of identity mapping is too high. We need build the
>> identity mapping on demand, not covering all physical address space.
>>
>> - Decouple the physical address and virtual address randomization of kernel
>> text and let them work separately.
>>
>> ***Parts:
>> - The 1st part is Yinghai's identity mapping building on demand patches.
>> This is used to solve the first problem mentioned above.
>> (Patch 09-10/19)
>> - The 2nd part is decoupling the physical address and virtual address
>> randomization of kernel text and letting them work separately patches
>> based on Yinghai's ident mapping patches.
>> (Patch 12-19/19)
>> - The 3rd part is some clean up patches which Yinghai found when he reviewed
>> my patches and the related code around.
>> (Patch 01-08/19)
>>
>> ***Patch status:
>> This patchset went through several rounds of review.
>>
>> v1:
>> - The first round can be found here:
>> https://lwn.net/Articles/637115/
>>
>> v1->v2:
>> - In 2nd round Yinghai made a big patchset including this kaslr fix and another
>> setup_data related fix. The link is here:
>> http://lists-archives.com/linux-kernel/28346903-x86-updated-patches-for-kaslr-and-setup_data-etc-for-v4-3.html
>> You can get the code from Yinghai's git branch:
>> git://git.kernel.org/pub/scm/linux/kernel/git/yinghai/linux-yinghai.git for-x86-v4.3-next
>>
>> v2->v3:
>> - It only takes care of the kaslr related patches.
>> For reviewers it's better to discuss only one issue in one thread.
>> * I take off one patch as follows from Yinghai's because I think it's unnecessay.
>> - Patch 05/19 x86, kaslr: rename output_size to output_run_size
>> output_size is enough to represen the value:
>> output_len > run_size ? output_len : run_size
>>
>> * I add Patch 04/19, it's a comment update patch. For other patches, I just
>> adjust patch log and do several places of change comparing with 2nd round.
>> Please check the change log under patch log of each patch for details.
>>
>> * Adjust sequence of several patches to make review easier. It doesn't
>> affect codes.
>>
>> v3->v4:
>> - Made changes according to Kees's comments.
>> Add one patch 20/20 as Kees suggested to use KERNEL_IMAGE_SIZE as offset
>> max of virtual random, meanwhile clean up useless CONFIG_RANDOM_OFFSET_MAX
>>
>> x86, kaslr: Use KERNEL_IMAGE_SIZE as the offset max for kernel virtual randomization
>
> This series is looking good to me. I'm running tests under qemu now,
> and things appear to work as advertised. :) I'll report back once I've
> booted a few hundred times.

My qemu isn't implementing rdrand, so my entropy source is poor, but I
had 7322 successful boots, with 6356 unique physical memory positions
and 487 unique virtual memory positions.

With 48G of physical memory, I'd expect to see more physical positions
(i.e. for a 24M kernel (using 12 slots), avoiding the first 512M (256
slots), I'd expect to see closer to 24308 positions (48G / 2M - 12 -
256)). The 487 is pretty close to the max 512 slots. Still, my entropy
source wasn't great, so that's probably the issue. Getting this
retested with rdrand would be nice. Regardless, no hangs. :)

-Kees

>
> Ingo, what do you think of getting this into the x86 tree for some
> testing in -next? For stuff I haven't already Acked, consider the
> whole series as:
>
> Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx>

--
Kees Cook
Chrome OS & Brillo Security