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

From: Baoquan He
Date: Mon Feb 02 2015 - 04:36:52 EST


On 02/01/15 at 05:13am, Andy Lutomirski wrote:
> 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.

Thanks a lot for help, Andy.

Currently in boot/compressed/head_64.S, 6 page tables are used to build
the identity mapping in 0~4G area, 1 page used for pgd table, 1 page
used for pud table, and left 4 pgaes used for pmd table. So I added 4
more pages for pmd table, then it cover 0~8G area. So during kernel
decompressing, if trying to reload kernel to be above 4G, physical
memory have to be larger than 4G. So you can set output=0x100000000,
then you only need 4.5G memory.

Then if you add below 2 lines of code, you will see the output messgae
from screen : "Booting the kernel."


diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index a468c0a..1c039a5 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -181,6 +181,10 @@ ENTRY(secondary_startup_64)
movl $(X86_CR4_PAE | X86_CR4_PGE), %ecx
movq %rcx, %cr4

+/*This is used to position where the kernel will reboot to bios*/
+1: hlt
+ jmp 1b
+
/* Setup early boot stage 4 level pagetables. */
addq phys_base(%rip), %rax
movq %rax, %cr3

>
> 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!

Here is a code bug which is fixed by my posted patch 2/6:
a bug that relocation can not be handled when kernel is loaded above 2G

So now I use the debug patch in last mail to debug how to make kernel
move to above 4G position and be decompressed there. So I just the
comment out the handle_relocations() calling. Actually the debug patch
can filter unncecessary interference.

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

I am creating a repo on git hub and push my patchset, then it can be got
publicly. Will send it as soon as it's finished.

Btw, I didn't try xz, just always bzImage.


Thanks
Baoquan

--
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/