Make EXEC_BACKEND more convenient on Linux and FreeBSD.
authorThomas Munro <tmunro@postgresql.org>
Mon, 10 Jan 2022 10:54:11 +0000 (23:54 +1300)
committerThomas Munro <tmunro@postgresql.org>
Mon, 10 Jan 2022 11:04:33 +0000 (00:04 +1300)
Try to disable ASLR when building in EXEC_BACKEND mode, to avoid random
memory mapping failures while testing.  For developer use only, no
effect on regular builds.

Suggested-by: Andres Freund <andres@anarazel.de>
Tested-by: Bossart, Nathan <bossartn@amazon.com>
Discussion: https://postgr.es/m/20210806032944.m4tz7j2w47mant26%40alap3.anarazel.de

configure
configure.ac
src/bin/pg_ctl/pg_ctl.c
src/common/exec.c
src/include/pg_config.h.in
src/include/port.h
src/test/regress/pg_regress.c
src/tools/msvc/Solution.pm

index 8714420bef2032974c4b460249aa9f2edefd8e98..3f2aea0d7decb2ec7043fdf5ea9a22673f07da6f 100755 (executable)
--- a/configure
+++ b/configure
@@ -13603,7 +13603,7 @@ $as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
 fi
 
 
-for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/event.h sys/ipc.h sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/uio.h sys/un.h termios.h ucred.h wctype.h
+for ac_header in atomic.h copyfile.h execinfo.h getopt.h ifaddrs.h langinfo.h mbarrier.h poll.h sys/epoll.h sys/event.h sys/ipc.h sys/personality.h sys/prctl.h sys/procctl.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/sockio.h sys/tas.h sys/uio.h sys/un.h termios.h ucred.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
index 49548b7a228abe226c3a0d365f9898e9a5169ed5..95287705f6b5583f5b4d6278d5647e0da2786acb 100644 (file)
@@ -1404,6 +1404,7 @@ AC_CHECK_HEADERS(m4_normalize([
        sys/epoll.h
        sys/event.h
        sys/ipc.h
+       sys/personality.h
        sys/prctl.h
        sys/procctl.h
        sys/pstat.h
index 4986c8f5177cfcb9156362296cc2647a28c5ff2b..070072299f1a4ed9c1695fe1919adb62ac14ec6b 100644 (file)
@@ -451,6 +451,10 @@ start_postmaster(void)
        fflush(stdout);
        fflush(stderr);
 
+#ifdef EXEC_BACKEND
+       pg_disable_aslr();
+#endif
+
        pm_pid = fork();
        if (pm_pid < 0)
        {
index 9428b7393c2f8609c253ec0c221ba964e52630e3..95ef13c322d735d6fd468dbaac1d831e7ba285ec 100644 (file)
 #include <sys/wait.h>
 #include <unistd.h>
 
+#ifdef EXEC_BACKEND
+#if defined(HAVE_SYS_PERSONALITY_H)
+#include <sys/personality.h>
+#elif defined(HAVE_SYS_PROCCTL_H)
+#include <sys/procctl.h>
+#endif
+#endif
+
 /*
  * Hacky solution to allow expressing both frontend and backend error reports
  * in one macro call.  First argument of log_error is an errcode() call of
@@ -470,6 +478,31 @@ set_pglocale_pgservice(const char *argv0, const char *app)
        }
 }
 
+#ifdef EXEC_BACKEND
+/*
+ * For the benefit of PostgreSQL developers testing EXEC_BACKEND on Unix
+ * systems (code paths normally exercised only on Windows), provide a way to
+ * disable address space layout randomization, if we know how on this platform.
+ * Otherwise, backends may fail to attach to shared memory at the fixed address
+ * chosen by the postmaster.  (See also the macOS-specific hack in
+ * sysv_shmem.c.)
+ */
+int
+pg_disable_aslr(void)
+{
+#if defined(HAVE_SYS_PERSONALITY_H)
+       return personality(ADDR_NO_RANDOMIZE);
+#elif defined(HAVE_SYS_PROCCTL_H) && defined(PROC_ASLR_FORCE_DISABLE)
+       int                     data = PROC_ASLR_FORCE_DISABLE;
+
+       return procctl(P_PID, 0, PROC_ASLR_CTL, &data);
+#else
+       errno = ENOSYS;
+       return -1;
+#endif
+}
+#endif
+
 #ifdef WIN32
 
 /*
index 7525c165974b92817377a024258ad76c6bda35a5..9d9bd6b9efc54bbfca3c88836942b9cd3cc0c835 100644 (file)
 /* Define to 1 if you have the <sys/ipc.h> header file. */
 #undef HAVE_SYS_IPC_H
 
+/* Define to 1 if you have the <sys/personality.h> header file. */
+#undef HAVE_SYS_PERSONALITY_H
+
 /* Define to 1 if you have the <sys/prctl.h> header file. */
 #undef HAVE_SYS_PRCTL_H
 
index 22ea292a6df918581e1dac67c89f92ae9d748ad4..56e3721f6a46af6c55fc8c1c991c3fa6bdbd526f 100644 (file)
@@ -140,6 +140,11 @@ extern char *pipe_read_line(char *cmd, char *line, int maxsize);
 /* Doesn't belong here, but this is used with find_other_exec(), so... */
 #define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
 
+#ifdef EXEC_BACKEND
+/* Disable ASLR before exec, for developer builds only (in exec.c) */
+extern int pg_disable_aslr(void);
+#endif
+
 
 #if defined(WIN32) || defined(__CYGWIN__)
 #define EXE ".exe"
index a34efed095c883ff1a5172bd4731349dbc2e77d2..cc311dba4c59184a31103412970f39b28da2424b 100644 (file)
@@ -1104,6 +1104,10 @@ spawn_process(const char *cmdline)
        if (logfile)
                fflush(logfile);
 
+#ifdef EXEC_BACKEND
+       pg_disable_aslr();
+#endif
+
        pid = fork();
        if (pid == -1)
        {
index 734d8e073fa2f54f1adf0737f28fe5835fcc2bff..e47c2d648cb50cc5780af1c4b0cab0d420bd8c26 100644 (file)
@@ -397,6 +397,7 @@ sub GenerateFiles
                HAVE_SYS_EPOLL_H                         => undef,
                HAVE_SYS_EVENT_H                         => undef,
                HAVE_SYS_IPC_H                           => undef,
+               HAVE_SYS_PERSONALITY_H                   => undef,
                HAVE_SYS_PRCTL_H                         => undef,
                HAVE_SYS_PROCCTL_H                       => undef,
                HAVE_SYS_PSTAT_H                         => undef,