mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	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.
This commit is contained in:
		@@ -1623,15 +1623,18 @@ do_connect(char *dbname, char *user, char *host, char *port)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Any change in the parameters read above makes us discard the password.
 | 
						 * 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
 | 
						 * We also discard it if we're to use a conninfo rather than the
 | 
				
			||||||
	 * syntax.
 | 
						 * positional syntax.  Note that currently, PQhost() can return NULL for a
 | 
				
			||||||
 | 
						 * default Unix-socket connection, so we have to allow NULL for host.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
						if (has_connection_string)
 | 
				
			||||||
 | 
							keep_password = false;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
		keep_password =
 | 
							keep_password =
 | 
				
			||||||
		(o_conn &&
 | 
								(user && PQuser(o_conn) && strcmp(user, PQuser(o_conn)) == 0) &&
 | 
				
			||||||
		 (strcmp(user, PQuser(o_conn)) == 0) &&
 | 
								((host && PQhost(o_conn) && strcmp(host, PQhost(o_conn)) == 0) ||
 | 
				
			||||||
		 (!host || strcmp(host, PQhost(o_conn)) == 0) &&
 | 
								 (host == NULL && PQhost(o_conn) == NULL)) &&
 | 
				
			||||||
		 (strcmp(port, PQport(o_conn)) == 0) &&
 | 
								(port && PQport(o_conn) && strcmp(port, PQport(o_conn)) == 0);
 | 
				
			||||||
		 !has_connection_string);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Grab dbname from old connection unless supplied by caller.  No password
 | 
						 * Grab dbname from old connection unless supplied by caller.  No password
 | 
				
			||||||
@@ -1643,8 +1646,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
 | 
						 * 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
 | 
						 * not, use the password from the old connection, provided the username
 | 
				
			||||||
	 * has not changed. Otherwise, try to connect without a password first,
 | 
						 * etc have not changed. Otherwise, try to connect without a password
 | 
				
			||||||
	 * and then ask for a password if needed.
 | 
						 * first, and then ask for a password if needed.
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * XXX: this behavior leads to spurious connection attempts recorded in
 | 
						 * XXX: this behavior leads to spurious connection attempts recorded in
 | 
				
			||||||
	 * the postmaster's log.  But libpq offers no API that would let us obtain
 | 
						 * the postmaster's log.  But libpq offers no API that would let us obtain
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user