diff --git a/contrib/pg_upgrade/test.sh b/contrib/pg_upgrade/test.sh
index baa7d4748b..c04398bfff 100644
--- a/contrib/pg_upgrade/test.sh
+++ b/contrib/pg_upgrade/test.sh
@@ -25,8 +25,6 @@ case $testhost in
*) LISTEN_ADDRESSES="" ;;
esac
-POSTMASTER_OPTS="-F -c listen_addresses=$LISTEN_ADDRESSES"
-
temp_root=$PWD/tmp_check
if [ "$1" = '--install' ]; then
@@ -86,13 +84,16 @@ PGSERVICE=""; unset PGSERVICE
PGSSLMODE=""; unset PGSSLMODE
PGREQUIRESSL=""; unset PGREQUIRESSL
PGCONNECT_TIMEOUT=""; unset PGCONNECT_TIMEOUT
-PGHOST=""; unset PGHOST
PGHOSTADDR=""; unset PGHOSTADDR
-# Select a non-conflicting port number, similarly to pg_regress.c
+# Select a port number and socket directory, similarly to pg_regress.c
PG_VERSION_NUM=`grep '#define PG_VERSION_NUM' $newsrc/src/include/pg_config.h | awk '{print $3}'`
PGPORT=`expr $PG_VERSION_NUM % 16384 + 49152`
export PGPORT
+PGHOST=${PG_REGRESS_SOCK_DIR-$PGDATA}
+export PGHOST
+
+POSTMASTER_OPTS="-F -c listen_addresses=$LISTEN_ADDRESSES -k \"$PGHOST\""
i=0
while psql -X postgres /dev/null
diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml
index 16b36211f3..f9319637b9 100644
--- a/doc/src/sgml/regress.sgml
+++ b/doc/src/sgml/regress.sgml
@@ -58,21 +58,14 @@ make check
- This test method starts a temporary server, which is configured to accept
- any connection originating on the local machine. Any local user can gain
- database superuser privileges when connecting to this server, and could
- in principle exploit all privileges of the operating-system user running
- the tests. Therefore, it is not recommended that you use make
- check> on machines shared with untrusted users. Instead, run the tests
- after completing the installation, as described in the next section.
-
-
-
- On Unix-like machines, this danger can be avoided if the temporary
- server's socket file is made inaccessible to other users, for example
- by running the tests in a protected chroot. On Windows, the temporary
- server opens a locally-accessible TCP socket, so filesystem protections
- cannot help.
+ On systems lacking Unix-domain sockets, notably Windows, this test method
+ starts a temporary server configured to accept any connection originating
+ on the local machine. Any local user can gain database superuser
+ privileges when connecting to this server, and could in principle exploit
+ all privileges of the operating-system user running the tests. Therefore,
+ it is not recommended that you use make check> on an affected
+ system shared with untrusted users. Instead, run the tests after
+ completing the installation, as described in the next section.
@@ -111,6 +104,17 @@ make MAX_CONNECTIONS=10 check
runs no more than ten tests concurrently.
+
+
+ To protect your operating system user account, the test driver places the
+ server's socket in a relative subdirectory inaccessible to other users.
+ Since most systems constrain the length of socket paths well
+ below _POSIX_PATH_MAX>, testing may fail to start from a
+ directory with a long name. Work around this problem by pointing
+ the PG_REGRESS_SOCK_DIR> environment variable to a substitute
+ socket directory having a shorter path. On a multi-user system, give that
+ directory mode 0700>.
+
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c
index abde5b477c..14bf2224f7 100644
--- a/src/test/regress/pg_regress.c
+++ b/src/test/regress/pg_regress.c
@@ -109,6 +109,7 @@ static const char *progname;
static char *logfilename;
static FILE *logfile;
static char *difffilename;
+static char *sockdir;
static _resultmap *resultmap = NULL;
@@ -758,8 +759,7 @@ initialize_environment(void)
* the wrong postmaster, or otherwise behave in nondefault ways. (Note
* we also use psql's -X switch consistently, so that ~/.psqlrc files
* won't mess things up.) Also, set PGPORT to the temp port, and set
- * or unset PGHOST depending on whether we are using TCP or Unix
- * sockets.
+ * PGHOST depending on whether we are using TCP or Unix sockets.
*/
unsetenv("PGDATABASE");
unsetenv("PGUSER");
@@ -771,7 +771,23 @@ initialize_environment(void)
if (hostname != NULL)
doputenv("PGHOST", hostname);
else
- unsetenv("PGHOST");
+ {
+ sockdir = getenv("PG_REGRESS_SOCK_DIR");
+ if (!sockdir)
+ {
+ /*
+ * Since initdb creates the data directory with secure
+ * permissions, we place the socket there. This ensures no
+ * other OS user can open our socket to exploit our use of
+ * trust authentication. Compared to using the compiled-in
+ * DEFAULT_PGSOCKET_DIR, this also permits testing to work in
+ * builds that relocate it to a directory not writable to the
+ * build/test user.
+ */
+ sockdir = psprintf("%s/data", temp_install);
+ }
+ doputenv("PGHOST", sockdir);
+ }
unsetenv("PGHOSTADDR");
if (port != -1)
{
@@ -2265,10 +2281,11 @@ regression_main(int argc, char *argv[], init_function ifunc, test_function tfunc
*/
header(_("starting postmaster"));
snprintf(buf, sizeof(buf),
- SYSTEMQUOTE "\"%s/postgres\" -D \"%s/data\" -F%s -c \"listen_addresses=%s\" > \"%s/log/postmaster.log\" 2>&1" SYSTEMQUOTE,
- bindir, temp_install,
- debug ? " -d 5" : "",
- hostname ? hostname : "",
+ SYSTEMQUOTE "\"%s/postgres\" -D \"%s/data\" -F%s "
+ "-c \"listen_addresses=%s\" -k \"%s\" "
+ "> \"%s/log/postmaster.log\" 2>&1" SYSTEMQUOTE,
+ bindir, temp_install, debug ? " -d 5" : "",
+ hostname ? hostname : "", sockdir ? sockdir : "",
outputdir);
postmaster_pid = spawn_process(buf);
if (postmaster_pid == INVALID_PID)