From mboxrd@z Thu Jan 1 00:00:00 1970 From: takahiro.akashi@linaro.org (AKASHI Takahiro) Date: Wed, 14 Mar 2018 11:10:53 +0900 Subject: [Query] ARM64 kaslr support - randomness, seeding and kdump In-Reply-To: References: <20180313102158.GI25863@linaro.org> <20180313104715.prurmrizho4ddc4l@lakrids.cambridge.arm.com> <20180313110747.GJ25863@linaro.org> <20180313112016.ocx4qqhji3zfwjhs@lakrids.cambridge.arm.com> Message-ID: <20180314021050.GK25863@linaro.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Wed, Mar 14, 2018 at 01:18:47AM +0530, Bhupesh Sharma wrote: > On Tue, Mar 13, 2018 at 4:50 PM, Mark Rutland wrote: > > On Tue, Mar 13, 2018 at 08:07:49PM +0900, AKASHI Takahiro wrote: > >> On Tue, Mar 13, 2018 at 10:47:15AM +0000, Mark Rutland wrote: > >> > On Tue, Mar 13, 2018 at 07:22:03PM +0900, AKASHI Takahiro wrote: > >> > > On Mon, Mar 12, 2018 at 08:58:00PM +0000, Ard Biesheuvel wrote: > >> > > > On 12 March 2018 at 20:14, Bhupesh Sharma wrote: > >> > > >> > > More importantly, neither arm64 _kexec_ supports kaslr. > > Sorry if my earlier email was not clear on this, but I meant both the > kdump/kexec cases. > > While for kdump there is no current requirement for physical > randomization, for kexec it would be good to support the same as the > primary kernel was already supporting kaslr and the secondary kernel > (if compiled with CONFIG_RANDOMIZE_BASE) would randomizes the virtual > address at which the kernel image is loaded. > > If we have physical randomization supported in this case in the > secondary/kexec kernel we can avoid potential misuse related to the > physical address being known at which the secondary/kexec kernel is > loaded. > > >> > > >> > The below is just considering this, and ignoring kdump (where I don't > >> > think we care at all about KASLR). > >> > > >> > > Currently kexec-tools is set to determine where the kernel actually be > >> > > loaded, using a constant offset, text_offset, which comes from an image's > >> > > boot header and relocation of an image to the load address is performed > >> > > at the very end of the first kernel without knowing whether the 2nd kernel > >> > > has kaslr support enabled or not. > >> > > >> > The kexec tools shouldn't need to know whether the kernel supports KASLR > >> > at all. > >> > > >> > If the new kernel image has bit 3 (Kernel physical placement) set, kexec > >> > tools can choose to randomize the physical load address, regardless of > >> > whether that kernel has KASLR enabled. > >> > >> So, by definition, is randomness, if we say so, in physical address not > >> part of KASLR? > > > > Physical randomization is not part of the kernel's KASLR implementation. > > > > We happen to do it in the EFI stub, because we can in that context. But > > generally, physical randomization is not part of arm64's in-kernel > > KASLR. > > > > For various reasons, the physical address that the kernel is loaded to > > may be arbitrary, so we have to cope with physical randomization > > regardless. > > Indeed, since the primary kernel depends on the firmware's > EFI_RNG_PROTOCOL implementation (if available) to randomise the > physical location of the kernel Image, for the secondary/kexec kernel, > if can have two approaches to enable physical randomization: I believe that you're now talking about "virtual" randomization. > - Implement a UEFI stub for loading the kexec kernel as well, or > > - Extend the 'kexec-tools' to invoke the entropy source available in > the primary kernel (provided by the firmware via EFI_RNG_PROTOCOL) to > generate a random seed to randomize the physical address and populate > it in the '/chosen/kaslr-seed' property of the device-tree being > passed to the secondary/kexec kernel and let the normal code flow in > ' arch/arm64/kernel/kaslr.c', function 'kaslr_early_init' to get the > seed for the secondary kernel from the '/chosen/kaslr-seed' property > itself. > > Personally the later approach looks simpler to me from a implementation p-o-v. If kaslr-seed has a critical value in terms of security, is kexec-tools a right place? It is exposed to user space albeit for a short time of period. (Speaking of kexec_file, we can easily adopt this approach as fdt modification is done totally inside the kernel. Likewise, "physical" randomization would be easy in part of arm64_relocate_new_kernel() because we only have to care bit 3 of boot header's flags after Mark's comment.) -Takahiro AKASHI > For example, currently in the kernel we normally invoke 'update_fdt' > (inside 'drivers/fimrware/efi/libstub/fdt.c') from the UEFI stub, > wherein we have this check for CONFIG_RANDOMIZE_BASE: > > static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, > unsigned long orig_fdt_size, > void *fdt, int new_fdt_size, char *cmdline_ptr, > u64 initrd_addr, u64 initrd_size) > { > > ... > if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { > efi_status_t efi_status; > > efi_status = efi_get_random_bytes(sys_table, sizeof(fdt_val64), > (u8 *)&fdt_val64); > if (efi_status == EFI_SUCCESS) { > status = fdt_setprop(fdt, node, "kaslr-seed", > &fdt_val64, sizeof(fdt_val64)); > if (status) > goto fdt_set_fail; > } else if (efi_status != EFI_NOT_FOUND) { > return efi_status; > } > } > ... > } > > I am thinking of modifying the kexec-tools code for arm64 (which > already processes the device tree to pass it to the secondary/kexec > kernel), so that we can do something like the following: > > --> efi_get_random_bytes(sys_table, sizeof(fdt_val64), > (u8 *)&fdt_val64); > ------> fdt_setprop(fdt, node, "kaslr-seed", &fdt_val64, > sizeof(fdt_val64)); > > Now when the modified dtb is passed to the secondary/kexec kernel it > will automatically find a valid seed, will wipe it to zero for > security reasons and use the same to perform physical randomization. > > If this looks sensible I will try to take a stab at this approach and > share results on thread in the coming days. > Please share your inputs. > > Regards, > Bhupesh From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from mail-pg0-x241.google.com ([2607:f8b0:400e:c05::241]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1evvsA-00038I-LM for kexec@lists.infradead.org; Wed, 14 Mar 2018 02:10:37 +0000 Received: by mail-pg0-x241.google.com with SMTP id i14so742878pgv.3 for ; Tue, 13 Mar 2018 19:10:22 -0700 (PDT) Date: Wed, 14 Mar 2018 11:10:53 +0900 From: AKASHI Takahiro Subject: Re: [Query] ARM64 kaslr support - randomness, seeding and kdump Message-ID: <20180314021050.GK25863@linaro.org> References: <20180313102158.GI25863@linaro.org> <20180313104715.prurmrizho4ddc4l@lakrids.cambridge.arm.com> <20180313110747.GJ25863@linaro.org> <20180313112016.ocx4qqhji3zfwjhs@lakrids.cambridge.arm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "kexec" Errors-To: kexec-bounces+dwmw2=infradead.org@lists.infradead.org To: Bhupesh Sharma Cc: Mark Rutland , Bhupesh SHARMA , kexec@lists.infradead.org, linux-arm-kernel , Ard Biesheuvel On Wed, Mar 14, 2018 at 01:18:47AM +0530, Bhupesh Sharma wrote: > On Tue, Mar 13, 2018 at 4:50 PM, Mark Rutland wrote: > > On Tue, Mar 13, 2018 at 08:07:49PM +0900, AKASHI Takahiro wrote: > >> On Tue, Mar 13, 2018 at 10:47:15AM +0000, Mark Rutland wrote: > >> > On Tue, Mar 13, 2018 at 07:22:03PM +0900, AKASHI Takahiro wrote: > >> > > On Mon, Mar 12, 2018 at 08:58:00PM +0000, Ard Biesheuvel wrote: > >> > > > On 12 March 2018 at 20:14, Bhupesh Sharma wrote: > >> > > >> > > More importantly, neither arm64 _kexec_ supports kaslr. > > Sorry if my earlier email was not clear on this, but I meant both the > kdump/kexec cases. > > While for kdump there is no current requirement for physical > randomization, for kexec it would be good to support the same as the > primary kernel was already supporting kaslr and the secondary kernel > (if compiled with CONFIG_RANDOMIZE_BASE) would randomizes the virtual > address at which the kernel image is loaded. > > If we have physical randomization supported in this case in the > secondary/kexec kernel we can avoid potential misuse related to the > physical address being known at which the secondary/kexec kernel is > loaded. > > >> > > >> > The below is just considering this, and ignoring kdump (where I don't > >> > think we care at all about KASLR). > >> > > >> > > Currently kexec-tools is set to determine where the kernel actually be > >> > > loaded, using a constant offset, text_offset, which comes from an image's > >> > > boot header and relocation of an image to the load address is performed > >> > > at the very end of the first kernel without knowing whether the 2nd kernel > >> > > has kaslr support enabled or not. > >> > > >> > The kexec tools shouldn't need to know whether the kernel supports KASLR > >> > at all. > >> > > >> > If the new kernel image has bit 3 (Kernel physical placement) set, kexec > >> > tools can choose to randomize the physical load address, regardless of > >> > whether that kernel has KASLR enabled. > >> > >> So, by definition, is randomness, if we say so, in physical address not > >> part of KASLR? > > > > Physical randomization is not part of the kernel's KASLR implementation. > > > > We happen to do it in the EFI stub, because we can in that context. But > > generally, physical randomization is not part of arm64's in-kernel > > KASLR. > > > > For various reasons, the physical address that the kernel is loaded to > > may be arbitrary, so we have to cope with physical randomization > > regardless. > > Indeed, since the primary kernel depends on the firmware's > EFI_RNG_PROTOCOL implementation (if available) to randomise the > physical location of the kernel Image, for the secondary/kexec kernel, > if can have two approaches to enable physical randomization: I believe that you're now talking about "virtual" randomization. > - Implement a UEFI stub for loading the kexec kernel as well, or > > - Extend the 'kexec-tools' to invoke the entropy source available in > the primary kernel (provided by the firmware via EFI_RNG_PROTOCOL) to > generate a random seed to randomize the physical address and populate > it in the '/chosen/kaslr-seed' property of the device-tree being > passed to the secondary/kexec kernel and let the normal code flow in > ' arch/arm64/kernel/kaslr.c', function 'kaslr_early_init' to get the > seed for the secondary kernel from the '/chosen/kaslr-seed' property > itself. > > Personally the later approach looks simpler to me from a implementation p-o-v. If kaslr-seed has a critical value in terms of security, is kexec-tools a right place? It is exposed to user space albeit for a short time of period. (Speaking of kexec_file, we can easily adopt this approach as fdt modification is done totally inside the kernel. Likewise, "physical" randomization would be easy in part of arm64_relocate_new_kernel() because we only have to care bit 3 of boot header's flags after Mark's comment.) -Takahiro AKASHI > For example, currently in the kernel we normally invoke 'update_fdt' > (inside 'drivers/fimrware/efi/libstub/fdt.c') from the UEFI stub, > wherein we have this check for CONFIG_RANDOMIZE_BASE: > > static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt, > unsigned long orig_fdt_size, > void *fdt, int new_fdt_size, char *cmdline_ptr, > u64 initrd_addr, u64 initrd_size) > { > > ... > if (IS_ENABLED(CONFIG_RANDOMIZE_BASE)) { > efi_status_t efi_status; > > efi_status = efi_get_random_bytes(sys_table, sizeof(fdt_val64), > (u8 *)&fdt_val64); > if (efi_status == EFI_SUCCESS) { > status = fdt_setprop(fdt, node, "kaslr-seed", > &fdt_val64, sizeof(fdt_val64)); > if (status) > goto fdt_set_fail; > } else if (efi_status != EFI_NOT_FOUND) { > return efi_status; > } > } > ... > } > > I am thinking of modifying the kexec-tools code for arm64 (which > already processes the device tree to pass it to the secondary/kexec > kernel), so that we can do something like the following: > > --> efi_get_random_bytes(sys_table, sizeof(fdt_val64), > (u8 *)&fdt_val64); > ------> fdt_setprop(fdt, node, "kaslr-seed", &fdt_val64, > sizeof(fdt_val64)); > > Now when the modified dtb is passed to the secondary/kexec kernel it > will automatically find a valid seed, will wipe it to zero for > security reasons and use the same to perform physical randomization. > > If this looks sensible I will try to take a stab at this approach and > share results on thread in the coming days. > Please share your inputs. > > Regards, > Bhupesh _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec