Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

kexec jump: check code size in control page

Kexec/Kexec-jump require code size in control page is less than
PAGE_SIZE/2. This patch add link-time checking for this.

ASSERT() of ld link script is used as the link-time checking mechanism.

[akpm@linux-foundation.org: build fix]
Signed-off-by: Huang Ying <ying.huang@intel.com>
Cc: Pavel Machek <pavel@ucw.cz>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Huang Ying and committed by
Linus Torvalds
fb45daa6 163f6876

+20 -4
+1 -1
arch/x86/kernel/machine_kexec_32.c
··· 138 138 } 139 139 140 140 control_page = page_address(image->control_code_page); 141 - memcpy(control_page, relocate_kernel, PAGE_SIZE/2); 141 + memcpy(control_page, relocate_kernel, KEXEC_CONTROL_CODE_MAX_SIZE); 142 142 143 143 relocate_kernel_ptr = control_page; 144 144 page_list[PA_CONTROL_PAGE] = __pa(control_page);
+7 -3
arch/x86/kernel/relocate_kernel_32.S
··· 20 20 #define PAGE_ATTR (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) 21 21 #define PAE_PGD_ATTR (_PAGE_PRESENT) 22 22 23 - /* control_page + PAGE_SIZE/2 ~ control_page + PAGE_SIZE * 3/4 are 24 - * used to save some data for jumping back 23 + /* control_page + KEXEC_CONTROL_CODE_MAX_SIZE 24 + * ~ control_page + PAGE_SIZE are used as data storage and stack for 25 + * jumping back 25 26 */ 26 - #define DATA(offset) (PAGE_SIZE/2+(offset)) 27 + #define DATA(offset) (KEXEC_CONTROL_CODE_MAX_SIZE+(offset)) 27 28 28 29 /* Minimal CPU state */ 29 30 #define ESP DATA(0x0) ··· 377 376 popl %ebx 378 377 popl %ebp 379 378 ret 379 + 380 + .globl kexec_control_code_size 381 + .set kexec_control_code_size, . - relocate_kernel
+8
arch/x86/kernel/vmlinux_32.lds.S
··· 209 209 210 210 DWARF_DEBUG 211 211 } 212 + 213 + #ifdef CONFIG_KEXEC 214 + /* Link time checks */ 215 + #include <asm/kexec.h> 216 + 217 + ASSERT(kexec_control_code_size <= KEXEC_CONTROL_CODE_MAX_SIZE, 218 + "kexec control code size is too big") 219 + #endif
+4
include/asm-x86/kexec.h
··· 41 41 # define PAGES_NR 17 42 42 #endif 43 43 44 + #ifdef CONFIG_X86_32 45 + # define KEXEC_CONTROL_CODE_MAX_SIZE 2048 46 + #endif 47 + 44 48 #ifndef __ASSEMBLY__ 45 49 46 50 #include <linux/string.h>