Re: [PATCH v9 2/2] x86/boot/KASLR: Restrict kernel to be randomized in mirror regions

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

 



On 17 August 2017 at 14:04, Baoquan He <bhe@xxxxxxxxxx> wrote:
> On 08/14/17 at 10:54pm, Baoquan He wrote:
>> Currently KASLR will parse all e820 entries of RAM type and add all
>> candidate position into slots array. Then we will choose one slot
>> randomly as the new position which kernel will be decompressed into
>> and run at.
>>
>> On system with EFI enabled, e820 memory regions are coming from EFI
>> memory regions by combining adjacent regions. While these EFI memory
>> regions have more attributes to mark their different use. Mirror
>> attribute is such kind. The physical memory region whose descriptors
>> in EFI memory map has EFI_MEMORY_MORE_RELIABLE attribute (bit: 16) are
>> mirrored. The address range mirroring feature of kernel arranges such
>> mirror region into normal zone and other region into movable zone. And
>> with mirroring feature enabled, the code and date of kernel can only be
>> located in more reliable mirror region. However, the current KASLR code
>> doesn't check EFI memory entries, and could choose new position in
>> non-mirrored region. This will break the functionality of the address
>> range mirroring feature.
>
> Thanks a lot for helping improving the patch log, Ingo! Will pay more
> attention to the description in words and paragraph partition of log.
>
>>
>> So if EFI is detected, iterate EFI memory map and pick the mirror region
>> to process for adding candidate of randomization slot. If EFI is disabled
>> or no mirror region found, still process e820 memory map.
>>
>> Signed-off-by: Baoquan He <bhe@xxxxxxxxxx>


Could the x86 people on cc either take these directly, or indicate
whether they are ok with this going in via the EFI tree?

Thanks.

>> ---
>>  arch/x86/boot/compressed/kaslr.c | 68 ++++++++++++++++++++++++++++++++++++++--
>>  1 file changed, 66 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c
>> index 99c7194f7ea6..7de23bb279ce 100644
>> --- a/arch/x86/boot/compressed/kaslr.c
>> +++ b/arch/x86/boot/compressed/kaslr.c
>> @@ -37,7 +37,9 @@
>>  #include <linux/uts.h>
>>  #include <linux/utsname.h>
>>  #include <linux/ctype.h>
>> +#include <linux/efi.h>
>>  #include <generated/utsrelease.h>
>> +#include <asm/efi.h>
>>
>>  /* Macros used by the included decompressor code below. */
>>  #define STATIC
>> @@ -558,6 +560,65 @@ static void process_mem_region(struct mem_vector *entry,
>>       }
>>  }
>>
>> +#ifdef CONFIG_EFI
>> +/*
>> + * Returns true if mirror region found (and must have been processed
>> + * for slots adding)
>> + */
>> +static bool
>> +process_efi_entries(unsigned long minimum, unsigned long image_size)
>> +{
>> +     struct efi_info *e = &boot_params->efi_info;
>> +     bool efi_mirror_found = false;
>> +     struct mem_vector region;
>> +     efi_memory_desc_t *md;
>> +     unsigned long pmap;
>> +     char *signature;
>> +     u32 nr_desc;
>> +     int i;
>> +
>> +     signature = (char *)&e->efi_loader_signature;
>> +     if (strncmp(signature, EFI32_LOADER_SIGNATURE, 4) &&
>> +         strncmp(signature, EFI64_LOADER_SIGNATURE, 4))
>> +             return false;
>> +
>> +#ifdef CONFIG_X86_32
>> +     /* Can't handle data above 4GB at this time */
>> +     if (e->efi_memmap_hi) {
>> +             warn("EFI memmap is above 4GB, can't be handled now on x86_32. EFI should be disabled.\n");
>> +             return false;
>> +     }
>> +     pmap =  e->efi_memmap;
>> +#else
>> +     pmap = (e->efi_memmap | ((__u64)e->efi_memmap_hi << 32));
>> +#endif
>> +
>> +     nr_desc = e->efi_memmap_size / e->efi_memdesc_size;
>> +     for (i = 0; i < nr_desc; i++) {
>> +             md = efi_early_memdesc_ptr(pmap, e->efi_memdesc_size, i);
>> +             if (md->attribute & EFI_MEMORY_MORE_RELIABLE) {
>> +                     region.start = md->phys_addr;
>> +                     region.size = md->num_pages << EFI_PAGE_SHIFT;
>> +                     process_mem_region(&region, minimum, image_size);
>> +                     efi_mirror_found = true;
>> +
>> +                     if (slot_area_index == MAX_SLOT_AREA) {
>> +                             debug_putstr("Aborted EFI scan (slot_areas full)!\n");
>> +                             break;
>> +                     }
>> +             }
>> +     }
>> +
>> +     return efi_mirror_found;
>> +}
>> +#else
>> +static inline bool
>> +process_efi_entries(unsigned long minimum, unsigned long image_size)
>> +{
>> +     return false;
>> +}
>> +#endif
>> +
>>  static void process_e820_entries(unsigned long minimum,
>>                                unsigned long image_size)
>>  {
>> @@ -586,13 +647,16 @@ static unsigned long find_random_phys_addr(unsigned long minimum,
>>  {
>>       /* Check if we had too many memmaps. */
>>       if (memmap_too_large) {
>> -             debug_putstr("Aborted e820 scan (more than 4 memmap= args)!\n");
>> +             debug_putstr("Aborted memory entries scan (more than 4 memmap= args)!\n");
>>               return 0;
>>       }
>>
>>       /* Make sure minimum is aligned. */
>>       minimum = ALIGN(minimum, CONFIG_PHYSICAL_ALIGN);
>>
>> +     if (process_efi_entries(minimum, image_size))
>> +             return slots_fetch_random();
>> +
>>       process_e820_entries(minimum, image_size);
>>       return slots_fetch_random();
>>  }
>> @@ -652,7 +716,7 @@ void choose_random_location(unsigned long input,
>>        */
>>       min_addr = min(*output, 512UL << 20);
>>
>> -     /* Walk e820 and find a random address. */
>> +     /* Walk available memory entries to find a random address. */
>>       random_addr = find_random_phys_addr(min_addr, output_size);
>>       if (!random_addr) {
>>               warn("Physical KASLR disabled: no suitable memory region!");
>> --
>> 2.5.5
>>
--
To unsubscribe from this list: send the line "unsubscribe linux-efi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux