diff options
| -rw-r--r-- | lib/libc/net/getnameinfo.c | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/lib/libc/net/getnameinfo.c b/lib/libc/net/getnameinfo.c index cee07f6e0fe73..9f60ae30910cd 100644 --- a/lib/libc/net/getnameinfo.c +++ b/lib/libc/net/getnameinfo.c @@ -46,6 +46,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include "namespace.h" #include <sys/types.h> #include <sys/socket.h> #include <net/if.h> @@ -53,10 +54,12 @@ __FBSDID("$FreeBSD$"); #include <arpa/inet.h> #include <arpa/nameser.h> #include <netdb.h> +#include <pthread.h> #include <resolv.h> #include <string.h> #include <stddef.h> #include <errno.h> +#include "un-namespace.h" static const struct afd { int a_af; @@ -85,6 +88,19 @@ static int ip6_parsenumeric(const struct sockaddr *, const char *, char *, static int ip6_sa2str(const struct sockaddr_in6 *, char *, size_t, int); #endif +/* + * XXX: Many dependencies are not thread-safe. So, we share lock between + * getaddrinfo() and getipnodeby*(). Still, we cannot use + * getaddrinfo() and getipnodeby*() in conjunction with other + * functions which call them. + */ +#include "libc_private.h" +extern pthread_mutex_t __getaddrinfo_thread_lock; +#define THREAD_LOCK() \ + if (__isthreaded) _pthread_mutex_lock(&__getaddrinfo_thread_lock); +#define THREAD_UNLOCK() \ + if (__isthreaded) _pthread_mutex_unlock(&__getaddrinfo_thread_lock); + int getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) const struct sockaddr *sa; @@ -136,6 +152,7 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) * servlen == 0 means that the caller does not want the result. */ } else { + THREAD_LOCK(); if (flags & NI_NUMERICSERV) sp = NULL; else { @@ -143,15 +160,20 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) (flags & NI_DGRAM) ? "udp" : "tcp"); } if (sp) { - if (strlen(sp->s_name) + 1 > servlen) + if (strlen(sp->s_name) + 1 > servlen) { + THREAD_UNLOCK(); return EAI_MEMORY; + } strlcpy(serv, sp->s_name, servlen); } else { snprintf(numserv, sizeof(numserv), "%u", ntohs(port)); - if (strlen(numserv) + 1 > servlen) + if (strlen(numserv) + 1 > servlen) { + THREAD_UNLOCK(); return EAI_MEMORY; + } strlcpy(serv, numserv, servlen); } + THREAD_UNLOCK(); } switch (sa->sa_family) { |
