Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)