Message ID | 20220419070150.254377-1-mawupeng1@huawei.com |
---|---|
Headers | show |
Series | Add support to relocate kernel image to mirrored region | expand |
On Tue, 19 Apr 2022 at 08:43, Wupeng Ma <mawupeng1@huawei.com> wrote: > > From: Ma Wupeng <mawupeng1@huawei.com> > > Now system image will perfer to be located to mirrored regions both KASLR > on and off. > Hello Ma Wupeng, I wonder if we could simplify this as follows: - ignore the non-KASLR case for now, and rely on the bootloader to load the image into mirrored memory if it exists; - simplify the KASLR case to the below. I think this is reasonable, because it means we take mirrored memory into account when we decide to move the image anyway, but expect the boot chain to take care of this if there is no need to move the image. -------------8<------------------ --- a/drivers/firmware/efi/libstub/randomalloc.c +++ b/drivers/firmware/efi/libstub/randomalloc.c @@ -56,6 +56,7 @@ efi_status_t efi_random_alloc(unsigned long size, unsigned long random_seed) { unsigned long map_size, desc_size, total_slots = 0, target_slot; + unsigned long total_mirrored_slots = 0; unsigned long buff_size; efi_status_t status; efi_memory_desc_t *memory_map; @@ -86,8 +87,14 @@ efi_status_t efi_random_alloc(unsigned long size, slots = get_entry_num_slots(md, size, ilog2(align)); MD_NUM_SLOTS(md) = slots; total_slots += slots; + if (md->attribute & EFI_MEMORY_MORE_RELIABLE) + total_mirrored_slots += slots; } + /* only consider mirrored slots for randomization if any exist */ + if (total_mirrored_slots > 0) + total_slots = total_mirrored_slots; + /* find a random number between 0 and total_slots */ target_slot = (total_slots * (u64)(random_seed & U32_MAX)) >> 32; @@ -107,6 +114,10 @@ efi_status_t efi_random_alloc(unsigned long size, efi_physical_addr_t target; unsigned long pages; + if (total_mirrored_slots > 0 && + !(md->attribute & EFI_MEMORY_MORE_RELIABLE)) + continue; + if (target_slot >= MD_NUM_SLOTS(md)) { target_slot -= MD_NUM_SLOTS(md); continue;
在 2022/5/3 17:58, Ard Biesheuvel 写道: > On Tue, 19 Apr 2022 at 08:43, Wupeng Ma <mawupeng1@huawei.com> wrote: >> >> From: Ma Wupeng <mawupeng1@huawei.com> >> >> Now system image will perfer to be located to mirrored regions both KASLR >> on and off. >> > > Hello Ma Wupeng, > > I wonder if we could simplify this as follows: > - ignore the non-KASLR case for now, and rely on the bootloader > load the image into mirrored memory if it exists; In grub, memory for static image is allocated via the following path: grub_cmd_linux kernel = grub_malloc(filelen) kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages) grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)) grub_loader_set (grub_linux_boot, grub_linux_unload, 0) Can we get memory from mirrored region by the following steps: 1. get memory map by calling grub_efi_get_memory_map() 2. iter all memory map to find a suitable mirrored memory area 3. locate kernel image to this area So, if kaslr is not enabled - grub will load kernel into mirrored region else - arm64-stub.c will relocate kernel image to mirrored region Is this feasible? > - simplify the KASLR case to the below. Yes, we can certainly do this. I will remove my code and use yours. > > I think this is reasonable, because it means we take mirrored memory > into account when we decide to move the image anyway, but expect the > boot chain to take care of this if there is no need to move the image. > > -------------8<------------------ > --- a/drivers/firmware/efi/libstub/randomalloc.c > +++ b/drivers/firmware/efi/libstub/randomalloc.c > @@ -56,6 +56,7 @@ efi_status_t efi_random_alloc(unsigned long size, > unsigned long random_seed) > { > unsigned long map_size, desc_size, total_slots = 0, target_slot; > + unsigned long total_mirrored_slots = 0; > unsigned long buff_size; > efi_status_t status; > efi_memory_desc_t *memory_map; > @@ -86,8 +87,14 @@ efi_status_t efi_random_alloc(unsigned long size, > slots = get_entry_num_slots(md, size, ilog2(align)); > MD_NUM_SLOTS(md) = slots; > total_slots += slots; > + if (md->attribute & EFI_MEMORY_MORE_RELIABLE) > + total_mirrored_slots += slots; > } > > + /* only consider mirrored slots for randomization if any exist */ > + if (total_mirrored_slots > 0) > + total_slots = total_mirrored_slots; > + > /* find a random number between 0 and total_slots */ > target_slot = (total_slots * (u64)(random_seed & U32_MAX)) >> 32; > > @@ -107,6 +114,10 @@ efi_status_t efi_random_alloc(unsigned long size, > efi_physical_addr_t target; > unsigned long pages; > > + if (total_mirrored_slots > 0 && > + !(md->attribute & EFI_MEMORY_MORE_RELIABLE)) > + continue; > + > if (target_slot >= MD_NUM_SLOTS(md)) { > target_slot -= MD_NUM_SLOTS(md); > continue; > .
在 2022/5/7 17:28, mawupeng 写道: > > > 在 2022/5/3 17:58, Ard Biesheuvel 写道: >> On Tue, 19 Apr 2022 at 08:43, Wupeng Ma <mawupeng1@huawei.com> wrote: >>> >>> From: Ma Wupeng <mawupeng1@huawei.com> >>> >>> Now system image will perfer to be located to mirrored regions both KASLR >>> on and off. >>> >> >> Hello Ma Wupeng, >> >> I wonder if we could simplify this as follows: >> - ignore the non-KASLR case for now, and rely on the bootloader > load the image into mirrored memory if it exists; > > In grub, memory for static image is allocated via the following path: > > grub_cmd_linux > kernel = grub_malloc(filelen) > kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages) > grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)) > grub_loader_set (grub_linux_boot, grub_linux_unload, 0) > > Can we get memory from mirrored region by the following steps: > 1. get memory map by calling grub_efi_get_memory_map() > 2. iter all memory map to find a suitable mirrored memory area > 3. locate kernel image to this area > > So, if kaslr is not enabled > - grub will load kernel into mirrored region > else > - arm64-stub.c will relocate kernel image to mirrored region > > Is this feasible? Is this a feasible proposal to relocate the static kernel image itself into more reliable memory? > >> - simplify the KASLR case to the below. > > Yes, we can certainly do this. I will remove my code and use yours. > >> >> I think this is reasonable, because it means we take mirrored memory >> into account when we decide to move the image anyway, but expect the >> boot chain to take care of this if there is no need to move the image. >> >> -------------8<------------------ >> --- a/drivers/firmware/efi/libstub/randomalloc.c >> +++ b/drivers/firmware/efi/libstub/randomalloc.c >> @@ -56,6 +56,7 @@ efi_status_t efi_random_alloc(unsigned long size, >> unsigned long random_seed) >> { >> unsigned long map_size, desc_size, total_slots = 0, target_slot; >> + unsigned long total_mirrored_slots = 0; >> unsigned long buff_size; >> efi_status_t status; >> efi_memory_desc_t *memory_map; >> @@ -86,8 +87,14 @@ efi_status_t efi_random_alloc(unsigned long size, >> slots = get_entry_num_slots(md, size, ilog2(align)); >> MD_NUM_SLOTS(md) = slots; >> total_slots += slots; >> + if (md->attribute & EFI_MEMORY_MORE_RELIABLE) >> + total_mirrored_slots += slots; >> } >> >> + /* only consider mirrored slots for randomization if any exist */ >> + if (total_mirrored_slots > 0) >> + total_slots = total_mirrored_slots; >> + >> /* find a random number between 0 and total_slots */ >> target_slot = (total_slots * (u64)(random_seed & U32_MAX)) >> 32; >> >> @@ -107,6 +114,10 @@ efi_status_t efi_random_alloc(unsigned long size, >> efi_physical_addr_t target; >> unsigned long pages; >> >> + if (total_mirrored_slots > 0 && >> + !(md->attribute & EFI_MEMORY_MORE_RELIABLE)) >> + continue; >> + >> if (target_slot >= MD_NUM_SLOTS(md)) { >> target_slot -= MD_NUM_SLOTS(md); >> continue; >> .
On Thu, 19 May 2022 at 13:09, mawupeng <mawupeng1@huawei.com> wrote: > > > > 在 2022/5/7 17:28, mawupeng 写道: > > > > > > 在 2022/5/3 17:58, Ard Biesheuvel 写道: > >> On Tue, 19 Apr 2022 at 08:43, Wupeng Ma <mawupeng1@huawei.com> wrote: > >>> > >>> From: Ma Wupeng <mawupeng1@huawei.com> > >>> > >>> Now system image will perfer to be located to mirrored regions both KASLR > >>> on and off. > >>> > >> > >> Hello Ma Wupeng, > >> > >> I wonder if we could simplify this as follows: > >> - ignore the non-KASLR case for now, and rely on the bootloader > load the image into mirrored memory if it exists; > > > > In grub, memory for static image is allocated via the following path: > > > > grub_cmd_linux > > kernel = grub_malloc(filelen) > > kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages) > > grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)) > > grub_loader_set (grub_linux_boot, grub_linux_unload, 0) > > > > Can we get memory from mirrored region by the following steps: > > 1. get memory map by calling grub_efi_get_memory_map() > > 2. iter all memory map to find a suitable mirrored memory area > > 3. locate kernel image to this area > > > > So, if kaslr is not enabled > > - grub will load kernel into mirrored region > > else > > - arm64-stub.c will relocate kernel image to mirrored region > > > > Is this feasible? > > Is this a feasible proposal to relocate the static kernel image itself > into more reliable memory? > I'm not sure, it all depends on the firmware. When GRUB calls LoadImage(), the firmware will reallocate the image and unpack it there. So it is really the firmware's job to ensure that the image is loaded into a suitable location. I have some code here that implements a EFI based decompressor, and which loads the kernel image into mirrored memory if it exists, without the need to move it again. It could trivially be modified to deal with non-randomized loads as well. But the bottom line is that UEFI should expose the ability to target mirrored memory, hacking around it like this is not a sustainable approach.
On Fri, 20 May 2022 at 08:52, Ard Biesheuvel <ardb@kernel.org> wrote: > > On Thu, 19 May 2022 at 13:09, mawupeng <mawupeng1@huawei.com> wrote: > > > > > > > > 在 2022/5/7 17:28, mawupeng 写道: > > > > > > > > > 在 2022/5/3 17:58, Ard Biesheuvel 写道: > > >> On Tue, 19 Apr 2022 at 08:43, Wupeng Ma <mawupeng1@huawei.com> wrote: > > >>> > > >>> From: Ma Wupeng <mawupeng1@huawei.com> > > >>> > > >>> Now system image will perfer to be located to mirrored regions both KASLR > > >>> on and off. > > >>> > > >> > > >> Hello Ma Wupeng, > > >> > > >> I wonder if we could simplify this as follows: > > >> - ignore the non-KASLR case for now, and rely on the bootloader > load the image into mirrored memory if it exists; > > > > > > In grub, memory for static image is allocated via the following path: > > > > > > grub_cmd_linux > > > kernel = grub_malloc(filelen) > > > kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages) > > > grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)) > > > grub_loader_set (grub_linux_boot, grub_linux_unload, 0) > > > > > > Can we get memory from mirrored region by the following steps: > > > 1. get memory map by calling grub_efi_get_memory_map() > > > 2. iter all memory map to find a suitable mirrored memory area > > > 3. locate kernel image to this area > > > > > > So, if kaslr is not enabled > > > - grub will load kernel into mirrored region > > > else > > > - arm64-stub.c will relocate kernel image to mirrored region > > > > > > Is this feasible? > > > > Is this a feasible proposal to relocate the static kernel image itself > > into more reliable memory? > > > > I'm not sure, it all depends on the firmware. > > When GRUB calls LoadImage(), the firmware will reallocate the image > and unpack it there. So it is really the firmware's job to ensure that > the image is loaded into a suitable location. > > I have some code here that implements a EFI based decompressor, and > which loads the kernel image into mirrored memory if it exists, > without the need to move it again. It could trivially be modified to > deal with non-randomized loads as well. > Code is here https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v2
在 2022/5/20 14:52, Ard Biesheuvel 写道: > On Thu, 19 May 2022 at 13:09, mawupeng <mawupeng1@huawei.com> wrote: >> >> >> >> 在 2022/5/7 17:28, mawupeng 写道: >>> >>> >>> 在 2022/5/3 17:58, Ard Biesheuvel 写道: >>>> On Tue, 19 Apr 2022 at 08:43, Wupeng Ma <mawupeng1@huawei.com> wrote: >>>>> >>>>> From: Ma Wupeng <mawupeng1@huawei.com> >>>>> >>>>> Now system image will perfer to be located to mirrored regions both KASLR >>>>> on and off. >>>>> >>>> >>>> Hello Ma Wupeng, >>>> >>>> I wonder if we could simplify this as follows: >>>> - ignore the non-KASLR case for now, and rely on the bootloader > load the image into mirrored memory if it exists; >>> >>> In grub, memory for static image is allocated via the following path: >>> >>> grub_cmd_linux >>> kernel = grub_malloc(filelen) >>> kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages) >>> grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)) >>> grub_loader_set (grub_linux_boot, grub_linux_unload, 0) >>> >>> Can we get memory from mirrored region by the following steps: >>> 1. get memory map by calling grub_efi_get_memory_map() >>> 2. iter all memory map to find a suitable mirrored memory area >>> 3. locate kernel image to this area >>> >>> So, if kaslr is not enabled >>> - grub will load kernel into mirrored region >>> else >>> - arm64-stub.c will relocate kernel image to mirrored region >>> >>> Is this feasible? >> >> Is this a feasible proposal to relocate the static kernel image itself >> into more reliable memory? >> > > I'm not sure, it all depends on the firmware. > > When GRUB calls LoadImage(), the firmware will reallocate the image > and unpack it there. So it is really the firmware's job to ensure that > the image is loaded into a suitable location. > > I have some code here that implements a EFI based decompressor, and > which loads the kernel image into mirrored memory if it exists, > without the need to move it again. It could trivially be modified to > deal with non-randomized loads as well. > > But the bottom line is that UEFI should expose the ability to target > mirrored memory, hacking around it like this is not a sustainable > approach. Since firmware is responsible for put kernel static image into mirrored region and kernel is responsible for relocate this image into mirrored region if kaslr is enabled. There is no conflict between these two. Can we integrate the kernel part(introduce mirrored support to arm64) first? > .
在 2022/5/20 14:52, Ard Biesheuvel 写道: > On Fri, 20 May 2022 at 08:52, Ard Biesheuvel <ardb@kernel.org> wrote: >> >> On Thu, 19 May 2022 at 13:09, mawupeng <mawupeng1@huawei.com> wrote: >>> >>> >>> >>> 在 2022/5/7 17:28, mawupeng 写道: >>>> >>>> >>>> 在 2022/5/3 17:58, Ard Biesheuvel 写道: >>>>> On Tue, 19 Apr 2022 at 08:43, Wupeng Ma <mawupeng1@huawei.com> wrote: >>>>>> >>>>>> From: Ma Wupeng <mawupeng1@huawei.com> >>>>>> >>>>>> Now system image will perfer to be located to mirrored regions both KASLR >>>>>> on and off. >>>>>> >>>>> >>>>> Hello Ma Wupeng, >>>>> >>>>> I wonder if we could simplify this as follows: >>>>> - ignore the non-KASLR case for now, and rely on the bootloader > load the image into mirrored memory if it exists; >>>> >>>> In grub, memory for static image is allocated via the following path: >>>> >>>> grub_cmd_linux >>>> kernel = grub_malloc(filelen) >>>> kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages) >>>> grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)) >>>> grub_loader_set (grub_linux_boot, grub_linux_unload, 0) >>>> >>>> Can we get memory from mirrored region by the following steps: >>>> 1. get memory map by calling grub_efi_get_memory_map() >>>> 2. iter all memory map to find a suitable mirrored memory area >>>> 3. locate kernel image to this area >>>> >>>> So, if kaslr is not enabled >>>> - grub will load kernel into mirrored region >>>> else >>>> - arm64-stub.c will relocate kernel image to mirrored region >>>> >>>> Is this feasible? >>> >>> Is this a feasible proposal to relocate the static kernel image itself >>> into more reliable memory? >>> >> >> I'm not sure, it all depends on the firmware. >> >> When GRUB calls LoadImage(), the firmware will reallocate the image >> and unpack it there. So it is really the firmware's job to ensure that >> the image is loaded into a suitable location. >> >> I have some code here that implements a EFI based decompressor, and >> which loads the kernel image into mirrored memory if it exists, >> without the need to move it again. It could trivially be modified to >> deal with non-randomized loads as well. >> > > Code is here > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v2 I will test this later. Thanks. > .
On Mon, 23 May 2022 at 03:18, mawupeng <mawupeng1@huawei.com> wrote: > > > > 在 2022/5/20 14:52, Ard Biesheuvel 写道: > > On Thu, 19 May 2022 at 13:09, mawupeng <mawupeng1@huawei.com> wrote: > >> > >> > >> > >> 在 2022/5/7 17:28, mawupeng 写道: > >>> > >>> > >>> 在 2022/5/3 17:58, Ard Biesheuvel 写道: > >>>> On Tue, 19 Apr 2022 at 08:43, Wupeng Ma <mawupeng1@huawei.com> wrote: > >>>>> > >>>>> From: Ma Wupeng <mawupeng1@huawei.com> > >>>>> > >>>>> Now system image will perfer to be located to mirrored regions both KASLR > >>>>> on and off. > >>>>> > >>>> > >>>> Hello Ma Wupeng, > >>>> > >>>> I wonder if we could simplify this as follows: > >>>> - ignore the non-KASLR case for now, and rely on the bootloader > load the image into mirrored memory if it exists; > >>> > >>> In grub, memory for static image is allocated via the following path: > >>> > >>> grub_cmd_linux > >>> kernel = grub_malloc(filelen) > >>> kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages) > >>> grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)) > >>> grub_loader_set (grub_linux_boot, grub_linux_unload, 0) > >>> > >>> Can we get memory from mirrored region by the following steps: > >>> 1. get memory map by calling grub_efi_get_memory_map() > >>> 2. iter all memory map to find a suitable mirrored memory area > >>> 3. locate kernel image to this area > >>> > >>> So, if kaslr is not enabled > >>> - grub will load kernel into mirrored region > >>> else > >>> - arm64-stub.c will relocate kernel image to mirrored region > >>> > >>> Is this feasible? > >> > >> Is this a feasible proposal to relocate the static kernel image itself > >> into more reliable memory? > >> > > > > I'm not sure, it all depends on the firmware. > > > > When GRUB calls LoadImage(), the firmware will reallocate the image > > and unpack it there. So it is really the firmware's job to ensure that > > the image is loaded into a suitable location. > > > > I have some code here that implements a EFI based decompressor, and > > which loads the kernel image into mirrored memory if it exists, > > without the need to move it again. It could trivially be modified to > > deal with non-randomized loads as well. > > > > But the bottom line is that UEFI should expose the ability to target > > mirrored memory, hacking around it like this is not a sustainable > > approach. > > Since firmware is responsible for put kernel static image into mirrored > region and kernel is responsible for relocate this image into mirrored > region if kaslr is enabled. There is no conflict between these two. > > Can we integrate the kernel part(introduce mirrored support to arm64) first? > Yes. If you drop the changes related to fake memmap and rebase, please resend them after -rc1 is released.
在 2022/5/23 22:41, Ard Biesheuvel 写道: > On Mon, 23 May 2022 at 03:18, mawupeng <mawupeng1@huawei.com> wrote: >> >> >> >> 在 2022/5/20 14:52, Ard Biesheuvel 写道: >>> On Thu, 19 May 2022 at 13:09, mawupeng <mawupeng1@huawei.com> wrote: >>>> >>>> >>>> >>>> 在 2022/5/7 17:28, mawupeng 写道: >>>>> >>>>> >>>>> 在 2022/5/3 17:58, Ard Biesheuvel 写道: >>>>>> On Tue, 19 Apr 2022 at 08:43, Wupeng Ma <mawupeng1@huawei.com> wrote: >>>>>>> >>>>>>> From: Ma Wupeng <mawupeng1@huawei.com> >>>>>>> >>>>>>> Now system image will perfer to be located to mirrored regions both KASLR >>>>>>> on and off. >>>>>>> >>>>>> >>>>>> Hello Ma Wupeng, >>>>>> >>>>>> I wonder if we could simplify this as follows: >>>>>> - ignore the non-KASLR case for now, and rely on the bootloader > load the image into mirrored memory if it exists; >>>>> >>>>> In grub, memory for static image is allocated via the following path: >>>>> >>>>> grub_cmd_linux >>>>> kernel = grub_malloc(filelen) >>>>> kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages) >>>>> grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)) >>>>> grub_loader_set (grub_linux_boot, grub_linux_unload, 0) >>>>> >>>>> Can we get memory from mirrored region by the following steps: >>>>> 1. get memory map by calling grub_efi_get_memory_map() >>>>> 2. iter all memory map to find a suitable mirrored memory area >>>>> 3. locate kernel image to this area >>>>> >>>>> So, if kaslr is not enabled >>>>> - grub will load kernel into mirrored region >>>>> else >>>>> - arm64-stub.c will relocate kernel image to mirrored region >>>>> >>>>> Is this feasible? >>>> >>>> Is this a feasible proposal to relocate the static kernel image itself >>>> into more reliable memory? >>>> >>> >>> I'm not sure, it all depends on the firmware. >>> >>> When GRUB calls LoadImage(), the firmware will reallocate the image >>> and unpack it there. So it is really the firmware's job to ensure that >>> the image is loaded into a suitable location. >>> >>> I have some code here that implements a EFI based decompressor, and >>> which loads the kernel image into mirrored memory if it exists, >>> without the need to move it again. It could trivially be modified to >>> deal with non-randomized loads as well. >>> >>> But the bottom line is that UEFI should expose the ability to target >>> mirrored memory, hacking around it like this is not a sustainable >>> approach. >> >> Since firmware is responsible for put kernel static image into mirrored >> region and kernel is responsible for relocate this image into mirrored >> region if kaslr is enabled. There is no conflict between these two. >> >> Can we integrate the kernel part(introduce mirrored support to arm64) first? >> > > Yes. If you drop the changes related to fake memmap and rebase, please > resend them after -rc1 is released. Ok, I will drop the changes related to fake memmap and rebase and then resend them after -rc1 is released. Thanks for reviewing. > .
From: Ma Wupeng <mawupeng1@huawei.com> Now system image will perfer to be located to mirrored regions both KASLR on and off. Ma Wupeng (2): arm64/boot/KASLR: Add support to relocate kernel image to mirrored region arm64/boot: Add support to relocate kernel image to mirrored region without kaslr drivers/firmware/efi/libstub/arm64-stub.c | 62 +++++++++++++++++++++- drivers/firmware/efi/libstub/efistub.h | 7 ++- drivers/firmware/efi/libstub/randomalloc.c | 14 ++++- 3 files changed, 79 insertions(+), 4 deletions(-)