From 1e4fda6da918f734dd6dab67b3ddcaba4c2fecb2 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Wed, 8 Feb 2023 13:09:49 +0900 Subject: [PATCH] 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. This has been originally applied as of f3e7806 for v15~, but recently-added buildfarm member gokiburi tests this configuration on older branches as well, causing it to fail randomly as ASLR would be enabled. Suggested-by: Andres Freund Tested-by: Bossart, Nathan Discussion: https://postgr.es/m/20210806032944.m4tz7j2w47mant26%40alap3.anarazel.de Backpatch-through: 12 --- configure | 2 +- configure.in | 1 + src/bin/pg_ctl/pg_ctl.c | 4 ++++ src/common/exec.c | 33 +++++++++++++++++++++++++++++++++ src/include/pg_config.h.in | 3 +++ src/include/port.h | 5 +++++ src/test/regress/pg_regress.c | 4 ++++ src/tools/msvc/Solution.pm | 1 + 8 files changed, 52 insertions(+), 1 deletion(-) diff --git a/configure b/configure index d2db555e9e..19a991aeca 100755 --- a/configure +++ b/configure @@ -13363,7 +13363,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/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/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.in b/configure.in index 31b4e2b08c..3e2767ae52 100644 --- a/configure.in +++ b/configure.in @@ -1377,6 +1377,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 8ab9ecb78f..01b815d4a0 100644 --- a/src/bin/pg_ctl/pg_ctl.c +++ b/src/bin/pg_ctl/pg_ctl.c @@ -453,6 +453,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 8f1147b68a..7f0142fb47 100644 --- a/src/common/exec.c +++ b/src/common/exec.c @@ -25,6 +25,14 @@ #include #include +#ifdef EXEC_BACKEND +#if defined(HAVE_SYS_PERSONALITY_H) +#include +#elif defined(HAVE_SYS_PROCCTL_H) +#include +#endif +#endif + /* Inhibit mingw CRT's auto-globbing of command line arguments */ #if defined(WIN32) && !defined(_MSC_VER) extern int _CRT_glob = 0; /* 0 turns off globbing; 1 turns it on */ @@ -492,6 +500,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 2711c2ce9b..2cd221b85a 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -590,6 +590,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IPC_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PERSONALITY_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PRCTL_H diff --git a/src/include/port.h b/src/include/port.h index 0c3c8d14e7..70b193657e 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -115,6 +115,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 25683a7841..36cc1707bf 100644 --- a/src/test/regress/pg_regress.c +++ b/src/test/regress/pg_regress.c @@ -1191,6 +1191,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 243d0b64fd..4147e8ad26 100644 --- a/src/tools/msvc/Solution.pm +++ b/src/tools/msvc/Solution.pm @@ -380,6 +380,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,