]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3227. [bug] Interim fix to make WKS's use of getprotobyname()
authorMark Andrews <marka@isc.org>
Wed, 30 Nov 2011 01:18:11 +0000 (01:18 +0000)
committerMark Andrews <marka@isc.org>
Wed, 30 Nov 2011 01:18:11 +0000 (01:18 +0000)
                        and getservbyname() self thread safe. [RT #26232]

CHANGES
lib/dns/rdata/in_1/wks_11.c

diff --git a/CHANGES b/CHANGES
index 9c74fa47de07e554ce622b6cf7dc11d014fdf47d..c1d54391584f1b5ce48cb224f48c74a30e1daa3b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3227.  [bug]           Interim fix to make WKS's use of getprotobyname()
+                       and getservbyname() self thread safe. [RT #26232]
+
 3226.  [bug]           Address minor resource leakages. [RT #26624]
 
 3225.  [bug]           Silence spurious "setsockopt(517, IPV6_V6ONLY) failed"
index 23914295947777012357803f123c70981b750d61..d539cf70c7795dc82d4a7ac23e877c44ab0bc328 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: wks_11.c,v 1.57 2009/12/04 21:09:34 marka Exp $ */
+/* $Id: wks_11.c,v 1.58 2011/11/30 01:18:11 marka Exp $ */
 
 /* Reviewed: Fri Mar 17 15:01:49 PST 2000 by explorer */
 
 
 #include <isc/net.h>
 #include <isc/netdb.h>
+#include <isc/once.h>
 
 #define RRTYPE_WKS_ATTRIBUTES (0)
 
+static isc_mutex_t wks_lock;
+
+static void init_lock(void) {
+        RUNTIME_CHECK(isc_mutex_init(&wks_lock) == ISC_R_SUCCESS);
+}
+
+static isc_boolean_t
+mygetprotobyname(const char *name, long *proto) {
+       struct protoent *pe;
+
+       LOCK(&wks_lock);
+       pe = getprotobyname(name);
+       if (pe != NULL)
+               *proto = pe->p_proto;
+       UNLOCK(&wks_lock);
+       return (ISC_TF(pe != NULL));
+}
+
+static isc_boolean_t
+mygetservbyname(const char *name, const char *proto, long *port) {
+       struct servent *se;
+
+       LOCK(&wks_lock);
+       se = getservbyname(name, proto);
+       if (se != NULL)
+               *port = ntohs(se->s_port);
+       UNLOCK(&wks_lock);
+       return (ISC_TF(se != NULL));
+}
+
 static inline isc_result_t
 fromtext_in_wks(ARGS_FROMTEXT) {
+       static isc_once_t once = ISC_ONCE_INIT;
        isc_token_t token;
        isc_region_t region;
        struct in_addr addr;
-       struct protoent *pe;
-       struct servent *se;
        char *e;
        long proto;
        unsigned char bm[8*1024]; /* 64k bits */
@@ -55,6 +85,8 @@ fromtext_in_wks(ARGS_FROMTEXT) {
        UNUSED(options);
        UNUSED(rdclass);
 
+       RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
+
        /*
         * IPv4 dotted quad.
         */
@@ -78,10 +110,9 @@ fromtext_in_wks(ARGS_FROMTEXT) {
        proto = strtol(DNS_AS_STR(token), &e, 10);
        if (*e == 0)
                ;
-       else if ((pe = getprotobyname(DNS_AS_STR(token))) != NULL)
-               proto = pe->p_proto;
-       else
+       else if (!mygetprotobyname(DNS_AS_STR(token), &proto))
                RETTOK(DNS_R_UNKNOWNPROTO);
+
        if (proto < 0 || proto > 0xff)
                RETTOK(ISC_R_RANGE);
 
@@ -112,12 +143,8 @@ fromtext_in_wks(ARGS_FROMTEXT) {
                port = strtol(DNS_AS_STR(token), &e, 10);
                if (*e == 0)
                        ;
-               else if ((se = getservbyname(service, ps)) != NULL)
-                       port = ntohs(se->s_port);
-               else if ((se = getservbyname(DNS_AS_STR(token), ps))
-                         != NULL)
-                       port = ntohs(se->s_port);
-               else
+               else if (!mygetservbyname(service, ps, &port) &&
+                        !mygetservbyname(DNS_AS_STR(token), ps, &port))
                        RETTOK(DNS_R_UNKNOWNSERVICE);
                if (port < 0 || port > 0xffff)
                        RETTOK(ISC_R_RANGE);