Re: [Query] PAGE_OFFSET on KASLR enabled ARM64 kernel

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

 



On 27 May 2018 at 23:03, Bhupesh Sharma <bhsharma@xxxxxxxxxx> wrote:
> Hi ARM64 maintainers,
>
> I am confused about the PAGE_OFFSET value (or the start of the linear
> map) on a KASLR enabled ARM64 kernel that I am seeing on a board which
> supports a compatible EFI firmware (with EFI_RNG_PROTOCOL support).
>
> 1. 'arch/arm64/include/asm/memory.h' defines PAGE_OFFSET as:
>
> /*
>  * PAGE_OFFSET - the virtual address of the start of the linear map (top
>  *         (VA_BITS - 1))
>  */
> #define PAGE_OFFSET        (UL(0xffffffffffffffff) - \
>     (UL(1) << (VA_BITS - 1)) + 1)
>
> So for example on a platform with VA_BITS=48, we have:
> PAGE_OFFSET = 0xffff800000000000
>
> 2. However, for the KASLR case, we set the 'memstart_offset_seed ' to
> use the 16-bits of the 'kaslr-seed' to randomize the linear region in
> 'arch/arm64/kernel/kaslr.c' :
>
> u64 __init kaslr_early_init(u64 dt_phys)
> {
> <snip..>
>     /* use the top 16 bits to randomize the linear region */
>     memstart_offset_seed = seed >> 48;
> <snip..>
> }
>
> 3. Now, we use the 'memstart_offset_seed' value to randomize the
> 'memstart_addr' value in 'arch/arm64/mm/init.c':
>
> void __init arm64_memblock_init(void)
> {
> <snip..>
>
>     if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) {
>         extern u16 memstart_offset_seed;
>         u64 range = linear_region_size -
>                 (memblock_end_of_DRAM() - memblock_start_of_DRAM());
>
>         /*
>          * If the size of the linear region exceeds, by a sufficient
>          * margin, the size of the region that the available physical
>          * memory spans, randomize the linear region as well.
>          */
>         if (memstart_offset_seed > 0 && range >= ARM64_MEMSTART_ALIGN) {
>             range = range / ARM64_MEMSTART_ALIGN + 1;
>             memstart_addr -= ARM64_MEMSTART_ALIGN *
>                      ((range * memstart_offset_seed) >> 16);
>         }
>     }
> <snip..>
> }
>
> 4. Since 'memstart_addr' indicates the start of physical RAM, we
> randomize the same on basis of 'memstart_offset_seed' value above.
> Also the 'memstart_addr' value is available in '/proc/kallsyms' and
> hence can be accessed by user-space applications to read the
> 'memstart_addr' value.
>
> 5. Now since the PAGE_OFFSET value is also used by several user space
> tools (for e.g. makedumpfile tool uses the same to determine the start
> of linear region and hence to read PT_NOTE fields from /proc/kcore), I
> am not sure how to read the randomized value of the same in the KASLR
> enabled case.
>
> 6. Reading the code further and adding some debug prints, it seems the
> 'memblock_start_of_DRAM()' value is more closer to the actual start of
> linear region rather than 'memstart_addr' and 'PAGE_OFFSET" in case of
> KASLR enabled kernel:
>
> [root@qualcomm-amberwing] # dmesg | grep -i "arm64_memblock_init" -A 5
>
> [    0.000000] inside arm64_memblock_init, memstart_addr = ffff976a00000000,
> linearstart_addr = ffffe89600200000, memblock_start_of_DRAM = ffffe89600200000,
> PHYS_OFFSET = ffff976a00000000, PAGE_OFFSET = ffff800000000000,
> KIMAGE_VADDR = ffff000008000000, kimage_vaddr = ffff20c2d7800000
>
> [root@qualcomm-amberwing] # dmesg | grep -i "Virtual kernel memory layout" -A 15
> [    0.000000] Virtual kernel memory layout:
> [    0.000000]     modules : 0xffff000000000000 - 0xffff000008000000
> (   128 MB)
> [    0.000000]     vmalloc : 0xffff000008000000 - 0xffff7bdfffff0000
> (126847 GB)
> [    0.000000]       .text : 0xffff20c2d7880000 - 0xffff20c2d8040000
> (  7936 KB)
> [    0.000000]     .rodata : 0xffff20c2d8040000 - 0xffff20c2d83a0000
> (  3456 KB)
> [    0.000000]       .init : 0xffff20c2d83a0000 - 0xffff20c2d8750000
> (  3776 KB)
> [    0.000000]       .data : 0xffff20c2d8750000 - 0xffff20c2d891b200
> (  1837 KB)
> [    0.000000]        .bss : 0xffff20c2d891b200 - 0xffff20c2d90a5198
> (  7720 KB)
> [    0.000000]     fixed   : 0xffff7fdffe790000 - 0xffff7fdffec00000
> (  4544 KB)
> [    0.000000]     PCI I/O : 0xffff7fdffee00000 - 0xffff7fdfffe00000
> (    16 MB)
> [    0.000000]     vmemmap : 0xffff7fe000000000 - 0xffff800000000000
> (   128 GB maximum)
> [    0.000000]               0xffff7ffa25800800 - 0xffff7ffa2b800000
> (    95 MB actual)
> [    0.000000]     memory  : 0xffffe89600200000 - 0xffffe8ae00000000
> ( 98302 MB)
>
> As one can see above, the 'memblock_start_of_DRAM()' value of
> 0xffffe89600200000 represents the start of linear region:
>
> [    0.000000]     memory  : 0xffffe89600200000 - 0xffffe8ae00000000
> ( 98302 MB)
>
> So, my question is to access the start of linear region (which was
> earlier determinable via PAGE_OFFSET macro), whether I should:
>
> - do some back-computation for the start of linear region from the
> 'memstart_addr' in user-space, or
> - use a new global variable in kernel which is assigned the value of
> memblock_start_of_DRAM()' and assign it to '/proc/kallsyms', so that
> it can be read by user-space tools, or
> - whether we should rather look at removing the PAGE_OFFSET usage from
> the kernel and replace it with a global variable instead which is
> properly updated for KASLR case as well.
>
> Kindly share your opinions on what can be a suitable solution in this case.
>
> Thanks for your help.
>

Hello Bhupesh,

Could you explain what the relevance is of PAGE_OFFSET to userland?
The only thing that should matter is where the actual linear mapping
of DRAM is, and I am not sure I understand why we care about where it
resides relative to the base of the linear region.

_______________________________________________
kexec mailing list
kexec@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/kexec



[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux