All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] s390/decompressor: fix initrd corruption caused by bss clear
@ 2017-03-13 15:14 Marcelo Henrique Cerri
  2017-03-13 15:27 ` Heiko Carstens
  2017-03-15  8:41 ` Heiko Carstens
  0 siblings, 2 replies; 3+ messages in thread
From: Marcelo Henrique Cerri @ 2017-03-13 15:14 UTC (permalink / raw)
  To: Martin Schwidefsky, linux-s390
  Cc: Heiko Carstens, Peter Oberparleiter, Marcelo Henrique Cerri,
	Joy Latten, linux-kernel

Reorder the operations in decompress_kernel() to ensure initrd is moved
to a safe location before the bss section is zeroed.

During decompression bss can overlap with the initrd and this can
corrupt the initrd contents depending on the size of the compressed
kernel (which affects where the initrd is placed by the bootloader) and
the size of the bss section of the decompressor.

Also use the correct initrd size when checking for overlaps with
parmblock.

Fixes: 06c0dd72aea3 ([S390] fix boot failures with compressed kernels)
Cc: stable@vger.kernel.org
Reviewed-by: Joy Latten <joy.latten@canonical.com>
Reviewed-by: Vineetha HariPai <vineetha.hari.pai@canonical.com>
Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
---
 arch/s390/boot/compressed/misc.c | 35 +++++++++++++++++++----------------
 1 file changed, 19 insertions(+), 16 deletions(-)

diff --git a/arch/s390/boot/compressed/misc.c b/arch/s390/boot/compressed/misc.c
index fa95041fa9f6..cf91297f4e7a 100644
--- a/arch/s390/boot/compressed/misc.c
+++ b/arch/s390/boot/compressed/misc.c
@@ -141,31 +141,34 @@ static void check_ipl_parmblock(void *start, unsigned long size)
 
 unsigned long decompress_kernel(void)
 {
-	unsigned long output_addr;
-	unsigned char *output;
+	void *output, *kernel_end;
 
-	output_addr = ((unsigned long) &_end + HEAP_SIZE + 4095UL) & -4096UL;
-	check_ipl_parmblock((void *) 0, output_addr + SZ__bss_start);
-	memset(&_bss, 0, &_ebss - &_bss);
-	free_mem_ptr = (unsigned long)&_end;
-	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
-	output = (unsigned char *) output_addr;
+	output = (void *) ALIGN((unsigned long) &_end + HEAP_SIZE, PAGE_SIZE);
+	kernel_end = output + SZ__bss_start;
+	check_ipl_parmblock(0, (unsigned long) kernel_end);
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	/*
 	 * Move the initrd right behind the end of the decompressed
-	 * kernel image.
+	 * kernel image. This also prevent the initrd corruption caused by the
+	 * bss clearing since kernel_end will always be located after the
+	 * current bss section..
 	 */
-	if (INITRD_START && INITRD_SIZE &&
-	    INITRD_START < (unsigned long) output + SZ__bss_start) {
-		check_ipl_parmblock(output + SZ__bss_start,
-				    INITRD_START + INITRD_SIZE);
-		memmove(output + SZ__bss_start,
-			(void *) INITRD_START, INITRD_SIZE);
-		INITRD_START = (unsigned long) output + SZ__bss_start;
+	if (INITRD_START && INITRD_SIZE && kernel_end > (void *) INITRD_START) {
+		check_ipl_parmblock(kernel_end, INITRD_SIZE);
+		memmove(kernel_end, (void *) INITRD_START, INITRD_SIZE);
+		INITRD_START = (unsigned long) kernel_end;
 	}
 #endif
 
+	/*
+	 * Clear the bss section. free_mem_ptr and free_mem_end_ptr need to be
+	 * initialized after since they reside on bss.
+	 */
+	memset(&_bss, 0, &_ebss - &_bss);
+	free_mem_ptr = (unsigned long) &_end;
+	free_mem_end_ptr = free_mem_ptr + HEAP_SIZE;
+
 	puts("Uncompressing Linux... ");
 	__decompress(input_data, input_len, NULL, NULL, output, 0, NULL, error);
 	puts("Ok, booting the kernel.\n");
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] s390/decompressor: fix initrd corruption caused by bss clear
  2017-03-13 15:14 [PATCH] s390/decompressor: fix initrd corruption caused by bss clear Marcelo Henrique Cerri
@ 2017-03-13 15:27 ` Heiko Carstens
  2017-03-15  8:41 ` Heiko Carstens
  1 sibling, 0 replies; 3+ messages in thread
From: Heiko Carstens @ 2017-03-13 15:27 UTC (permalink / raw)
  To: Marcelo Henrique Cerri
  Cc: Martin Schwidefsky, linux-s390, Peter Oberparleiter, Joy Latten,
	linux-kernel

On Mon, Mar 13, 2017 at 12:14:58PM -0300, Marcelo Henrique Cerri wrote:
> Reorder the operations in decompress_kernel() to ensure initrd is moved
> to a safe location before the bss section is zeroed.
> 
> During decompression bss can overlap with the initrd and this can
> corrupt the initrd contents depending on the size of the compressed
> kernel (which affects where the initrd is placed by the bootloader) and
> the size of the bss section of the decompressor.
> 
> Also use the correct initrd size when checking for overlaps with
> parmblock.
> 
> Fixes: 06c0dd72aea3 ([S390] fix boot failures with compressed kernels)
> Cc: stable@vger.kernel.org
> Reviewed-by: Joy Latten <joy.latten@canonical.com>
> Reviewed-by: Vineetha HariPai <vineetha.hari.pai@canonical.com>
> Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
> ---
>  arch/s390/boot/compressed/misc.c | 35 +++++++++++++++++++----------------
>  1 file changed, 19 insertions(+), 16 deletions(-)

Indeed. I just checked that we currently have 32 bytes within the bss
section of the compressed kernel image, where clearing it would corrupt the
initrd if would be placed directly behind the image.
I will look into the patch tomorrow.

Thanks,
Heiko

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] s390/decompressor: fix initrd corruption caused by bss clear
  2017-03-13 15:14 [PATCH] s390/decompressor: fix initrd corruption caused by bss clear Marcelo Henrique Cerri
  2017-03-13 15:27 ` Heiko Carstens
@ 2017-03-15  8:41 ` Heiko Carstens
  1 sibling, 0 replies; 3+ messages in thread
From: Heiko Carstens @ 2017-03-15  8:41 UTC (permalink / raw)
  To: Marcelo Henrique Cerri
  Cc: Martin Schwidefsky, linux-s390, Peter Oberparleiter, Joy Latten,
	linux-kernel

On Mon, Mar 13, 2017 at 12:14:58PM -0300, Marcelo Henrique Cerri wrote:
> Reorder the operations in decompress_kernel() to ensure initrd is moved
> to a safe location before the bss section is zeroed.
> 
> During decompression bss can overlap with the initrd and this can
> corrupt the initrd contents depending on the size of the compressed
> kernel (which affects where the initrd is placed by the bootloader) and
> the size of the bss section of the decompressor.
> 
> Also use the correct initrd size when checking for overlaps with
> parmblock.
> 
> Fixes: 06c0dd72aea3 ([S390] fix boot failures with compressed kernels)
> Cc: stable@vger.kernel.org
> Reviewed-by: Joy Latten <joy.latten@canonical.com>
> Reviewed-by: Vineetha HariPai <vineetha.hari.pai@canonical.com>
> Signed-off-by: Marcelo Henrique Cerri <marcelo.cerri@canonical.com>
> ---
>  arch/s390/boot/compressed/misc.c | 35 +++++++++++++++++++----------------
>  1 file changed, 19 insertions(+), 16 deletions(-)

Applied. Thank you!

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-03-15  8:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-13 15:14 [PATCH] s390/decompressor: fix initrd corruption caused by bss clear Marcelo Henrique Cerri
2017-03-13 15:27 ` Heiko Carstens
2017-03-15  8:41 ` Heiko Carstens

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.