Package: grub Version: 0.95+cvs20040624-12 Severity: important When using Linux 2.6.10, grub's 'install' command segfaults on new hardware that has the NX bit available (e.g. AMD64, and I think also new Pentium 4 systems). This turns out to be because:
* grub's Unix shell allocates a region of memory part of which is used as a simulated stack; * the 'install' command uses a nested function which causes GCC to emit a stack trampoline requiring an executable stack; * malloc()ed memory is only PROT_READ|PROT_WRITE by default; * 2.6.10 sets noexec=on by default, thereby assuming that pages without PROT_EXEC set can be treated as non-executable, and this is enforced on hardware with the NX bit available. The attached patch corrects this problem (tested), and I believe should be harmless on older systems. Please apply. Most of it came from the mprotect() man page and/or is probably too obvious/short to be copyrightable, but if I need to sign an assignment to have this go upstream then I'll be happy to do so. Thanks, -- Colin Watson [EMAIL PROTECTED]
--- grub-0.95+cvs20040624.orig/grub/asmstub.c +++ grub-0.95+cvs20040624/grub/asmstub.c @@ -42,6 +42,12 @@ #include <sys/time.h> #include <termios.h> #include <signal.h> +#include <sys/mman.h> + +#include <limits.h> +#ifndef PAGESIZE +#define PAGESIZE 4096 +#endif #ifdef __linux__ # include <sys/ioctl.h> /* ioctl */ @@ -142,6 +148,22 @@ assert (grub_scratch_mem == 0); scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15); assert (scratch); + + { + char *p; + int ret; + + /* Align to a multiple of PAGESIZE, assumed to be a power of two. */ + p = (char *) (((long) scratch) & ~(PAGESIZE - 1)); + + /* The simulated stack needs to be executable, since GCC uses stack + * trampolines to implement nested functions. + */ + ret = mprotect (p, 0x100000 + EXTENDED_MEMSIZE + 15, + PROT_READ | PROT_WRITE | PROT_EXEC); + assert (ret == 0); + } + grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4); /* FIXME: simulate the memory holes using mprot, if available. */