Skip to content

Commit 4af446e

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 d3fe599 commit 4af446e

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
@@ -308,6 +308,14 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
308308
* that file path
309309
*/
310310
UNIXSOCK_PATH(unixSocketPath, portNumber, unixSocketDir);
311+
if (strlen(unixSocketPath) >= UNIXSOCK_PATH_BUFLEN)
312+
{
313+
ereport(LOG,
314+
(errmsg("Unix-domain socket path \"%s\" is too long (maximum %d bytes)",
315+
unixSocketPath,
316+
(int) (UNIXSOCK_PATH_BUFLEN - 1))));
317+
return STATUS_ERROR;
318+
}
311319
if (Lock_AF_UNIX(unixSocketDir, unixSocketPath) != STATUS_OK)
312320
return STATUS_ERROR;
313321
service = unixSocketPath;

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
@@ -1322,7 +1322,7 @@ static int
13221322
connectDBStart(PGconn *conn)
13231323
{
13241324
int portnum;
1325-
char portstr[128];
1325+
char portstr[MAXPGPATH];
13261326
struct addrinfo *addrs = NULL;
13271327
struct addrinfo hint;
13281328
const char *node;
@@ -1384,6 +1384,15 @@ connectDBStart(PGconn *conn)
13841384
node = NULL;
13851385
hint.ai_family = AF_UNIX;
13861386
UNIXSOCK_PATH(portstr, portnum, conn->pgunixsocket);
1387+
if (strlen(portstr) >= UNIXSOCK_PATH_BUFLEN)
1388+
{
1389+
appendPQExpBuffer(&conn->errorMessage,
1390+
libpq_gettext("Unix-domain socket path \"%s\" is too long (maximum %d bytes)\n"),
1391+
portstr,
1392+
(int) (UNIXSOCK_PATH_BUFLEN - 1));
1393+
conn->options_valid = false;
1394+
goto connect_errReturn;
1395+
}
13871396
#else
13881397
/* Without Unix sockets, default to localhost instead */
13891398
node = DefaultHost;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy