Skip to contentSkip to conversation

ARM: kexec: Make .text R/W in machine_kexec

PATCH New Nikolay Borisov 3 participants 7 messages May 12, 2014 – May 21, 2014 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 ARM: kexec: Make .text R/W in machine_kexec

With the introduction of Kees Cook's patch to make the kernel .text read-only the existing method by which kexec works got broken since it directly pokes some values in the template code, which resides in the .text section.

The current patch changes the way those values are inserted so that poking .text section occurs only in machine_kexec (e.g when we are about to nuke the old kernel and are beyond the point of return). This allows to use set_kernel_text_rw() to directly patch the values in the .text section.

I had already sent a patch which achieved this but it was significantly more complicated, so this is a cleaner/straight-forward approach.

Tested on 3.15-rc4

---
 arch/arm/kernel/machine_kexec.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm/kernel/machine_kexec.c +4 -1
index 8cf0996..cee44db 100644
@@ -29,6 +29,7 @@ extern unsigned long kexec_boot_atags;
 
 static atomic_t waiting_for_crash_ipi;
 
+static unsigned long dt_mem;
 /*
  * Provide a dummy crash_notes definition while crash dump arrives to arm.
  * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -64,7 +65,7 @@ int machine_kexec_prepare(struct kimage *image)
 			return err;
 
 		if (be32_to_cpu(header) == OF_DT_HEADER)
-			kexec_boot_atags = current_segment->mem;
+			dt_mem = current_segment->mem;
 	}
 	return 0;
 }
@@ -163,9 +164,11 @@ void machine_kexec(struct kimage *image)
 	reboot_code_buffer = page_address(image->control_code_page);
 
 	/* Prepare parameters for reboot_code_buffer*/
+	set_kernel_text_rw();
 	kexec_start_address = image->start;
 	kexec_indirection_page = page_list;
 	kexec_mach_type = machine_arch_type;
+	kexec_boot_atags = dt_mem;
 	if (!kexec_boot_atags)
 		kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
 
Signature · 1 line
1.8.1.5
#1 lore raw

PATCH 2/2 ARM: Kconfig: remove dependence of CONFIG_DEBUG_RODATA on !kexec

Remove DEBUG_RODATA dependence on !kexec since "ARM: kexec: Make .text R/W in machine_kexec" fixes the incompatibility between those 2
options.

---
 arch/arm/mm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/Kconfig +1 -1
index 3cd7c0a..a96f585 100644
@@ -969,7 +969,7 @@ config ARM_KERNMEM_PERMS
 
 config DEBUG_RODATA
 	bool "Make kernel text and rodata read-only"
-	depends on ARM_KERNMEM_PERMS && KEXEC=n && KPROBES=n
+	depends on ARM_KERNMEM_PERMS && KPROBES=n
 	default y
 	help
 	  If this is set, kernel text and rodata will be made read-only.
Signature · 1 line
1.8.1.5
#3 lore raw

PATCH 2/2 ARM: Kconfig: remove dependence of CONFIG_DEBUG_RODATA on !kexec

Quoted 8 lines · Will Deacon
Quoted 5 lines · Nikolay Borisov

Remove DEBUG_RODATA dependence on !kexec since "ARM: kexec: Make .text R/W in machine_kexec" fixes the incompatibility between those 2
options.

We've got, from what I can see, about 4 sets of patches that are or revolve around DEBUG_RODATA. What do you think is the best way to gather everything together? Do you want me to build 1 giant set of patches that includes kexec, DEBUG_RODATA, FIXMAP, and kgdb all together, or should we just start flushing each one separately into the patch tracker?

-Kees

Signature · 2 lines
Kees Cook
Chrome OS Security
#4 lore raw

PATCH 2/2 ARM: Kconfig: remove dependence of CONFIG_DEBUG_RODATA on !kexec

Quoted 8 lines · Kees Cook
Quoted 7 lines · Will Deacon
Quoted 5 lines · Nikolay Borisov

Remove DEBUG_RODATA dependence on !kexec since "ARM: kexec: Make .text R/W in machine_kexec" fixes the incompatibility between those 2
options.

Quoted 8 lines
Quoted 1 line

We've got, from what I can see, about 4 sets of patches that are or revolve around DEBUG_RODATA. What do you think is the best way to gather everything together? Do you want me to build 1 giant set of patches that includes kexec, DEBUG_RODATA, FIXMAP, and kgdb all together, or should we just start flushing each one separately into the patch tracker?

It's probably worth you collating the patches together into a single series, giving it some testing, then reposting that to the list. Then, assuming nothing explodes, sending a pull request to rmk (although it's getting quite late in the day for 3.16).

Sound like a plan?

Will

#5 lore raw

PATCH 2/2 ARM: Kconfig: remove dependence of CONFIG_DEBUG_RODATA on !kexec

Quoted 18 lines · Will Deacon
Quoted 8 lines · Kees Cook
Quoted 7 lines · Will Deacon
Quoted 5 lines · Nikolay Borisov

Remove DEBUG_RODATA dependence on !kexec since "ARM: kexec: Make .text R/W in machine_kexec" fixes the incompatibility between those 2
options.

Quoted 8 lines
Quoted 1 line

We've got, from what I can see, about 4 sets of patches that are or revolve around DEBUG_RODATA. What do you think is the best way to gather everything together? Do you want me to build 1 giant set of patches that includes kexec, DEBUG_RODATA, FIXMAP, and kgdb all together, or should we just start flushing each one separately into the patch tracker?

Quoted 6 lines

It's probably worth you collating the patches together into a single series, giving it some testing, then reposting that to the list. Then, assuming nothing explodes, sending a pull request to rmk (although it's getting quite late in the day for 3.16).

Sound like a plan?

Sure! I'll start collecting it. :)

-Kees

Signature · 2 lines
Kees Cook
Chrome OS Security
#6 lore raw

PATCH 1/2 ARM: kexec: Make .text R/W in machine_kexec

In reply to Nikolay Borisov
Quoted 41 lines · Nikolay Borisov

With the introduction of Kees Cook's patch to make the kernel .text read-only the existing method by which kexec works got broken since it directly pokes some values in the template code, which resides in the .text section.

The current patch changes the way those values are inserted so that poking .text section occurs only in machine_kexec (e.g when we are about to nuke the old kernel and are beyond the point of return). This allows to use set_kernel_text_rw() to directly patch the values in the .text section.

I had already sent a patch which achieved this but it was significantly more complicated, so this is a cleaner/straight-forward approach.

Tested on 3.15-rc4

---
 arch/arm/kernel/machine_kexec.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm/kernel/machine_kexec.c +2 -1
index 8cf0996..cee44db 100644
@@ -29,6 +29,7 @@ extern unsigned long kexec_boot_atags;
 
 static atomic_t waiting_for_crash_ipi;
 
+static unsigned long dt_mem;
 /*
  * Provide a dummy crash_notes definition while crash dump arrives to arm.
  * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -64,7 +65,7 @@ int machine_kexec_prepare(struct kimage *image)
 			return err;
 
 		if (be32_to_cpu(header) == OF_DT_HEADER)
-			kexec_boot_atags = current_segment->mem;
+			dt_mem = current_segment->mem;
 	}
 	return 0;
 }

arch/arm/kernel/machine_kexec.c void machine_kexec(struct kimage *image) · line 173

Quoted 10 lines
arch/arm/kernel/machine_kexec.c +2 -0
@@ -163,9 +164,11 @@ void machine_kexec(struct kimage *image)
 	reboot_code_buffer = page_address(image->control_code_page);
 
 	/* Prepare parameters for reboot_code_buffer*/
+	set_kernel_text_rw();
 	kexec_start_address = image->start;
 	kexec_indirection_page = page_list;
 	kexec_mach_type = machine_arch_type;
+	kexec_boot_atags = dt_mem;
 	if (!kexec_boot_atags)
 		kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;

You could collapse this to:

	kexec_boot_atags = dt_mem ?: image->start - KEXEC_ARM_ZIMAGE_OFFSET
				     + KEXEC_ARM_ATAGS_OFFSET;

Other than that:

Will