diff options
| author | Paul Eggert | 2016-07-20 09:16:49 +0200 |
|---|---|---|
| committer | Paul Eggert | 2016-07-20 09:49:41 +0200 |
| commit | 63750fd4ed4ff8bb9b3ff8868d4e36e3422adb21 (patch) | |
| tree | cff2b72f4d4fc257cc7cf73ec13777c768317328 | |
| parent | bf5ddded70c11edaf3514b25da27fc71cfb8e965 (diff) | |
| download | emacs-63750fd4ed4ff8bb9b3ff8868d4e36e3422adb21.tar.gz emacs-63750fd4ed4ff8bb9b3ff8868d4e36e3422adb21.zip | |
Fix port to glibc 2.24 (pre-release) + ppc64
* src/callproc.c (child_setup): Use emacs_exec_file
so that ASLR is enabled in the child process.
* src/emacs.c: Move some personality details into sys/sysdep.c.
Do not include <sys/personality.h>.
(main): Disable ASLR earlier, so that we don’t chdir twice.
* src/lisp.h (disable_address_randomization): New decl.
* src/sysdep.c (disable_address_randomization)
[HAVE_PERSONALITY_ADDR_NO_RANDOMIZE]: Move personality details
here from emacs.c.
(emacs_exec_file): New function.
| -rw-r--r-- | src/callproc.c | 4 | ||||
| -rw-r--r-- | src/emacs.c | 48 | ||||
| -rw-r--r-- | src/lisp.h | 6 | ||||
| -rw-r--r-- | src/sysdep.c | 42 |
4 files changed, 74 insertions, 26 deletions
diff --git a/src/callproc.c b/src/callproc.c index 9ec7893868d..487115d60c3 100644 --- a/src/callproc.c +++ b/src/callproc.c | |||
| @@ -1317,8 +1317,8 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp, | |||
| 1317 | setpgid (0, 0); | 1317 | setpgid (0, 0); |
| 1318 | tcsetpgrp (0, pid); | 1318 | tcsetpgrp (0, pid); |
| 1319 | 1319 | ||
| 1320 | execve (new_argv[0], new_argv, env); | 1320 | int errnum = emacs_exec_file (new_argv[0], new_argv, env); |
| 1321 | exec_failed (new_argv[0], errno); | 1321 | exec_failed (new_argv[0], errnum); |
| 1322 | 1322 | ||
| 1323 | #else /* MSDOS */ | 1323 | #else /* MSDOS */ |
| 1324 | pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); | 1324 | pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env); |
diff --git a/src/emacs.c b/src/emacs.c index fa7ec017fb5..53bcc9879a9 100644 --- a/src/emacs.c +++ b/src/emacs.c | |||
| @@ -112,10 +112,6 @@ extern void moncontrol (int mode); | |||
| 112 | #include <sys/resource.h> | 112 | #include <sys/resource.h> |
| 113 | #endif | 113 | #endif |
| 114 | 114 | ||
| 115 | #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE | ||
| 116 | #include <sys/personality.h> | ||
| 117 | #endif | ||
| 118 | |||
| 119 | static const char emacs_version[] = PACKAGE_VERSION; | 115 | static const char emacs_version[] = PACKAGE_VERSION; |
| 120 | static const char emacs_copyright[] = COPYRIGHT; | 116 | static const char emacs_copyright[] = COPYRIGHT; |
| 121 | static const char emacs_bugreport[] = PACKAGE_BUGREPORT; | 117 | static const char emacs_bugreport[] = PACKAGE_BUGREPORT; |
| @@ -685,6 +681,30 @@ main (int argc, char **argv) | |||
| 685 | 681 | ||
| 686 | stack_base = &dummy; | 682 | stack_base = &dummy; |
| 687 | 683 | ||
| 684 | dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0 | ||
| 685 | || strcmp (argv[argc - 1], "bootstrap") == 0); | ||
| 686 | |||
| 687 | /* True if address randomization interferes with memory allocaiton. */ | ||
| 688 | # ifdef __PPC64__ | ||
| 689 | bool disable_aslr = true; | ||
| 690 | # else | ||
| 691 | bool disable_aslr = dumping; | ||
| 692 | # endif | ||
| 693 | |||
| 694 | if (disable_aslr && disable_address_randomization ()) | ||
| 695 | { | ||
| 696 | /* Set this so the personality will be reverted before execs | ||
| 697 | after this one. */ | ||
| 698 | xputenv ("EMACS_HEAP_EXEC=true"); | ||
| 699 | |||
| 700 | /* Address randomization was enabled, but is now disabled. | ||
| 701 | Re-execute Emacs to get a clean slate. */ | ||
| 702 | execvp (argv[0], argv); | ||
| 703 | |||
| 704 | /* If the exec fails, warn and then try anyway. */ | ||
| 705 | perror (argv[0]); | ||
| 706 | } | ||
| 707 | |||
| 688 | #ifndef CANNOT_DUMP | 708 | #ifndef CANNOT_DUMP |
| 689 | might_dump = !initialized; | 709 | might_dump = !initialized; |
| 690 | #endif | 710 | #endif |
| @@ -793,26 +813,6 @@ main (int argc, char **argv) | |||
| 793 | } | 813 | } |
| 794 | } | 814 | } |
| 795 | 815 | ||
| 796 | dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0 | ||
| 797 | || strcmp (argv[argc - 1], "bootstrap") == 0); | ||
| 798 | |||
| 799 | #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE | ||
| 800 | if (dumping) | ||
| 801 | { | ||
| 802 | int pers = personality (0xffffffff); | ||
| 803 | if (! (pers & ADDR_NO_RANDOMIZE) | ||
| 804 | && 0 <= personality (pers | ADDR_NO_RANDOMIZE)) | ||
| 805 | { | ||
| 806 | /* Address randomization was enabled, but is now disabled. | ||
| 807 | Re-execute Emacs to get a clean slate. */ | ||
| 808 | execvp (argv[0], argv); | ||
| 809 | |||
| 810 | /* If the exec fails, warn and then try without a clean slate. */ | ||
| 811 | perror (argv[0]); | ||
| 812 | } | ||
| 813 | } | ||
| 814 | #endif | ||
| 815 | |||
| 816 | #if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK) && !defined (CYGWIN) | 816 | #if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK) && !defined (CYGWIN) |
| 817 | /* Extend the stack space available. Don't do that if dumping, | 817 | /* Extend the stack space available. Don't do that if dumping, |
| 818 | since some systems (e.g. DJGPP) might define a smaller stack | 818 | since some systems (e.g. DJGPP) might define a smaller stack |
diff --git a/src/lisp.h b/src/lisp.h index 48c27281643..39877d7bb4d 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4261,6 +4261,12 @@ struct tty_display_info; | |||
| 4261 | struct terminal; | 4261 | struct terminal; |
| 4262 | 4262 | ||
| 4263 | /* Defined in sysdep.c. */ | 4263 | /* Defined in sysdep.c. */ |
| 4264 | #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE | ||
| 4265 | extern bool disable_address_randomization (void); | ||
| 4266 | #else | ||
| 4267 | INLINE bool disable_address_randomization (void) { return false; } | ||
| 4268 | #endif | ||
| 4269 | extern int emacs_exec_file (char const *, char *const *, char *const *); | ||
| 4264 | extern void init_standard_fds (void); | 4270 | extern void init_standard_fds (void); |
| 4265 | extern char *emacs_get_current_dir_name (void); | 4271 | extern char *emacs_get_current_dir_name (void); |
| 4266 | extern void stuff_char (char c); | 4272 | extern void stuff_char (char c); |
diff --git a/src/sysdep.c b/src/sysdep.c index 56142a55cdf..16541735f03 100644 --- a/src/sysdep.c +++ b/src/sysdep.c | |||
| @@ -129,6 +129,48 @@ static const int baud_convert[] = | |||
| 129 | 1800, 2400, 4800, 9600, 19200, 38400 | 129 | 1800, 2400, 4800, 9600, 19200, 38400 |
| 130 | }; | 130 | }; |
| 131 | 131 | ||
| 132 | #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE | ||
| 133 | # include <sys/personality.h> | ||
| 134 | |||
| 135 | /* Disable address randomization in the current process. Return true | ||
| 136 | if addresses were randomized but this has been disabled, false | ||
| 137 | otherwise. */ | ||
| 138 | bool | ||
| 139 | disable_address_randomization (void) | ||
| 140 | { | ||
| 141 | bool disabled = false; | ||
| 142 | int pers = personality (0xffffffff); | ||
| 143 | disabled = (! (pers & ADDR_NO_RANDOMIZE) | ||
| 144 | && 0 <= personality (pers | ADDR_NO_RANDOMIZE)); | ||
| 145 | return disabled; | ||
| 146 | } | ||
| 147 | #endif | ||
| 148 | |||
| 149 | /* Execute the program in FILE, with argument vector ARGV and environ | ||
| 150 | ENVP. Return an error number if unsuccessful. This is like execve | ||
| 151 | except it reenables ASLR in the executed program if necessary, and | ||
| 152 | on error it returns an error number rather than -1. */ | ||
| 153 | int | ||
| 154 | emacs_exec_file (char const *file, char *const *argv, char *const *envp) | ||
| 155 | { | ||
| 156 | #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE | ||
| 157 | int pers = getenv ("EMACS_HEAP_EXEC") ? personality (0xffffffff) : -1; | ||
| 158 | bool change_personality = 0 <= pers && pers & ADDR_NO_RANDOMIZE; | ||
| 159 | if (change_personality) | ||
| 160 | personality (pers & ~ADDR_NO_RANDOMIZE); | ||
| 161 | #endif | ||
| 162 | |||
| 163 | execve (file, argv, envp); | ||
| 164 | int err = errno; | ||
| 165 | |||
| 166 | #ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE | ||
| 167 | if (change_personality) | ||
| 168 | personality (pers); | ||
| 169 | #endif | ||
| 170 | |||
| 171 | return err; | ||
| 172 | } | ||
| 173 | |||
| 132 | /* If FD is not already open, arrange for it to be open with FLAGS. */ | 174 | /* If FD is not already open, arrange for it to be open with FLAGS. */ |
| 133 | static void | 175 | static void |
| 134 | force_open (int fd, int flags) | 176 | force_open (int fd, int flags) |