On Wed, Jan 30, 2013 at 1:34 PM, H. Peter Anvin <hpa at zytor.com> wrote: > On 01/30/2013 01:25 PM, Yinghai Lu wrote: >> >> +static void clean_boot_params(unsigned char *real_mode, unsigned long size) >> +{ >> + unsigned long end; >> + >> + /* clear value before header */ >> + memset(real_mode, 0, 0x1f1); >> + /* clear value after setup_header */ >> + end = *(real_mode + 0x201); > > real_mode[0x201] might be clearer... > >> + end += 0x202; >> + if (end < size) >> + memset(real_mode + end, 0, size - end); >> +} > > You don't actually need the test... the value is inherently smaller than > 0x301 which is less than the size. > > That being said, if you want to sanity-check it you can check that the > value is in a sensible range -- the permitted range is 0x22 to 0x7f > inclusive, corresponding to a total end value of 0x224 to 0x281. yes. how about clear all and copy only setup_header? that looks more readable. Index: kexec-tools/kexec/arch/i386/kexec-bzImage.c =================================================================== --- kexec-tools.orig/kexec/arch/i386/kexec-bzImage.c +++ kexec-tools/kexec/arch/i386/kexec-bzImage.c @@ -211,7 +211,16 @@ int do_bzImage_load(struct kexec_info *i /* The argument/parameter segment */ setup_size = kern16_size + command_line_len + PURGATORY_CMDLINE_SIZE; real_mode = xmalloc(setup_size); - memcpy(real_mode, kernel, kern16_size); + if (!real_mode_entry) { + unsigned long size = kernel[0x201] + 0x202 - 0x1f1; + + /* only copy setup_header */ + memset(real_mode, 0, setup_size); + if (size > 0x7f) + size = 0x7f; + memcpy(real_mode + 0x1f1, kernel + 0x1f1, size); + } else + memcpy(real_mode, kernel, kern16_size); if (info->kexec_flags & (KEXEC_ON_CRASH | KEXEC_PRESERVE_CONTEXT)) { /* If using bzImage for capture kernel, then we will not be