diff --git a/contrib/pg_upgrade/test.sh b/contrib/pg_upgrade/test.sh index 28130f16010720104aae2b73c55334905a73b86d..88f1dc3486664d5efb0b62db4a03528754308fe5 100644 --- a/contrib/pg_upgrade/test.sh +++ b/contrib/pg_upgrade/test.sh @@ -22,8 +22,6 @@ case $testhost in *) LISTEN_ADDRESSES="" ;; esac -POSTMASTER_OPTS="-F -c listen_addresses=$LISTEN_ADDRESSES" - temp_root=$PWD/tmp_check if [ "$1" = '--install' ]; then @@ -79,9 +77,14 @@ PGSERVICE=""; unset PGSERVICE PGSSLMODE=""; unset PGSSLMODE PGREQUIRESSL=""; unset PGREQUIRESSL PGCONNECT_TIMEOUT=""; unset PGCONNECT_TIMEOUT -PGHOST=""; unset PGHOST PGHOSTADDR=""; unset PGHOSTADDR +# Select a socket directory, similarly to pg_regress.c +PGHOST=${PG_REGRESS_SOCK_DIR-$PGDATA} +export PGHOST + +POSTMASTER_OPTS="-F -c listen_addresses=$LISTEN_ADDRESSES -k \"$PGHOST\"" + logdir=$PWD/log rm -rf "$logdir" mkdir "$logdir" diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml index 466b492d25e19f23918987fe784bc009548e2481..98602eccfd8e315270ab64dabf3533dc918d5388 100644 --- a/doc/src/sgml/regress.sgml +++ b/doc/src/sgml/regress.sgml @@ -58,21 +58,14 @@ gmake check <warning> <para> - 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 <literal>gmake - check</> on machines shared with untrusted users. Instead, run the tests - after completing the installation, as described in the next section. - </para> - - <para> - 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 <literal>gmake check</> on an affected + system shared with untrusted users. Instead, run the tests after + completing the installation, as described in the next section. </para> </warning> @@ -111,6 +104,17 @@ gmake MAX_CONNECTIONS=10 check </screen> runs no more than ten tests concurrently. </para> + + <para> + 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 <literal>_POSIX_PATH_MAX</>, testing may fail to start from a + directory with a long name. Work around this problem by pointing + the <envar>PG_REGRESS_SOCK_DIR</> environment variable to a substitute + socket directory having a shorter path. On a multi-user system, give that + directory mode <literal>0700</>. + </para> </sect2> <sect2> diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index a6466ebddff660f229a7f7d3ea25af41e656a520..118562bc0a2db379b562b6db070163bc9f6291c6 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; @@ -759,8 +760,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"); @@ -772,7 +772,24 @@ 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 = malloc(strlen(temp_install) + sizeof("/data")); + sprintf(sockdir, "%s/data", temp_install); + } + doputenv("PGHOST", sockdir); + } unsetenv("PGHOSTADDR"); if (port != -1) { @@ -2246,10 +2263,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)