On Thu, Mar 06, 2014 at 11:52:22PM -0500, Noah Misch wrote:
> On Thu, Mar 06, 2014 at 12:44:34PM -0500, Tom Lane wrote:
> > I'm inclined to suggest that we should put the socket under $CWD by
> > default, but provide some way for the user to override that choice.
> > If they want to put it in /tmp, it's on their head as to how secure
> > that is.  On most modern platforms it'd be fine.
> 
> I am skeptical about the value of protecting systems with non-sticky /tmp, but
> long $CWD isn't of great importance, either.  I'm fine with your suggestion.
> Though the $CWD or one of its parents could be world-writable, that would
> typically mean an attacker could just replace the test cases directly.

Here's the patch.  The temporary data directory makes for a convenient socket
directory; initdb already gives it mode 0700, and we have existing
arrangements to purge it when finished.  One can override the socket directory
by defining PG_REGRESS_SOCK_DIR in the environment.

nm

-- 
Noah Misch
EnterpriseDB                                 http://www.enterprisedb.com
diff --git a/contrib/pg_upgrade/test.sh b/contrib/pg_upgrade/test.sh
index baa7d47..c04398b 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 2>/dev/null
diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml
index 16b3621..f931963 100644
--- a/doc/src/sgml/regress.sgml
+++ b/doc/src/sgml/regress.sgml
@@ -58,21 +58,14 @@ make 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>make
-    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>make 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 @@ make 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 abde5b4..14bf222 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)
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to