Re: [PATCH 0/6] randomize kernel physical address and virtual address separately

From: Andy Lutomirski
Date: Sun Feb 01 2015 - 08:15:12 EST


On Sun, Feb 1, 2015 at 12:10 AM, Baoquan He <bhe@xxxxxxxxxx> wrote:
> On 01/20/15 at 08:19pm, Andy Lutomirski wrote:
>> On 01/20/2015 07:37 PM, Baoquan He wrote:
>>
>> I have no idea what the #PF thing you're referring to is, but I have
>> code to implement a #PF handler in boot/compressed if it would be
>> helpful. It's two patches:
>>
>> https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/commit/?h=sync_rand_seed&id=89476ea6a2becbaee4f45c3b6689ff31b6aa959a
>>
>> https://git.kernel.org/cgit/linux/kernel/git/luto/linux.git/commit/?h=sync_rand_seed&id=142d86921e6f271261584016fc8cfa5cdbf455ba
>>
>> You can't recover from a page fault in my version of this code, but that
>> would be straightforward to add.
>>
> Hi all,
>
> I used Andy's patch to setup idt and implement #PF handler before kernel
> decompression, and it works. Then a problem is encountered that when
> choose a position above 4G and decompress kernel there system will
> reboot to BIOS after kernel decompression. I use hlt command to position
> where the asm code will cause that reboot and found it happened after
> jumping when adjusted page table is loaded in arch/x86/kernel/head_64.S

I applied this to Linus' tree today, and I get:

early console in decompress_kernel
KASLR disabled by default...

Decompressing Linux...

XZ-compressed data is corrupt

-- System halted

If I comment out the output = 0x140000000 line, then it boots.

With gzip instead of XZ, it just gets stuck at Decompressing Linux...

Presumably this is because 0x140000000 is an invalid address in my VM.
I added more RAM, and I get a nice reboot loop. QEMU thinks that it's
a page fault causing a triple fault.

If I add in my IDT code and #PF handler, nothing changes. If I
re-enable relocations, I get:

32-bit relocation outside of kernel!

Can you post the whole set of patches you're using or a link to a git tree?

>
> /* Setup early boot stage 4 level pagetables. */
> addq phys_base(%rip), %rax
> movq %rax, %cr3
>
> /* Ensure I am executing from virtual addresses */
> movq $1f, %rax
> jmp *%rax
> 1:
>
> /* Check if nx is implemented */
> movl $0x80000001, %eax
> cpuid
> movl %edx,%edi
>
> Now I doubt gdt table is not approporiate when extend identity mapping
> to be above 4G in arch/x86/boot/compressed/head_64.S. As far as I
> understand, that gdt is a gdt with the 64bit segments using 32bit
> descriptor, still has attribute of segment base addr and limit. I wrote
> a simple patch to debug this, but still don't know how to make it work,
> does anyone can help or point out what I should do to make it work?
>
>
> From 40a550ad94ca5927586fb85d3419200dbea9ebd8 Mon Sep 17 00:00:00 2001
> From: Baoquan He <bhe@xxxxxxxxxx>
> Date: Sun, 1 Feb 2015 07:42:09 +0800
> Subject: [PATCH] extend the identity mapping to 8G
> This patch add 4 more pages as pmd directory tables to extend the
> identity mapping to cover 8G. And hardcode the position to 5G where
> kernel will be relocated and decompressed. Meanwhile commented out
> the relocation handling calling.
>
> Signed-off-by: Baoquan He <bhe@xxxxxxxxxx>
> ---
> arch/x86/boot/compressed/head_64.S | 8 ++++----
> arch/x86/boot/compressed/misc.c | 3 +++
> 2 files changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
> index 6b1766c..74da678 100644
> --- a/arch/x86/boot/compressed/head_64.S
> +++ b/arch/x86/boot/compressed/head_64.S
> @@ -123,7 +123,7 @@ ENTRY(startup_32)
> /* Initialize Page tables to 0 */
> leal pgtable(%ebx), %edi
> xorl %eax, %eax
> - movl $((4096*6)/4), %ecx
> + movl $((4096*10)/4), %ecx
> rep stosl
>
> /* Build Level 4 */
> @@ -134,7 +134,7 @@ ENTRY(startup_32)
> /* Build Level 3 */
> leal pgtable + 0x1000(%ebx), %edi
> leal 0x1007(%edi), %eax
> - movl $4, %ecx
> + movl $8, %ecx
> 1: movl %eax, 0x00(%edi)
> addl $0x00001000, %eax
> addl $8, %edi
> @@ -144,7 +144,7 @@ ENTRY(startup_32)
> /* Build Level 2 */
> leal pgtable + 0x2000(%ebx), %edi
> movl $0x00000183, %eax
> - movl $2048, %ecx
> + movl $4096, %ecx
> 1: movl %eax, 0(%edi)
> addl $0x00200000, %eax
> addl $8, %edi
> @@ -476,4 +476,4 @@ boot_stack_end:
> .section ".pgtable","a",@nobits
> .balign 4096
> pgtable:
> - .fill 6*4096, 1, 0
> + .fill 10*4096, 1, 0
> diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
> index a950864..47c8c80 100644
> --- a/arch/x86/boot/compressed/misc.c
> +++ b/arch/x86/boot/compressed/misc.c
> @@ -404,6 +404,7 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
> output = choose_kernel_location(input_data, input_len, output,
> output_len > run_size ? output_len
> : run_size);
> + output = 0x140000000;
>
> /* Validate memory location choices. */
> if ((unsigned long)output & (MIN_KERNEL_ALIGN - 1))
> @@ -427,8 +428,10 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
> * 32-bit always performs relocations. 64-bit relocations are only
> * needed if kASLR has chosen a different load address.
> */
> +#if 0
> if (!IS_ENABLED(CONFIG_X86_64) || output != output_orig)
> handle_relocations(output, output_len);
> +#endif
> debug_putstr("done.\nBooting the kernel.\n");
> return output;
> }
> --
> 1.9.3
>
>
>



--
Andy Lutomirski
AMA Capital Management, LLC
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/