Skip to contentSkip to conversation

Command line randomness

PATCH Superseded Laura Abbott 4 participants 9 messages Aug 16, 2017 – Aug 17, 2017 Memory management

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

v2 cover Command line randomness

Hi,

This is a series to add the kernel command line as a source of randomness. The first patch is an (old) prepatory patch from me to move the stack canary initialization later. The second patch is from Daniel Micay to actually add the command line to the pool.

Kees suggested this go through -mm.

Thanks,
Laura

Daniel Micay (1):
extract early boot entropy from the passed cmdline

Laura Abbott (1):
init: Move stack canary initialization after setup_arch

 init/main.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
Signature · 1 line
2.13.0
#1 lore raw

PATCH v2 1/2 init: Move stack canary initialization after setup_arch

From: Laura Abbott <[email protected]>

Stack canary intialization involves getting a random number. Getting this random number may involve accessing caches or other architectural specific features which are not available until after the architecture is setup. Move the stack canary initialization later to accomodate this.

---
v2: Also moved add_latent_entropy per suggestion of Kees.

---
 init/main.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
init/main.c +5 -6
index 052481fbe363..21d599eaad06 100644
@@ -515,12 +515,6 @@ asmlinkage __visible void __init start_kernel(void)
 	smp_setup_processor_id();
 	debug_objects_early_init();
 
-	/*
-	 * Set up the initial canary ASAP:
-	 */
-	add_latent_entropy();
-	boot_init_stack_canary();
-
 	cgroup_init_early();
 
 	local_irq_disable();
@@ -534,6 +528,11 @@ asmlinkage __visible void __init start_kernel(void)
 	page_address_init();
 	pr_notice("%s", linux_banner);
 	setup_arch(&command_line);
+	/*
+	 * Set up the the initial canary and entropy after arch
+	 */
+	add_latent_entropy();
+	boot_init_stack_canary();
 	mm_init_cpumask(&init_mm);
 	setup_command_line(command_line);
 	setup_nr_cpu_ids();
Signature · 1 line
2.13.0
Acked-by on v2 1/2
#2 lore raw

Re: [PATCHv2 1/2] init: Move stack canary initialization after setup_arch

Quoted 10 lines · Laura Abbott

From: Laura Abbott <[email protected]>

Stack canary intialization involves getting a random number. Getting this random number may involve accessing caches or other architectural specific features which are not available until after the architecture is setup. Move the stack canary initialization later to accomodate this.

-Kees

Quoted 38 lines

---
v2: Also moved add_latent_entropy per suggestion of Kees.

---
 init/main.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
init/main.c +5 -7
index 052481fbe363..21d599eaad06 100644
@@ -515,12 +515,6 @@ asmlinkage __visible void __init start_kernel(void)
        smp_setup_processor_id();
        debug_objects_early_init();
 
-       /*
-        * Set up the initial canary ASAP:
-        */
-       add_latent_entropy();
-       boot_init_stack_canary();
-
        cgroup_init_early();
 
        local_irq_disable();
@@ -534,6 +528,11 @@ asmlinkage __visible void __init start_kernel(void)
        page_address_init();
        pr_notice("%s", linux_banner);
        setup_arch(&command_line);
+       /*
+        * Set up the the initial canary and entropy after arch
+        */
+       add_latent_entropy();
+       boot_init_stack_canary();
        mm_init_cpumask(&init_mm);
        setup_command_line(command_line);
        setup_nr_cpu_ids();
--

2.13.0

Signature · 2 lines
Kees Cook
Pixel Security
#3 lore raw

PATCH v2 2/2 extract early boot entropy from the passed cmdline

In reply to Laura Abbott

From: Daniel Micay <[email protected]>

Existing Android bootloaders usually pass data useful as early entropy on the kernel command-line. It may also be the case on other embedded systems. Sample command-line from a Google Pixel running CopperheadOS:

    console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0
    androidboot.hardware=sailfish user_debug=31 ehci-hcd.park=3
    lpm_levels.sleep_disabled=1 cma=32M@0-0xffffffff buildvariant=user
    veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab
    androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=yellow
    androidboot.veritymode=enforcing androidboot.keymaster=1
    androidboot.serialno=FA6CE0305299 androidboot.baseband=msm
    mdss_mdp.panel=1:dsi:0:qcom,mdss_dsi_samsung_ea8064tg_1080p_cmd:1:none:cfg:single_dsi
    androidboot.slot_suffix=_b fpsimd.fpsimd_settings=0
    app_setting.use_app_setting=0 kernelflag=0x00000000 debugflag=0x00000000
    androidboot.hardware.revision=PVT radioflag=0x00000000
    radioflagex1=0x00000000 radioflagex2=0x00000000 cpumask=0x00000000
    androidboot.hardware.ddr=4096MB,Hynix,LPDDR4 androidboot.ddrinfo=00000006
    androidboot.ddrsize=4GB androidboot.hardware.color=GRA00
    androidboot.hardware.ufs=32GB,Samsung androidboot.msm.hw_ver_id=268824801
    androidboot.qf.st=2 androidboot.cid=11111111 androidboot.mid=G-2PW4100
    androidboot.bootloader=8996-012001-1704121145
    androidboot.oem_unlock_support=1 androidboot.fp_src=1
    androidboot.htc.hrdump=detected androidboot.ramdump.opt=mem@2g:2g,mem@4g:2g
    androidboot.bootreason=reboot androidboot.ramdump_enable=0 ro
    root=/dev/dm-0 dm="system none ro,0 1 android-verity /dev/sda34"
    rootwait skip_initramfs init=/init androidboot.wificountrycode=US
    androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136

Among other things, it contains a value unique to the device (androidboot.serialno=FA6CE0305299), unique to the OS builds for the device variant (veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab) and timings from the bootloader stages in milliseconds (androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136).

[labbott: Line-wrapped command line]
---
 init/main.c | 1 +
 1 file changed, 1 insertion(+)
init/main.c +1 -0
index 21d599eaad06..cb051aec46ef 100644
@@ -533,6 +533,7 @@ asmlinkage __visible void __init start_kernel(void)
 	 */
 	add_latent_entropy();
 	boot_init_stack_canary();
+	add_device_randomness(command_line, strlen(command_line));
 	mm_init_cpumask(&init_mm);
 	setup_command_line(command_line);
 	setup_nr_cpu_ids();
Signature · 1 line
2.13.0
#4 lore raw

Re: [PATCHv2 2/2] extract early boot entropy from the passed cmdline

Quoted 48 lines · Laura Abbott

From: Daniel Micay <[email protected]>

Existing Android bootloaders usually pass data useful as early entropy on the kernel command-line. It may also be the case on other embedded systems. Sample command-line from a Google Pixel running CopperheadOS:

    console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0
    androidboot.hardware=sailfish user_debug=31 ehci-hcd.park=3
    lpm_levels.sleep_disabled=1 cma=32M@0-0xffffffff buildvariant=user
    veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab
    androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=yellow
    androidboot.veritymode=enforcing androidboot.keymaster=1
    androidboot.serialno=FA6CE0305299 androidboot.baseband=msm
    mdss_mdp.panel=1:dsi:0:qcom,mdss_dsi_samsung_ea8064tg_1080p_cmd:1:none:cfg:single_dsi
    androidboot.slot_suffix=_b fpsimd.fpsimd_settings=0
    app_setting.use_app_setting=0 kernelflag=0x00000000 debugflag=0x00000000
    androidboot.hardware.revision=PVT radioflag=0x00000000
    radioflagex1=0x00000000 radioflagex2=0x00000000 cpumask=0x00000000
    androidboot.hardware.ddr=4096MB,Hynix,LPDDR4 androidboot.ddrinfo=00000006
    androidboot.ddrsize=4GB androidboot.hardware.color=GRA00
    androidboot.hardware.ufs=32GB,Samsung androidboot.msm.hw_ver_id=268824801
    androidboot.qf.st=2 androidboot.cid=11111111 androidboot.mid=G-2PW4100
    androidboot.bootloader=8996-012001-1704121145
    androidboot.oem_unlock_support=1 androidboot.fp_src=1
    androidboot.htc.hrdump=detected androidboot.ramdump.opt=mem@2g:2g,mem@4g:2g
    androidboot.bootreason=reboot androidboot.ramdump_enable=0 ro
    root=/dev/dm-0 dm="system none ro,0 1 android-verity /dev/sda34"
    rootwait skip_initramfs init=/init androidboot.wificountrycode=US
    androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136

Among other things, it contains a value unique to the device (androidboot.serialno=FA6CE0305299), unique to the OS builds for the device variant (veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab) and timings from the bootloader stages in milliseconds (androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136).

[labbott: Line-wrapped command line]
---
 init/main.c | 1 +
 1 file changed, 1 insertion(+)
init/main.c +0 -0
index 21d599eaad06..cb051aec46ef 100644

init/main.c asmlinkage __visible void __init start_kernel(void) · line 536

Quoted 4 lines
init/main.c +1 -0
@@ -533,6 +533,7 @@ asmlinkage __visible void __init start_kernel(void)
         */
        add_latent_entropy();
        boot_init_stack_canary();
+       add_device_randomness(command_line, strlen(command_line));

This should be above the add_latent_entropy() line there so the cmdline entropy can contribute to the canary entropy.

-Kees

Quoted 6 lines
init/main.c +0 -1
        mm_init_cpumask(&init_mm);
        setup_command_line(command_line);
        setup_nr_cpu_ids();
--

2.13.0

Signature · 2 lines
Kees Cook
Pixel Security
#5 lore raw

Re: [PATCHv2 2/2] extract early boot entropy from the passed cmdline

Quoted 44 lines · Kees Cook
Quoted 43 lines · Laura Abbott

From: Daniel Micay <[email protected]>

Existing Android bootloaders usually pass data useful as early entropy on the kernel command-line. It may also be the case on other embedded systems. Sample command-line from a Google Pixel running CopperheadOS:

    console=ttyHSL0,115200,n8 androidboot.console=ttyHSL0
    androidboot.hardware=sailfish user_debug=31 ehci-hcd.park=3
    lpm_levels.sleep_disabled=1 cma=32M@0-0xffffffff buildvariant=user
    veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab
    androidboot.bootdevice=624000.ufshc androidboot.verifiedbootstate=yellow
    androidboot.veritymode=enforcing androidboot.keymaster=1
    androidboot.serialno=FA6CE0305299 androidboot.baseband=msm
    mdss_mdp.panel=1:dsi:0:qcom,mdss_dsi_samsung_ea8064tg_1080p_cmd:1:none:cfg:single_dsi
    androidboot.slot_suffix=_b fpsimd.fpsimd_settings=0
    app_setting.use_app_setting=0 kernelflag=0x00000000 debugflag=0x00000000
    androidboot.hardware.revision=PVT radioflag=0x00000000
    radioflagex1=0x00000000 radioflagex2=0x00000000 cpumask=0x00000000
    androidboot.hardware.ddr=4096MB,Hynix,LPDDR4 androidboot.ddrinfo=00000006
    androidboot.ddrsize=4GB androidboot.hardware.color=GRA00
    androidboot.hardware.ufs=32GB,Samsung androidboot.msm.hw_ver_id=268824801
    androidboot.qf.st=2 androidboot.cid=11111111 androidboot.mid=G-2PW4100
    androidboot.bootloader=8996-012001-1704121145
    androidboot.oem_unlock_support=1 androidboot.fp_src=1
    androidboot.htc.hrdump=detected androidboot.ramdump.opt=mem@2g:2g,mem@4g:2g
    androidboot.bootreason=reboot androidboot.ramdump_enable=0 ro
    root=/dev/dm-0 dm="system none ro,0 1 android-verity /dev/sda34"
    rootwait skip_initramfs init=/init androidboot.wificountrycode=US
    androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136

Among other things, it contains a value unique to the device (androidboot.serialno=FA6CE0305299), unique to the OS builds for the device variant (veritykeyid=id:dfcb9db0089e5b3b4090a592415c28e1cb4545ab) and timings from the bootloader stages in milliseconds (androidboot.boottime=1BLL:85,1BLE:669,2BLL:0,2BLE:1777,SW:6,KL:8136).

[labbott: Line-wrapped command line]
---
 init/main.c | 1 +
 1 file changed, 1 insertion(+)
Quoted 13 lines

init/main.c asmlinkage __visible void __init start_kernel(void) · line 536

Quoted 9 lines
init/main.c +1 -0
index 21d599eaad06..cb051aec46ef 100644
@@ -533,6 +533,7 @@ asmlinkage __visible void __init start_kernel(void)
         */
        add_latent_entropy();
        boot_init_stack_canary();
+       add_device_randomness(command_line, strlen(command_line));

This should be above the add_latent_entropy() line there so the cmdline entropy can contribute to the canary entropy.

Yeah, bad merge on my fault. Will spin a v3.

Quoted 11 lines

-Kees

Quoted 6 lines
init/main.c +0 -1
        mm_init_cpumask(&init_mm);
        setup_command_line(command_line);
        setup_nr_cpu_ids();
--

2.13.0

#6 lore raw

Re: [kernel-hardening] [PATCHv2 2/2] extract early boot entropy from the passed cmdline

In reply to Laura Abbott
Quoted 6 lines · Laura Abbott

From: Daniel Micay <[email protected]>

Existing Android bootloaders usually pass data useful as early entropy on the kernel command-line. It may also be the case on other embedded systems. Sample command-line from a Google Pixel running CopperheadOS:

Why is it better to put this into the kernel, rather than just rely on the existing userspace functionality which does exactly the same thing? This is what Android already does today:
https://android-review.googlesource.com/198113

-- Nick

#7 lore raw

Re: [kernel-hardening] [PATCHv2 2/2] extract early boot entropy from the passed cmdline

Quoted 8 lines · Nick Kralevich
Quoted 6 lines · Laura Abbott

From: Daniel Micay <[email protected]>

Existing Android bootloaders usually pass data useful as early entropy on the kernel command-line. It may also be the case on other embedded systems. Sample command-line from a Google Pixel running CopperheadOS:

Quoted 4 lines

Why is it better to put this into the kernel, rather than just rely on the existing userspace functionality which does exactly the same thing? This is what Android already does today:
https://android-review.googlesource.com/198113

That's too late for setting up the kernel stack canary, among other things. The kernel will also be generating some early secrets for slab cache canaries, etc. That all needs to happen well before init is started.

-Kees

Signature · 2 lines
Kees Cook
Pixel Security
#8 lore raw

Re: [kernel-hardening] [PATCHv2 2/2] extract early boot entropy from the passed cmdline

Quoted 20 lines · Kees Cook
Quoted 12 lines · Nick Kralevich
Quoted 9 lines · Laura Abbott

From: Daniel Micay <[email protected]>

Existing Android bootloaders usually pass data useful as early entropy
on the kernel command-line. It may also be the case on other embedded
systems. Sample command-line from a Google Pixel running CopperheadOS:

Quoted 5 lines

Why is it better to put this into the kernel, rather than just rely on
the existing userspace functionality which does exactly the same thing? This is what Android already does today:
https://android-review.googlesource.com/198113

Quoted 7 lines

That's too late for setting up the kernel stack canary, among other things. The kernel will also be generating some early secrets for slab cache canaries, etc. That all needs to happen well before init is started.

-Kees

It's also unfortunately the kernel's global stack canary for the entire boot since unlike x86 there aren't per-task canaries. GCC / Clang access it via a segment register on x86 vs. a global on other architectures.

In theory it could be task-local elsewhere but doing it efficiently would imply reserving a register to store the random value. I think that may actually end up helping performance more than it hurts by not needing to read the global stack canary value from cache repeatedly. If stack canaries were augmented into something more (XOR in the retaddr and offer the option of more coverage than STRONG) it would be more important.