aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/command.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2015-11-25 17:31:53 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2015-11-25 17:31:53 -0500
commitc5ef8ce53d37e276d70593ff0f4b06dd119cd3ff (patch)
tree79ceb8ee57576c4c1a0dc7662589baef8cf5ec38 /src/bin/psql/command.c
parent46166197c3b3748c3266c694d7c2f5a312ea928e (diff)
downloadpostgresql-c5ef8ce53d37e276d70593ff0f4b06dd119cd3ff.tar.gz
postgresql-c5ef8ce53d37e276d70593ff0f4b06dd119cd3ff.zip
Be more paranoid about null return values from libpq status functions.
PQhost() can return NULL in non-error situations, namely when a Unix-socket connection has been selected by default. That behavior is a tad debatable perhaps, but for the moment we should make sure that psql copes with it. Unfortunately, do_connect() failed to: it could pass a NULL pointer to strcmp(), resulting in crashes on most platforms. This was reported as a security issue by ChenQin of Topsec Security Team, but the consensus of the security list is that it's just a garden-variety bug with no security implications. For paranoia's sake, I made the keep_password test not trust PQuser or PQport either, even though I believe those will never return NULL given a valid PGconn. Back-patch to all supported branches.
Diffstat (limited to 'src/bin/psql/command.c')
-rw-r--r--src/bin/psql/command.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 72c00c1251c..3a82e37401c 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -1750,14 +1750,17 @@ do_connect(char *dbname, char *user, char *host, char *port)
/*
* Any change in the parameters read above makes us discard the password.
* We also discard it if we're to use a conninfo rather than the
- * positional syntax.
+ * positional syntax. Note that currently, PQhost() can return NULL for a
+ * default Unix-socket connection, so we have to allow NULL for host.
*/
- keep_password =
- (o_conn &&
- (strcmp(user, PQuser(o_conn)) == 0) &&
- (!host || strcmp(host, PQhost(o_conn)) == 0) &&
- (strcmp(port, PQport(o_conn)) == 0) &&
- !has_connection_string);
+ if (has_connection_string)
+ keep_password = false;
+ else
+ keep_password =
+ (user && PQuser(o_conn) && strcmp(user, PQuser(o_conn)) == 0) &&
+ ((host && PQhost(o_conn) && strcmp(host, PQhost(o_conn)) == 0) ||
+ (host == NULL && PQhost(o_conn) == NULL)) &&
+ (port && PQport(o_conn) && strcmp(port, PQport(o_conn)) == 0);
/*
* Grab dbname from old connection unless supplied by caller. No password
@@ -1769,8 +1772,8 @@ do_connect(char *dbname, char *user, char *host, char *port)
/*
* If the user asked to be prompted for a password, ask for one now. If
* not, use the password from the old connection, provided the username
- * has not changed. Otherwise, try to connect without a password first,
- * and then ask for a password if needed.
+ * etc have not changed. Otherwise, try to connect without a password
+ * first, and then ask for a password if needed.
*
* XXX: this behavior leads to spurious connection attempts recorded in
* the postmaster's log. But libpq offers no API that would let us obtain