From: bhsharma@redhat.com (Bhupesh Sharma) To: linux-arm-kernel@lists.infradead.org Subject: [Query] ARM64 kaslr support - randomness, seeding and kdump Date: Wed, 14 Mar 2018 10:33:03 +0530 [thread overview] Message-ID: <CACi5LpPUKEWYfVDFvrfnf4_2LgKbKat-meMTzTXWEPN_D8nAVQ@mail.gmail.com> (raw) In-Reply-To: <20180314021050.GK25863@linaro.org> ' On Wed, Mar 14, 2018 at 7:40 AM, AKASHI Takahiro <takahiro.akashi@linaro.org> wrote: > On Wed, Mar 14, 2018 at 01:18:47AM +0530, Bhupesh Sharma wrote: >> On Tue, Mar 13, 2018 at 4:50 PM, Mark Rutland <mark.rutland@arm.com> 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 <bhsharma@redhat.com> 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. But doesn't this problem exist in the arm64 kexec design already for kexec_load() case? Since it relies on sending a dtb (updated with the 'linux,usable-memory') property to the secondary/kexec kernel, we can easily introduce a security vulnerability in the system by expanding the dtb to include a static value for '/chosen/kaslr-seed'. Consider the following scenario (which I tried yesterday on my arm64 board just out of curiosity): 1. Primary kernel and secondary kernel both are compiled with kaslr flags (CONFIG_RANDOMIZE_BASE) 2. Primary kernel is loaded at random physical address on the basis of the '/chosen/kaslr-seed' property. 3. Thereafter this property is memset to 0. 4. Now we call 'kexec -l + kexec -e' combination to warm boot to a secondary/kexec kernel. 5. Since 'kexec-tools' picks up the existing dtb with '/chosen/kaslr-seed' set to 0, it passes the same to the secondary/kexec kernel. 6. Instead if we have a vulnerable 'kexec-tools' user space application, which unpacks the dtb and sets the '/chosen/kaslr-seed' to a known static non-zero value. 7. Now the secondary/kexec kernel is invoked and the 'kaslr_early_init()' finds a valid, non-zero '/chosen/kaslr-seed' and uses it to calculate the offsets for randomizing the linear region and randomizing the base of the module region. Since the seed was a known static value, determining the randomized bases of the above regions is always possible. So, I am not sure the existing 'kexec-tools' design can protect us from such security vulnerabilities anyway as we rely on passing the dtb to the secondary kernel for arm64 kexec to work. What I was suggesting in the previous mail was that instead of passing a zero '/chosen/kaslr-seed' to the secondary/kexec kernel (which effectively leads to a *nokaslr* behaviour), we can do the right thing by using a entropy source (if available) to generate a random seed. > (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.) I think we need to handle both the kexec_load() and kexec_file_load() cases transparently as the user may invoke either of them. Just for my understanding - in the arm64 kexec_file_load() case we don't pass the modified dtb via user-space to the secondary kernel. Right (sorry I still haven't looked at the latest kexec_file_load() patches yet)? Thanks, Bhupesh > >> 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
WARNING: multiple messages have this Message-ID (diff)
From: Bhupesh Sharma <bhsharma@redhat.com> To: AKASHI Takahiro <takahiro.akashi@linaro.org>, Bhupesh Sharma <bhsharma@redhat.com>, Mark Rutland <mark.rutland@arm.com>, Ard Biesheuvel <ard.biesheuvel@linaro.org>, linux-arm-kernel <linux-arm-kernel@lists.infradead.org>, kexec@lists.infradead.org, Bhupesh SHARMA <bhupesh.linux@gmail.com> Subject: Re: [Query] ARM64 kaslr support - randomness, seeding and kdump Date: Wed, 14 Mar 2018 10:33:03 +0530 [thread overview] Message-ID: <CACi5LpPUKEWYfVDFvrfnf4_2LgKbKat-meMTzTXWEPN_D8nAVQ@mail.gmail.com> (raw) In-Reply-To: <20180314021050.GK25863@linaro.org> ' On Wed, Mar 14, 2018 at 7:40 AM, AKASHI Takahiro <takahiro.akashi@linaro.org> wrote: > On Wed, Mar 14, 2018 at 01:18:47AM +0530, Bhupesh Sharma wrote: >> On Tue, Mar 13, 2018 at 4:50 PM, Mark Rutland <mark.rutland@arm.com> 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 <bhsharma@redhat.com> 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. But doesn't this problem exist in the arm64 kexec design already for kexec_load() case? Since it relies on sending a dtb (updated with the 'linux,usable-memory') property to the secondary/kexec kernel, we can easily introduce a security vulnerability in the system by expanding the dtb to include a static value for '/chosen/kaslr-seed'. Consider the following scenario (which I tried yesterday on my arm64 board just out of curiosity): 1. Primary kernel and secondary kernel both are compiled with kaslr flags (CONFIG_RANDOMIZE_BASE) 2. Primary kernel is loaded at random physical address on the basis of the '/chosen/kaslr-seed' property. 3. Thereafter this property is memset to 0. 4. Now we call 'kexec -l + kexec -e' combination to warm boot to a secondary/kexec kernel. 5. Since 'kexec-tools' picks up the existing dtb with '/chosen/kaslr-seed' set to 0, it passes the same to the secondary/kexec kernel. 6. Instead if we have a vulnerable 'kexec-tools' user space application, which unpacks the dtb and sets the '/chosen/kaslr-seed' to a known static non-zero value. 7. Now the secondary/kexec kernel is invoked and the 'kaslr_early_init()' finds a valid, non-zero '/chosen/kaslr-seed' and uses it to calculate the offsets for randomizing the linear region and randomizing the base of the module region. Since the seed was a known static value, determining the randomized bases of the above regions is always possible. So, I am not sure the existing 'kexec-tools' design can protect us from such security vulnerabilities anyway as we rely on passing the dtb to the secondary kernel for arm64 kexec to work. What I was suggesting in the previous mail was that instead of passing a zero '/chosen/kaslr-seed' to the secondary/kexec kernel (which effectively leads to a *nokaslr* behaviour), we can do the right thing by using a entropy source (if available) to generate a random seed. > (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.) I think we need to handle both the kexec_load() and kexec_file_load() cases transparently as the user may invoke either of them. Just for my understanding - in the arm64 kexec_file_load() case we don't pass the modified dtb via user-space to the secondary kernel. Right (sorry I still haven't looked at the latest kexec_file_load() patches yet)? Thanks, Bhupesh > >> 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
next prev parent reply other threads:[~2018-03-14 5:03 UTC|newest] Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-03-12 20:14 [Query] ARM64 kaslr support - randomness, seeding and kdump Bhupesh Sharma 2018-03-12 20:14 ` Bhupesh Sharma 2018-03-12 20:58 ` Ard Biesheuvel 2018-03-12 20:58 ` Ard Biesheuvel 2018-03-13 1:54 ` Dave Young 2018-03-13 1:54 ` Dave Young 2018-03-13 10:22 ` AKASHI Takahiro 2018-03-13 10:22 ` AKASHI Takahiro 2018-03-13 10:47 ` Mark Rutland 2018-03-13 10:47 ` Mark Rutland 2018-03-13 11:07 ` AKASHI Takahiro 2018-03-13 11:07 ` AKASHI Takahiro 2018-03-13 11:20 ` Mark Rutland 2018-03-13 11:20 ` Mark Rutland 2018-03-13 19:48 ` Bhupesh Sharma 2018-03-13 19:48 ` Bhupesh Sharma 2018-03-14 2:10 ` AKASHI Takahiro 2018-03-14 2:10 ` AKASHI Takahiro 2018-03-14 5:03 ` Bhupesh Sharma [this message] 2018-03-14 5:03 ` Bhupesh Sharma 2018-03-14 6:40 ` AKASHI Takahiro 2018-03-14 6:40 ` AKASHI Takahiro 2018-03-14 18:24 ` Mark Rutland 2018-03-14 18:24 ` Mark Rutland 2018-03-16 9:35 ` Bhupesh Sharma 2018-03-16 9:35 ` Bhupesh Sharma 2018-04-06 2:09 ` AKASHI Takahiro 2018-04-06 2:09 ` AKASHI Takahiro 2018-04-09 4:01 ` Bhupesh Sharma 2018-04-09 4:01 ` Bhupesh Sharma 2018-04-09 4:31 ` AKASHI Takahiro 2018-04-09 4:31 ` AKASHI Takahiro 2018-04-09 9:28 ` Ard Biesheuvel 2018-04-09 9:28 ` Ard Biesheuvel 2018-04-09 9:39 ` Baoquan He 2018-04-09 9:39 ` Baoquan He 2018-04-09 18:28 ` Bhupesh Sharma 2018-04-09 18:28 ` Bhupesh Sharma 2018-04-10 0:47 ` AKASHI Takahiro 2018-04-10 0:47 ` AKASHI Takahiro 2018-04-14 20:14 ` Bhupesh Sharma 2018-04-14 20:14 ` Bhupesh Sharma 2018-04-18 11:52 ` Mark Rutland 2018-04-18 11:52 ` Mark Rutland 2018-04-23 20:34 ` Bhupesh Sharma 2018-04-23 20:34 ` Bhupesh Sharma
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=CACi5LpPUKEWYfVDFvrfnf4_2LgKbKat-meMTzTXWEPN_D8nAVQ@mail.gmail.com \ --to=bhsharma@redhat.com \ --cc=linux-arm-kernel@lists.infradead.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.