GNU bug report logs -
#900
temacs segmentation fault in unexec under Linux 2.6.26
Previous Next
Reported by: Ulrich Mueller <ulm <at> gentoo.org>
Date: Sat, 6 Sep 2008 03:45:03 UTC
Severity: normal
Tags: patch
Merged with 443
Found in version 22.3
Done: Chong Yidong <cyd <at> stupidchicken.com>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
Tags: patch
I guess the issue boils down to the fact that testing for
(heap_bss_diff > MAX_HEAP_BSS_DIFF) is not a reliable method to
determine if heap randomisation is switched on. "heap_bss_diff" is
random in nature, and will therefore be smaller than MAX_HEAP_BSS_DIFF
in some cases. These lead to the observed segmentation faults.
Here is an attempt of a patch, asking the kernel (via /proc fs) for
the presence of the feature. I've also made the definition of
ADDR_NO_RANDOMIZE conditional, since it is already defined in newer
versions of personality.h.
Patch was tested with 22.3, but also applies cleanly to the CVS trunk
of today.
*** emacs-orig/src/emacs.c 2008-05-12 21:55:52.000000000 +0200
--- emacs/src/emacs.c 2008-09-09 16:26:52.000000000 +0200
***************
*** 73,78 ****
--- 73,81 ----
#ifdef HAVE_PERSONALITY_LINUX32
#include <sys/personality.h>
+ #ifndef ADDR_NO_RANDOMIZE
+ #define ADDR_NO_RANDOMIZE 0x0040000
+ #endif
#endif
#ifndef O_RDWR
***************
*** 789,794 ****
--- 792,817 ----
return count >= 3 ? REPORT_EMACS_BUG_PRETEST_ADDRESS : REPORT_EMACS_BUG_ADDRESS;
}
+ #ifdef HAVE_PERSONALITY_LINUX32
+ /* Get the `randomize_va_space' parameter. A value of 2 (introduced
+ in Linux 2.6.25) indicates that brk() randomization is switched on,
+ which will break unexec. See <http://lkml.org/lkml/2007/10/23/435>. */
+ static int
+ linux_randomize_va_space ()
+ {
+ FILE *fp;
+ int rand, count;
+
+ fp = fopen ("/proc/sys/kernel/randomize_va_space", "r");
+ if (!fp)
+ return -1;
+ count = fscanf (fp, "%d", &rand);
+ (void) fclose (fp);
+ if (count != 1)
+ return -1;
+ return rand;
+ }
+ #endif /* HAVE_PERSONALITY_LINUX32 */
/* ARGSUSED */
int
***************
*** 883,906 ****
if (!initialized
&& (strcmp (argv[argc-1], "dump") == 0
|| strcmp (argv[argc-1], "bootstrap") == 0)
! && heap_bss_diff > MAX_HEAP_BSS_DIFF)
{
! if (! getenv ("EMACS_HEAP_EXEC"))
! {
! /* Set this so we only do this once. */
! putenv("EMACS_HEAP_EXEC=true");
!
! /* A flag to turn off address randomization which is introduced
! in linux kernel shipped with fedora core 4 */
! #define ADD_NO_RANDOMIZE 0x0040000
! personality (PER_LINUX32 | ADD_NO_RANDOMIZE);
! #undef ADD_NO_RANDOMIZE
!
! execvp (argv[0], argv);
!
! /* If the exec fails, try to dump anyway. */
! perror ("execvp");
! }
}
#endif /* HAVE_PERSONALITY_LINUX32 */
--- 906,925 ----
if (!initialized
&& (strcmp (argv[argc-1], "dump") == 0
|| strcmp (argv[argc-1], "bootstrap") == 0)
! && !getenv ("EMACS_HEAP_EXEC")
! && (heap_bss_diff > MAX_HEAP_BSS_DIFF
! || linux_randomize_va_space() >= 2))
{
! /* Set this so we only do this once. */
! putenv("EMACS_HEAP_EXEC=true");
!
! /* Set personality and disable randomization of VA space. */
! personality (PER_LINUX32 | ADDR_NO_RANDOMIZE);
!
! execvp (argv[0], argv);
!
! /* If the exec fails, try to dump anyway. */
! perror ("execvp");
}
#endif /* HAVE_PERSONALITY_LINUX32 */
This bug report was last modified 16 years and 214 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.