0001-Try-to-make-EXEC_BACKEND-more-convenient-on-macOS.patch
application/x-patch
Filename: 0001-Try-to-make-EXEC_BACKEND-more-convenient-on-macOS.patch
Type: application/x-patch
Part: 0
Patch
Format: format-patch
Series: patch 0001
Subject: Try to make EXEC_BACKEND more convenient on macOS.
| File | + | − |
|---|---|---|
| src/backend/postmaster/postmaster.c | 33 | 0 |
| src/bin/pg_ctl/pg_ctl.c | 50 | 1 |
From 9bcedede452c1f37dd790f86bc587353cc455e3f Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Tue, 10 Aug 2021 22:05:00 +1200
Subject: [PATCH] Try to make EXEC_BACKEND more convenient on macOS.
Use posix_spawn() instead of fork() + execv(), with a special
undocumented flag that disables ASLR, if you build with -DEXEC_BACKEND
-DUSE_POSIX_SPAWN -DUSE_POSIX_SPAWN_DISABLE_ASLR.
XXX Experiment only...
XXX Still fails make check occasionally :-(
---
src/backend/postmaster/postmaster.c | 33 +++++++++++++++++++
src/bin/pg_ctl/pg_ctl.c | 51 ++++++++++++++++++++++++++++-
2 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index fc0bc8d99e..3a1e9ae8f8 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -93,6 +93,10 @@
#include <pthread.h>
#endif
+#ifdef USE_POSIX_SPAWN
+#include <spawn.h>
+#endif
+
#include "access/transam.h"
#include "access/xlog.h"
#include "catalog/pg_control.h"
@@ -4585,6 +4589,10 @@ internal_forkexec(int argc, char *argv[], Port *port)
char tmpfilename[MAXPGPATH];
BackendParameters param;
FILE *fp;
+#ifdef USE_POSIX_SPAWN
+ posix_spawn_file_actions_t spawn_file_actions;
+ posix_spawnattr_t spawnattrs;
+#endif
if (!save_backend_variables(¶m, port))
return -1; /* log made by save_backend_variables */
@@ -4642,6 +4650,30 @@ internal_forkexec(int argc, char *argv[], Port *port)
/* Insert temp file name after --fork argument */
argv[2] = tmpfilename;
+#ifdef USE_POSIX_SPAWN
+ posix_spawn_file_actions_init(&spawn_file_actions);
+ posix_spawnattr_init(&spawnattrs);
+#ifdef USE_POSIX_SPAWN_DISABLE_ASLR
+ /*
+ * Undocumented magic. See bsd/sys/spawn.h and bsd/kern/kern_exec.c in the
+ * Darwin sources at https://github.com/apple/darwin-xnu.
+ */
+ if ((errno = posix_spawnattr_setflags(&spawnattrs, 0x0100)) != 0)
+ elog(ERROR, "could not set ASLR disable flag when spawning backend: %m");
+#endif
+ errno = posix_spawn(&pid,
+ postgres_exec_path,
+ &spawn_file_actions,
+ &spawnattrs,
+ argv,
+ NULL);
+ if (errno != 0)
+ {
+ ereport(LOG,
+ (errmsg("could not spawn server process \"%s\": %m",
+ postgres_exec_path)));
+ }
+#else
/* Fire off execv in child */
if ((pid = fork_process()) == 0)
{
@@ -4654,6 +4686,7 @@ internal_forkexec(int argc, char *argv[], Port *port)
exit(1);
}
}
+#endif
return pid; /* Parent returns pid, or -1 on fork failure */
}
diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 7985da0a94..f105e483c4 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -18,6 +18,10 @@
#include <sys/wait.h>
#include <unistd.h>
+#ifdef USE_POSIX_SPAWN
+#include <spawn.h>
+#endif
+
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/time.h>
#include <sys/resource.h>
@@ -442,15 +446,59 @@ free_readfile(char **optlines)
static pgpid_t
start_postmaster(void)
{
+#ifdef USE_POSIX_SPAWN
+ posix_spawn_file_actions_t spawn_file_actions;
+ posix_spawnattr_t spawnattrs;
+#else
char cmd[MAXPGPATH];
+#endif
#ifndef WIN32
- pgpid_t pm_pid;
+ pid_t pm_pid;
/* Flush stdio channels just before fork, to avoid double-output problems */
fflush(stdout);
fflush(stderr);
+#ifdef USE_POSIX_SPAWN
+ posix_spawn_file_actions_init(&spawn_file_actions);
+ posix_spawnattr_init(&spawnattrs);
+#ifdef USE_POSIX_SPAWN_DISABLE_ASLR
+ /*
+ * Undocumented magic. See bsd/sys/spawn.h and bsd/kern/kern_exec.c in the
+ * Darwin sources at https://github.com/apple/darwin-xnu.
+ */
+ if ((errno = posix_spawnattr_setflags(&spawnattrs, 0x0100)) != 0)
+ write_stderr(_("could not set undocumented ASLR disable flag when spawning postmaster: %s"),
+ strerror(errno));
+#endif
+ {
+ /* XXX:HACK this is incomplete, doesn't include the postopts... */
+ /* XXX Theory here was that shell exec style used by the exec code
+ * might drop the flag, hence spawning executable directly, but doing
+ * that properly would involve unpicking the options and their quotes
+ * etc... */
+ char *args[] = {
+ exec_path,
+ "-D",
+ getenv("PGDATA"),
+ NULL
+ };
+ errno = posix_spawn(&pm_pid,
+ exec_path,
+ &spawn_file_actions,
+ &spawnattrs,
+ args,
+ NULL);
+ }
+ if (errno != 0)
+ {
+ write_stderr(_("%s: could not start server: %s\n"),
+ progname, strerror(errno));
+ exit(1);
+ }
+ return pm_pid;
+#else
pm_pid = fork();
if (pm_pid < 0)
{
@@ -502,6 +550,7 @@ start_postmaster(void)
exit(1);
return 0; /* keep dumb compilers quiet */
+#endif
#else /* WIN32 */
--
2.30.1 (Apple Git-130)