Skip to content

Commit 65f4384

Browse files
committed
Fix gai_strerror() thread-safety on Windows.
Commit 5579388 removed code that supplied a fallback implementation of getaddrinfo(), which was dead code on modern systems. One tiny piece of the removed code was still doing something useful on Windows, though: that OS's own gai_strerror()/gai_strerrorA() function returns a pointer to a static buffer that it overwrites each time, so it's not thread-safe. In rare circumstances, a multi-threaded client program could get an incorrect or corrupted error message. Restore the replacement gai_strerror() function, though now that it's only for Windows we can put it into a win32-specific file and cut it down to the errors that Windows documents. The error messages here are taken from FreeBSD, because Windows' own messages seemed too verbose. Back-patch to 16. Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Discussion: https://postgr.es/m/CA%2BhUKGKz%2BF9d2PTiXwfYV7qJw%2BWg2jzACgSDgPizUw7UG%3Di58A%40mail.gmail.com
1 parent e70abd6 commit 65f4384

File tree

5 files changed

+61
-0
lines changed

5 files changed

+61
-0
lines changed

configure

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16388,6 +16388,12 @@ esac
1638816388
;;
1638916389
esac
1639016390

16391+
case " $LIBOBJS " in
16392+
*" win32gai_strerror.$ac_objext "* ) ;;
16393+
*) LIBOBJS="$LIBOBJS win32gai_strerror.$ac_objext"
16394+
;;
16395+
esac
16396+
1639116397
case " $LIBOBJS " in
1639216398
*" win32getrusage.$ac_objext "* ) ;;
1639316399
*) LIBOBJS="$LIBOBJS win32getrusage.$ac_objext"

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1885,6 +1885,7 @@ if test "$PORTNAME" = "win32"; then
18851885
AC_LIBOBJ(win32env)
18861886
AC_LIBOBJ(win32error)
18871887
AC_LIBOBJ(win32fdatasync)
1888+
AC_LIBOBJ(win32gai_strerror)
18881889
AC_LIBOBJ(win32getrusage)
18891890
AC_LIBOBJ(win32link)
18901891
AC_LIBOBJ(win32ntdll)

src/include/port/win32/sys/socket.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,12 @@
2323
#define ERROR PGERROR
2424
#endif
2525

26+
/*
27+
* We don't use the Windows gai_strerror[A] function because it is not
28+
* thread-safe. We define our own in src/port/win32gai_strerror.c.
29+
*/
30+
#undef gai_strerror
31+
32+
extern const char *gai_strerror(int ecode);
33+
2634
#endif /* WIN32_SYS_SOCKET_H */

src/port/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ if host_system == 'windows'
3535
'win32error.c',
3636
'win32fdatasync.c',
3737
'win32fseek.c',
38+
'win32gai_strerror.c',
3839
'win32getrusage.c',
3940
'win32link.c',
4041
'win32ntdll.c',

src/port/win32gai_strerror.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* win32gai_strerror.c
4+
* Thread-safe gai_strerror() for Windows.
5+
*
6+
* Portions Copyright (c) 2024, PostgreSQL Global Development Group
7+
*
8+
* IDENTIFICATION
9+
* src/port/win32gai_strerror.c
10+
*
11+
*-------------------------------------------------------------------------
12+
*/
13+
14+
#include <sys/socket.h>
15+
16+
/*
17+
* Windows has gai_strerrorA(), but it is not thread-safe so we avoid it.
18+
*
19+
* https://learn.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-gai_strerrora
20+
*/
21+
const char *
22+
gai_strerror(int errcode)
23+
{
24+
switch (errcode)
25+
{
26+
case EAI_AGAIN:
27+
return "Temporary failure in name resolution";
28+
case EAI_BADFLAGS:
29+
return "Bad value for ai_flags";
30+
case EAI_FAIL:
31+
return "Non-recoverable failure in name resolution";
32+
case EAI_FAMILY:
33+
return "ai_family not supported";
34+
case EAI_MEMORY:
35+
return "Memory allocation failure";
36+
case EAI_NONAME:
37+
return "Name or service not known";
38+
case EAI_SERVICE:
39+
return "Servname not supported for ai_socktype";
40+
case EAI_SOCKTYPE:
41+
return "ai_socktype not supported";
42+
default:
43+
return "Unknown server error";
44+
}
45+
}

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