mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
Produce a more useful error message for over-length Unix socket paths.
The length of a socket path name is constrained by the size of struct sockaddr_un, and there's not a lot we can do about it since that is a kernel API. However, it would be a good thing if we produced an intelligible error message when the user specifies a socket path that's too long --- and getaddrinfo's standard API is too impoverished to do this in the natural way. So insert explicit tests at the places where we construct a socket path name. Now you'll get an error that makes sense and even tells you what the limit is, rather than something generic like "Non-recoverable failure in name resolution". Per trouble report from Jeremy Drake and a fix idea from Andrew Dunstan.
This commit is contained in:
parent
edfc84b878
commit
a8e60f0b23
@ -493,6 +493,14 @@ static int
|
|||||||
Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
|
Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
|
||||||
{
|
{
|
||||||
UNIXSOCK_PATH(sock_path, portNumber, unixSocketName);
|
UNIXSOCK_PATH(sock_path, portNumber, unixSocketName);
|
||||||
|
if (strlen(sock_path) >= UNIXSOCK_PATH_BUFLEN)
|
||||||
|
{
|
||||||
|
ereport(LOG,
|
||||||
|
(errmsg("Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
|
||||||
|
sock_path,
|
||||||
|
(int) (UNIXSOCK_PATH_BUFLEN - 1))));
|
||||||
|
return STATUS_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Grab an interlock file associated with the socket file.
|
* Grab an interlock file associated with the socket file.
|
||||||
|
@ -73,6 +73,19 @@ typedef struct
|
|||||||
DEFAULT_PGSOCKET_DIR, \
|
DEFAULT_PGSOCKET_DIR, \
|
||||||
(port))
|
(port))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The maximum workable length of a socket path is what will fit into
|
||||||
|
* struct sockaddr_un. This is usually only 100 or so bytes :-(.
|
||||||
|
*
|
||||||
|
* For consistency, always pass a MAXPGPATH-sized buffer to UNIXSOCK_PATH(),
|
||||||
|
* then complain if the resulting string is >= UNIXSOCK_PATH_BUFLEN bytes.
|
||||||
|
* (Because the standard API for getaddrinfo doesn't allow it to complain in
|
||||||
|
* a useful way when the socket pathname is too long, we have to test for
|
||||||
|
* this explicitly, instead of just letting the subroutine return an error.)
|
||||||
|
*/
|
||||||
|
#define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These manipulate the frontend/backend protocol version number.
|
* These manipulate the frontend/backend protocol version number.
|
||||||
*
|
*
|
||||||
|
@ -1300,7 +1300,7 @@ static int
|
|||||||
connectDBStart(PGconn *conn)
|
connectDBStart(PGconn *conn)
|
||||||
{
|
{
|
||||||
int portnum;
|
int portnum;
|
||||||
char portstr[128];
|
char portstr[MAXPGPATH];
|
||||||
struct addrinfo *addrs = NULL;
|
struct addrinfo *addrs = NULL;
|
||||||
struct addrinfo hint;
|
struct addrinfo hint;
|
||||||
const char *node;
|
const char *node;
|
||||||
@ -1362,6 +1362,15 @@ connectDBStart(PGconn *conn)
|
|||||||
node = NULL;
|
node = NULL;
|
||||||
hint.ai_family = AF_UNIX;
|
hint.ai_family = AF_UNIX;
|
||||||
UNIXSOCK_PATH(portstr, portnum, conn->pgunixsocket);
|
UNIXSOCK_PATH(portstr, portnum, conn->pgunixsocket);
|
||||||
|
if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
|
||||||
|
{
|
||||||
|
appendPQExpBuffer(&conn->errorMessage,
|
||||||
|
libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
|
||||||
|
portstr,
|
||||||
|
(int) (UNIXSOCK_PATH_BUFLEN - 1));
|
||||||
|
conn->options_valid = false;
|
||||||
|
goto connect_errReturn;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/* Without Unix sockets, default to localhost instead */
|
/* Without Unix sockets, default to localhost instead */
|
||||||
node = DefaultHost;
|
node = DefaultHost;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user