Re: [PATCH v8 0/3] x86/boot/KASLR: Parse ACPI table and limit kaslr in immovable memory

2018-10-14 Thread Masayoshi Mizuma
On Sun, Oct 14, 2018 at 12:05:41AM +0200, Borislav Petkov wrote:
> On Sat, Oct 13, 2018 at 05:45:51PM -0400, Masayoshi Mizuma wrote:
> > Yes, but I think we need to arrange the Chao's SRAT parsing to be used
> > from kernel_randomize_memory() because Chao's approach needs the SRAT
> > parsing before extract kernel and the padding size calculation needs
> > the parsing in start_kernel(), so they are living in different life
> > cycle and space.
> 
> Or you would like to pass some info from the compressed kernel to kernel
> proper?
> 
> For example, something like the passing in add_e820ext() and the consumtion
> in parse_setup_data():
> 
> switch (data_type) {
> case SETUP_E820_EXT:
> e820__memory_setup_extended(pa_data, data_len);
> 
> So info you need for your padding gets collected in
> arch/x86/boot/compressed/acpitb.c and you consume it in
> kernel_randomize_memory()?
> 
> Would that work?

It's nice idea! Thank you so much!

- Masa


Re: [RFC PATCH] x86/efi: Allocate e820 buffer before calling efi_exit_boot_service

2018-10-14 Thread Ard Biesheuvel
On 14 October 2018 at 18:51, Eric Snowberg  wrote:
>
>> On Oct 14, 2018, at 9:34 AM, Jeffrey Hugo  wrote:
>>
>> On 10/12/2018 3:46 PM, Ard Biesheuvel wrote:
>>> On 9 August 2018 at 16:50, Eric Snowberg  wrote:
 Commit d64934019f6c ("x86/efi: Use efi_exit_boot_services()")
 introduced a regression on systems with large memory maps
 causing them to hang on boot. The first "goto get_map" that was removed
 from exit_boot insured there was enough room for the memory map when
 efi_call_early(exit_boot_services) was called. This happens when
 (nr_desc > ARRAY_SIZE(params->e820_table).

 Chain of events:
   exit_boot()
 efi_exit_boot_services()
   efi_get_memory_map <- at this point the mm can't grow over 8 desc
   priv_func()
 exit_boot_func()
   allocate_e820ext() <- new mm grows over 8 desc from e820 alloc
   efi_call_early(exit_boot_services) <- mm key doesn't match so retry
   efi_call_early(get_memory_map) <- not enough room for new mm
   system hangs

 This patch allocates the e820 buffer before calling efi_exit_boot_services
 and fixes the regression.

 Signed-off-by: Eric Snowberg 
 ---
  arch/x86/boot/compressed/eboot.c | 63 
 +---
  1 file changed, 40 insertions(+), 23 deletions(-)

 diff --git a/arch/x86/boot/compressed/eboot.c 
 b/arch/x86/boot/compressed/eboot.c
 index cbf4b87..91a650e 100644
 --- a/arch/x86/boot/compressed/eboot.c
 +++ b/arch/x86/boot/compressed/eboot.c
 @@ -866,11 +866,43 @@ static efi_status_t alloc_e820ext(u32 nr_desc, 
 struct setup_data **e820ext,
 return status;
  }

 +static efi_status_t allocate_e820(struct boot_params *params,
 + struct setup_data **e820ext,
 + u32 *e820ext_size)
 +{
 +   unsigned long map_size, desc_size, buff_size;
 +   struct efi_boot_memmap boot_map;
 +   efi_memory_desc_t *map;
 +   efi_status_t status;
 +   __u32 nr_desc;
 +
 +   boot_map.map =  
 +   boot_map.map_size = _size;
 +   boot_map.desc_size =_size;
 +   boot_map.desc_ver = NULL;
 +   boot_map.key_ptr =  NULL;
 +   boot_map.buff_size =_size;
 +
 +   status = efi_get_memory_map(sys_table, _map);
 +   if (status != EFI_SUCCESS)
 +   return status;
 +
 +   nr_desc = buff_size / desc_size;
 +
>>> I think we should add some slack here. This function is now called
>>> right before the first call to ExitBootServices(), which means events
>>> may fire that allocate or free memory between this call to
>>> efi_get_memory_map() and the final one which obtains the map key
>>> (which is the whole reason for this complicated dance)
>>
>> Slack in addition to what efi_get_memory_map() provides?
>
> Would additional slack be necessary here? This takes place before memory 
> allocation is no longer possible.  The efi_get_memory_map function will be 
> called again afterwards insuring their is slack available for the memory map 
> passed into EBS.
>

The point is that memory allocation is always possible due to
asynchronous events firing. Only after the first call to EBS() is it
guaranteed that event dispatch has terminated.

But to Jeffrey's point, efi_get_memory_map() already has 8 slots'
worth of slack, which means that we have 8 spare e820 table entries as
well. I guess this should be sufficient.


Re: [RFC PATCH] x86/efi: Allocate e820 buffer before calling efi_exit_boot_service

2018-10-14 Thread Eric Snowberg


> On Oct 14, 2018, at 9:34 AM, Jeffrey Hugo  wrote:
> 
> On 10/12/2018 3:46 PM, Ard Biesheuvel wrote:
>> On 9 August 2018 at 16:50, Eric Snowberg  wrote:
>>> Commit d64934019f6c ("x86/efi: Use efi_exit_boot_services()")
>>> introduced a regression on systems with large memory maps
>>> causing them to hang on boot. The first "goto get_map" that was removed
>>> from exit_boot insured there was enough room for the memory map when
>>> efi_call_early(exit_boot_services) was called. This happens when
>>> (nr_desc > ARRAY_SIZE(params->e820_table).
>>> 
>>> Chain of events:
>>>   exit_boot()
>>> efi_exit_boot_services()
>>>   efi_get_memory_map <- at this point the mm can't grow over 8 desc
>>>   priv_func()
>>> exit_boot_func()
>>>   allocate_e820ext() <- new mm grows over 8 desc from e820 alloc
>>>   efi_call_early(exit_boot_services) <- mm key doesn't match so retry
>>>   efi_call_early(get_memory_map) <- not enough room for new mm
>>>   system hangs
>>> 
>>> This patch allocates the e820 buffer before calling efi_exit_boot_services
>>> and fixes the regression.
>>> 
>>> Signed-off-by: Eric Snowberg 
>>> ---
>>>  arch/x86/boot/compressed/eboot.c | 63 
>>> +---
>>>  1 file changed, 40 insertions(+), 23 deletions(-)
>>> 
>>> diff --git a/arch/x86/boot/compressed/eboot.c 
>>> b/arch/x86/boot/compressed/eboot.c
>>> index cbf4b87..91a650e 100644
>>> --- a/arch/x86/boot/compressed/eboot.c
>>> +++ b/arch/x86/boot/compressed/eboot.c
>>> @@ -866,11 +866,43 @@ static efi_status_t alloc_e820ext(u32 nr_desc, struct 
>>> setup_data **e820ext,
>>> return status;
>>>  }
>>> 
>>> +static efi_status_t allocate_e820(struct boot_params *params,
>>> + struct setup_data **e820ext,
>>> + u32 *e820ext_size)
>>> +{
>>> +   unsigned long map_size, desc_size, buff_size;
>>> +   struct efi_boot_memmap boot_map;
>>> +   efi_memory_desc_t *map;
>>> +   efi_status_t status;
>>> +   __u32 nr_desc;
>>> +
>>> +   boot_map.map =  
>>> +   boot_map.map_size = _size;
>>> +   boot_map.desc_size =_size;
>>> +   boot_map.desc_ver = NULL;
>>> +   boot_map.key_ptr =  NULL;
>>> +   boot_map.buff_size =_size;
>>> +
>>> +   status = efi_get_memory_map(sys_table, _map);
>>> +   if (status != EFI_SUCCESS)
>>> +   return status;
>>> +
>>> +   nr_desc = buff_size / desc_size;
>>> +
>> I think we should add some slack here. This function is now called
>> right before the first call to ExitBootServices(), which means events
>> may fire that allocate or free memory between this call to
>> efi_get_memory_map() and the final one which obtains the map key
>> (which is the whole reason for this complicated dance)
> 
> Slack in addition to what efi_get_memory_map() provides?

Would additional slack be necessary here? This takes place before memory 
allocation is no longer possible.  The efi_get_memory_map function will be 
called again afterwards insuring their is slack available for the memory map 
passed into EBS.




[PATCH 3.16 299/366] efi: Avoid potential crashes, fix the 'struct efi_pci_io_protocol_32' definition for mixed mode

2018-10-14 Thread Ben Hutchings
3.16.60-rc1 review patch.  If anyone has any objections, please let me know.

--

From: Ard Biesheuvel 

commit 0b3225ab9407f557a8e20f23f37aa7236c10a9b1 upstream.

Mixed mode allows a kernel built for x86_64 to interact with 32-bit
EFI firmware, but requires us to define all struct definitions carefully
when it comes to pointer sizes.

'struct efi_pci_io_protocol_32' currently uses a 'void *' for the
'romimage' field, which will be interpreted as a 64-bit field
on such kernels, potentially resulting in bogus memory references
and subsequent crashes.

Tested-by: Hans de Goede 
Signed-off-by: Ard Biesheuvel 
Cc: Linus Torvalds 
Cc: Matt Fleming 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/20180504060003.19618-13-ard.biesheu...@linaro.org
Signed-off-by: Ingo Molnar 
Signed-off-by: Ben Hutchings 
---
 arch/x86/boot/compressed/eboot.c | 6 --
 include/linux/efi.h  | 8 
 2 files changed, 8 insertions(+), 6 deletions(-)

--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -358,7 +358,8 @@ __setup_efi_pci32(efi_pci_io_protocol_32
if (status != EFI_SUCCESS)
goto free_struct;
 
-   memcpy(rom->romdata, pci->romimage, pci->romsize);
+   memcpy(rom->romdata, (void *)(unsigned long)pci->romimage,
+  pci->romsize);
return status;
 
 free_struct:
@@ -460,7 +461,8 @@ __setup_efi_pci64(efi_pci_io_protocol_64
if (status != EFI_SUCCESS)
goto free_struct;
 
-   memcpy(rom->romdata, pci->romimage, pci->romsize);
+   memcpy(rom->romdata, (void *)(unsigned long)pci->romimage,
+  pci->romsize);
return status;
 
 free_struct:
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -368,8 +368,8 @@ typedef struct {
u32 attributes;
u32 get_bar_attributes;
u32 set_bar_attributes;
-   uint64_t romsize;
-   void *romimage;
+   u64 romsize;
+   u32 romimage;
 } efi_pci_io_protocol_32;
 
 typedef struct {
@@ -388,8 +388,8 @@ typedef struct {
u64 attributes;
u64 get_bar_attributes;
u64 set_bar_attributes;
-   uint64_t romsize;
-   void *romimage;
+   u64 romsize;
+   u64 romimage;
 } efi_pci_io_protocol_64;
 
 typedef struct {