diff options
author | Noah Misch <noah@leadboat.com> | 2014-03-29 00:52:56 -0400 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2014-03-29 01:13:13 -0400 |
commit | 83d12a99daf935d8dc4064cd0282179e08354c3f (patch) | |
tree | 47e19e9547f8497cc78077cf980f5e08a2e9f9ab /src | |
parent | c1932ec9e864d475b1debbcf26ba77c88dc163d0 (diff) | |
download | postgresql-83d12a99daf935d8dc4064cd0282179e08354c3f.tar.gz postgresql-83d12a99daf935d8dc4064cd0282179e08354c3f.zip |
Secure Unix-domain sockets of "make check" temporary clusters.
Any OS user able to access the socket can connect as the bootstrap
superuser and in turn execute arbitrary code as the OS user running the
test. Protect against that by placing the socket in the temporary data
directory, which has mode 0700 thanks to initdb. Back-patch to 8.4 (all
supported versions). The hazard remains wherever the temporary cluster
accepts TCP connections, notably on Windows.
Attempts to run "make check" from a directory with a long name will now
fail. An alternative not sharing that problem was to place the socket
in a subdirectory of /tmp, but that is only secure if /tmp is sticky.
The PG_REGRESS_SOCK_DIR environment variable is available as a
workaround when testing from long directory paths.
As a convenient side effect, this lets testing proceed smoothly in
builds that override DEFAULT_PGSOCKET_DIR. Popular non-default values
like /var/run/postgresql are often unwritable to the build user.
Security: CVE-2014-0067
Diffstat (limited to 'src')
-rw-r--r-- | src/test/regress/pg_regress.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/src/test/regress/pg_regress.c b/src/test/regress/pg_regress.c index a6466ebddff..118562bc0a2 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) |