emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 63750fd: Fix port to glibc 2.24 (pre-release) + ppc


From: Paul Eggert
Subject: [Emacs-diffs] master 63750fd: Fix port to glibc 2.24 (pre-release) + ppc64
Date: Wed, 20 Jul 2016 07:49:46 +0000 (UTC)

branch: master
commit 63750fd4ed4ff8bb9b3ff8868d4e36e3422adb21
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    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.
---
 src/callproc.c |    4 ++--
 src/emacs.c    |   48 ++++++++++++++++++++++++------------------------
 src/lisp.h     |    6 ++++++
 src/sysdep.c   |   42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 74 insertions(+), 26 deletions(-)

diff --git a/src/callproc.c b/src/callproc.c
index 9ec7893..487115d 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,
   setpgid (0, 0);
   tcsetpgrp (0, pid);
 
-  execve (new_argv[0], new_argv, env);
-  exec_failed (new_argv[0], errno);
+  int errnum = emacs_exec_file (new_argv[0], new_argv, env);
+  exec_failed (new_argv[0], errnum);
 
 #else /* MSDOS */
   pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
diff --git a/src/emacs.c b/src/emacs.c
index fa7ec01..53bcc98 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -112,10 +112,6 @@ extern void moncontrol (int mode);
 #include <sys/resource.h>
 #endif
 
-#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
-#include <sys/personality.h>
-#endif
-
 static const char emacs_version[] = PACKAGE_VERSION;
 static const char emacs_copyright[] = COPYRIGHT;
 static const char emacs_bugreport[] = PACKAGE_BUGREPORT;
@@ -685,6 +681,30 @@ main (int argc, char **argv)
 
   stack_base = &dummy;
 
+  dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0
+                            || strcmp (argv[argc - 1], "bootstrap") == 0);
+
+  /* True if address randomization interferes with memory allocaiton.  */
+# ifdef __PPC64__
+  bool disable_aslr = true;
+# else
+  bool disable_aslr = dumping;
+# endif
+
+  if (disable_aslr && disable_address_randomization ())
+    {
+      /* Set this so the personality will be reverted before execs
+        after this one.  */
+      xputenv ("EMACS_HEAP_EXEC=true");
+
+      /* Address randomization was enabled, but is now disabled.
+        Re-execute Emacs to get a clean slate.  */
+      execvp (argv[0], argv);
+
+      /* If the exec fails, warn and then try anyway.  */
+      perror (argv[0]);
+    }
+
 #ifndef CANNOT_DUMP
   might_dump = !initialized;
 #endif
@@ -793,26 +813,6 @@ main (int argc, char **argv)
         }
     }
 
-  dumping = !initialized && (strcmp (argv[argc - 1], "dump") == 0
-                            || strcmp (argv[argc - 1], "bootstrap") == 0);
-
-#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
-  if (dumping)
-    {
-      int pers = personality (0xffffffff);
-      if (! (pers & ADDR_NO_RANDOMIZE)
-         && 0 <= personality (pers | ADDR_NO_RANDOMIZE))
-       {
-         /* Address randomization was enabled, but is now disabled.
-            Re-execute Emacs to get a clean slate.  */
-         execvp (argv[0], argv);
-
-         /* If the exec fails, warn and then try without a clean slate.  */
-         perror (argv[0]);
-       }
-    }
-#endif
-
 #if defined (HAVE_SETRLIMIT) && defined (RLIMIT_STACK) && !defined (CYGWIN)
   /* Extend the stack space available.  Don't do that if dumping,
      since some systems (e.g. DJGPP) might define a smaller stack
diff --git a/src/lisp.h b/src/lisp.h
index 48c2728..39877d7 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4261,6 +4261,12 @@ struct tty_display_info;
 struct terminal;
 
 /* Defined in sysdep.c.  */
+#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
+extern bool disable_address_randomization (void);
+#else
+INLINE bool disable_address_randomization (void) { return false; }
+#endif
+extern int emacs_exec_file (char const *, char *const *, char *const *);
 extern void init_standard_fds (void);
 extern char *emacs_get_current_dir_name (void);
 extern void stuff_char (char c);
diff --git a/src/sysdep.c b/src/sysdep.c
index 56142a5..1654173 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -129,6 +129,48 @@ static const int baud_convert[] =
     1800, 2400, 4800, 9600, 19200, 38400
   };
 
+#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
+# include <sys/personality.h>
+
+/* Disable address randomization in the current process.  Return true
+   if addresses were randomized but this has been disabled, false
+   otherwise. */
+bool
+disable_address_randomization (void)
+{
+  bool disabled = false;
+  int pers = personality (0xffffffff);
+  disabled = (! (pers & ADDR_NO_RANDOMIZE)
+             && 0 <= personality (pers | ADDR_NO_RANDOMIZE));
+  return disabled;
+}
+#endif
+
+/* Execute the program in FILE, with argument vector ARGV and environ
+   ENVP.  Return an error number if unsuccessful.  This is like execve
+   except it reenables ASLR in the executed program if necessary, and
+   on error it returns an error number rather than -1.  */
+int
+emacs_exec_file (char const *file, char *const *argv, char *const *envp)
+{
+#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
+  int pers = getenv ("EMACS_HEAP_EXEC") ? personality (0xffffffff) : -1;
+  bool change_personality = 0 <= pers && pers & ADDR_NO_RANDOMIZE;
+  if (change_personality)
+    personality (pers & ~ADDR_NO_RANDOMIZE);
+#endif
+
+  execve (file, argv, envp);
+  int err = errno;
+
+#ifdef HAVE_PERSONALITY_ADDR_NO_RANDOMIZE
+  if (change_personality)
+    personality (pers);
+#endif
+
+  return err;
+}
+
 /* If FD is not already open, arrange for it to be open with FLAGS.  */
 static void
 force_open (int fd, int flags)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]