8000 Produce a more useful error message for over-length Unix socket paths. · home201448/postgres@9837be9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9837be9

Browse files
committed
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.
1 parent 5c8c7c7 commit 9837be9

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

src/backend/libpq/pqcomm.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,14 @@ static int
476476
Lock_AF_UNIX(unsigned short portNumber, char *unixSocketName)
477477
{
478478
UNIXSOCK_PATH(sock_path, portNumber, unixSocketName);
479+
if (strlen(sock_path) >= UNIXSOCK_PATH_BUFLEN)
480+
{
481+
ereport(LOG,
482+
(errmsg("Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
483+
sock_path,
484+
(int) (UNIXSOCK_PATH_BUFLEN - 1))));
485+
return STATUS_ERROR;
486+
}
479487

480488
/*
481489
* Grab an interlock file associated with the socket file.

src/include/libpq/pqcomm.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,19 @@ typedef struct
7373
DEFAULT_PGSOCKET_DIR, \
7474
(port))
7575

76+
/*
77+
* The maximum workable length of a socket path is what will fit into
78+
* struct sockaddr_un. This is usually only 100 or so bytes :-(.
79+
*
80+
* For consistency, always pass a MAXPGPATH-sized buffer to UNIXSOCK_PATH(),
81+
* then complain if the resulting string is >= UNIXSOCK_PATH_BUFLEN bytes.
82+
* (Because the standard API for getaddrinfo doesn't allow it to complain in
83+
* a useful way when the socket pathname is too long, we have to test for
84+
* this explicitly, instead of just letting the subroutine return an error.)
85+
*/
86+
#define UNIXSOCK_PATH_BUFLEN sizeof(((struct sockaddr_un *) NULL)->sun_path)
87+
88+
7689
/*
7790
* These manipulate the frontend/backend protocol version number.
7891
*

src/interfaces/libpq/fe-connect.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ static int
765765
connectDBStart(PGconn *conn)
766766
{
767767
int portnum;
768-
char portstr[128];
768+
char portstr[MAXPGPATH];
769769
struct addrinfo *addrs = NULL;
770770
struct addrinfo hint;
771771
const char *node;
@@ -817,6 +817,15 @@ connectDBStart(PGconn *conn)
817817
node = NULL;
818818
hint.ai_family = AF_UNIX;
819819
UNIXSOCK_PATH(portstr, portnum, conn->pgunixsocket);
820+
if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
821+
{
822+
appendPQExpBuffer(&conn->errorMessage,
823+
libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
824+
portstr,
825+
(int) (UNIXSOCK_PATH_BUFLEN - 1));
826+
conn->options_valid = false;
827+
goto connect_errReturn;
828+
}
820829
#else
821830
/* Without Unix sockets, default to localhost instead */
822831
node = "localhost";

0 commit comments

Comments
 (0)
0