summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2022-01-10 10:54:11 +0000
committerThomas Munro2022-01-10 11:04:33 +0000
commitf3e78069db7f7a753ebfe1010b810e47e0d2aa9a (patch)
tree87b4da09ae69dfbcbd47d65c206cfd0a2fe88335
parentee419607381dd9a8031f2bc226c742a3289b7f33 (diff)
Make EXEC_BACKEND more convenient on Linux and FreeBSD.
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 <[email protected]> Tested-by: Bossart, Nathan <[email protected]> Discussion: https://postgr.es/m/20210806032944.m4tz7j2w47mant26%40alap3.anarazel.de
-rwxr-xr-xconfigure2
-rw-r--r--configure.ac1
-rw-r--r--src/bin/pg_ctl/pg_ctl.c4
-rw-r--r--src/common/exec.c33
-rw-r--r--src/include/pg_config.h.in3
-rw-r--r--src/include/port.h5
-rw-r--r--src/test/regress/pg_regress.c4
-rw-r--r--src/tools/msvc/Solution.pm1
8 files changed, 52 insertions, 1 deletions
diff --git a/configure b/configure
index 8714420bef..3f2aea0d7d 100755
--- 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"
diff --git a/configure.ac b/configure.ac
index 49548b7a22..95287705f6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 4986c8f517..070072299f 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -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)
{
diff --git a/src/common/exec.c b/src/common/exec.c
index 9428b7393c..95ef13c322 100644
--- a/src/common/exec.c
+++ b/src/common/exec.c
@@ -25,6 +25,14 @@
#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
/*
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 7525c16597..9d9bd6b9ef 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -614,6 +614,9 @@
/* 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
diff --git a/src/include/port.h b/src/include/port.h
index 22ea292a6d..56e3721f6a 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -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"
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index a34efed095..cc311dba4c 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -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)
{
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 734d8e073f..e47c2d648c 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -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,