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)