aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2018-11-11 22:18:47 -0800
committerPaul Eggert2018-11-11 22:20:39 -0800
commitc14eab222c5208ec0650292c3771a3ee632fdb0d (patch)
treeca3ca2cd05505a7edcb1bb062e2a669f870255f5 /src
parentb87c874aa1016939ccbee4cd3bd1384726cb2220 (diff)
downloademacs-c14eab222c5208ec0650292c3771a3ee632fdb0d.tar.gz
emacs-c14eab222c5208ec0650292c3771a3ee632fdb0d.zip
Fix dumping on GNU/Linux ppc64le
Problem reported by Thomas Fitzsimmons (Bug#33174). * src/emacs.c (main): Adjust to sysdep.c changes. * src/sysdep.c (exec_personality): New static var. (disable_address_randomization): Remove, replacing with ... (maybe_disable_address_randomization): ... this new function. Do not set or use an environment variable; use a command-line argument instead, and set the new static var. Migrate the emacs.c personality-change code to here, where it belongs. (emacs_exec_file): Simplify by using new static var.
Diffstat (limited to 'src')
-rw-r--r--src/emacs.c23
-rw-r--r--src/lisp.h7
-rw-r--r--src/sysdep.c73
3 files changed, 53 insertions, 50 deletions
diff --git a/src/emacs.c b/src/emacs.c
index 07df191035c..512174d562e 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -706,28 +706,7 @@ main (int argc, char **argv)
706 dumping = false; 706 dumping = false;
707#endif 707#endif
708 708
709 /* True if address randomization interferes with memory allocation. */ 709 argc = maybe_disable_address_randomization (dumping, argc, argv);
710# ifdef __PPC64__
711 bool disable_aslr = true;
712# else
713 bool disable_aslr = dumping;
714# endif
715
716 if (disable_aslr && disable_address_randomization ()
717 && !getenv ("EMACS_HEAP_EXEC"))
718 {
719 /* Set this so the personality will be reverted before execs
720 after this one, and to work around an re-exec loop on buggy
721 kernels (Bug#32083). */
722 xputenv ("EMACS_HEAP_EXEC=true");
723
724 /* Address randomization was enabled, but is now disabled.
725 Re-execute Emacs to get a clean slate. */
726 execvp (argv[0], argv);
727
728 /* If the exec fails, warn and then try anyway. */
729 perror (argv[0]);
730 }
731 710
732#ifndef CANNOT_DUMP 711#ifndef CANNOT_DUMP
733 might_dump = !initialized; 712 might_dump = !initialized;
diff --git a/src/lisp.h b/src/lisp.h
index eb6762678c7..383d61274c4 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4325,9 +4325,12 @@ struct tty_display_info;
4325 4325
4326/* Defined in sysdep.c. */ 4326/* Defined in sysdep.c. */
4327#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE 4327#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
4328extern bool disable_address_randomization (void); 4328extern int maybe_disable_address_randomization (bool, int, char **);
4329#else 4329#else
4330INLINE bool disable_address_randomization (void) { return false; } 4330INLINE void
4331maybe_disable_address_randomization (bool dumping, int argc, char **argv)
4332{
4333}
4331#endif 4334#endif
4332extern int emacs_exec_file (char const *, char *const *, char *const *); 4335extern int emacs_exec_file (char const *, char *const *, char *const *);
4333extern void init_standard_fds (void); 4336extern void init_standard_fds (void);
diff --git a/src/sysdep.c b/src/sysdep.c
index 7a0c8a8ab85..ddcb594f668 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -150,22 +150,52 @@ static const int baud_convert[] =
150#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE 150#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
151# include <sys/personality.h> 151# include <sys/personality.h>
152 152
153/* Disable address randomization in the current process. Return true 153/* If not -1, the personality that should be restored before exec. */
154 if addresses were randomized but this has been disabled, false 154static int exec_personality;
155 otherwise. */ 155
156bool 156/* Try to disable randomization if the current process needs it and
157disable_address_randomization (void) 157 does not appear to have it already. */
158int
159maybe_disable_address_randomization (bool dumping, int argc, char **argv)
158{ 160{
159 int pers = personality (0xffffffff); 161 /* Undocumented Emacs option used only by this function. */
160 if (pers < 0) 162 static char const aslr_disabled_option[] = "--__aslr-disabled";
161 return false;
162 int desired_pers = pers | ADDR_NO_RANDOMIZE;
163 163
164 /* Call 'personality' twice, to detect buggy platforms like WSL 164 if (argc < 2 || strcmp (argv[1], aslr_disabled_option) != 0)
165 where 'personality' always returns 0. */ 165 {
166 return (pers != desired_pers 166 bool disable_aslr = dumping;
167 && personality (desired_pers) == pers 167# ifdef __PPC64__
168 && personality (0xffffffff) == desired_pers); 168 disable_aslr = true;
169# endif
170 exec_personality = disable_aslr ? personality (0xffffffff) : -1;
171 if (exec_personality & ADDR_NO_RANDOMIZE)
172 exec_personality = -1;
173 if (exec_personality != -1
174 && personality (exec_personality | ADDR_NO_RANDOMIZE) != -1)
175 {
176 char **newargv = malloc ((argc + 2) * sizeof *newargv);
177 if (newargv)
178 {
179 /* Invoke self with undocumented option. */
180 newargv[0] = argv[0];
181 newargv[1] = (char *) aslr_disabled_option;
182 memcpy (&newargv[2], &argv[1], argc * sizeof *newargv);
183 execvp (newargv[0], newargv);
184 }
185
186 /* If malloc or execvp fails, warn and then try anyway. */
187 perror (argv[0]);
188 free (newargv);
189 }
190 }
191 else
192 {
193 /* Our earlier incarnation already disabled ASLR. */
194 argc--;
195 memmove (&argv[1], &argv[2], argc * sizeof *argv);
196 }
197
198 return argc;
169} 199}
170#endif 200#endif
171 201
@@ -177,21 +207,12 @@ int
177emacs_exec_file (char const *file, char *const *argv, char *const *envp) 207emacs_exec_file (char const *file, char *const *argv, char *const *envp)
178{ 208{
179#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE 209#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
180 int pers = getenv ("EMACS_HEAP_EXEC") ? personality (0xffffffff) : -1; 210 if (exec_personality != -1)
181 bool change_personality = 0 <= pers && pers & ADDR_NO_RANDOMIZE; 211 personality (exec_personality);
182 if (change_personality)
183 personality (pers & ~ADDR_NO_RANDOMIZE);
184#endif 212#endif
185 213
186 execve (file, argv, envp); 214 execve (file, argv, envp);
187 int err = errno; 215 return errno;
188
189#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
190 if (change_personality)
191 personality (pers);
192#endif
193
194 return err;
195} 216}
196 217
197/* If FD is not already open, arrange for it to be open with FLAGS. */ 218/* If FD is not already open, arrange for it to be open with FLAGS. */