It can be triggered if nsd was compiled with --enable-zone-stats.

http://www.nlnetlabs.nl/downloads/CVE-2012-2979.txt

OpenBSD patch:

Index: query.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/query.c,v
retrieving revision 1.6
diff -u -p -r1.6 query.c
--- query.c     19 Jul 2012 17:46:11 -0000      1.6
+++ query.c     28 Jul 2012 16:02:54 -0000
@@ -1209,9 +1209,11 @@ answer_query(struct nsd *nsd, struct que
        answer_lookup_zone(nsd, q, &answer, 0, exact, closest_match,
                closest_encloser, q->qname);
 
-       ZTATUP2(q->zone, opcode, q->opcode);
-       ZTATUP2(q->zone, qtype, q->qtype);
-       ZTATUP2(q->zone, opcode, q->qclass);
+        if (q->zone) {
+               ZTATUP2(q->zone, opcode, q->opcode);
+               ZTATUP2(q->zone, qtype, q->qtype);
+               ZTATUP2(q->zone, opcode, q->qclass);
+       }
 
        offset = 
dname_label_offsets(q->qname)[domain_dname(closest_encloser)->label_count - 1] 
+ QHEADERSZ;
        query_add_compression_domain(q, closest_encloser, offset);
@@ -1403,7 +1405,9 @@ query_add_optional(query_type *q, nsd_ty
                }
                ARCOUNT_SET(q->packet, ARCOUNT(q->packet) + 1);
                STATUP(nsd, edns);
-               ZTATUP(q->zone, edns);
+               if (q->zone) {
+                       ZTATUP(q->zone, edns);
+               }
                break;
        case EDNS_ERROR:
                if (q->edns.dnssec_ok)  edns->error[7] = 0x80;
@@ -1412,7 +1416,9 @@ query_add_optional(query_type *q, nsd_ty
                buffer_write(q->packet, edns->rdata_none, OPT_RDATA);
                ARCOUNT_SET(q->packet, ARCOUNT(q->packet) + 1);
                STATUP(nsd, ednserr);
-               ZTATUP(q->zone, ednserr);
+               if (q->zone) {
+                       ZTATUP(q->zone, ednserr);
+               }
                break;
        }
 
Index: server.c
===================================================================
RCS file: /cvs/src/usr.sbin/nsd/server.c,v
retrieving revision 1.5
diff -u -p -r1.5 server.c
--- server.c    9 Jul 2012 21:56:41 -0000       1.5
+++ server.c    28 Jul 2012 16:02:55 -0000
@@ -1417,15 +1417,20 @@ handle_udp(netio_type *ATTR_UNUSED(netio
 #ifdef BIND8_STATS
                        if (RCODE(q->packet) == RCODE_OK && !AA(q->packet)) {
                                STATUP(data->nsd, nona);
-                               ZTATUP(q->zone, nona);
+# ifdef USE_ZONE_STATS
+                               if (q->zone)
+                                       ZTATUP(q->zone, nona);
+# endif
                        }
 
 # ifdef USE_ZONE_STATS
+                       if (q->zone) {
                        if (data->socket->addr->ai_family == AF_INET) {
                                ZTATUP(q->zone, qudp);
                        } else if (data->socket->addr->ai_family == AF_INET6) {
                                ZTATUP(q->zone, qudp6);
                        }
+                       }
 # endif
 #endif
 
@@ -1443,17 +1448,27 @@ handle_udp(netio_type *ATTR_UNUSED(netio
                        if (sent == -1) {
                                log_msg(LOG_ERR, "sendto failed: %s", 
strerror(errno));
                                STATUP(data->nsd, txerr);
-                               ZTATUP(q->zone, txerr);
+
+#ifdef USE_ZONE_STATS
+                               if (q->zone)
+                                       ZTATUP(q->zone, txerr);
+#endif
                        } else if ((size_t) sent != 
buffer_remaining(q->packet)) {
                                log_msg(LOG_ERR, "sent %d in place of %d 
bytes", sent, (int) buffer_remaining(q->packet));
 #ifdef BIND8_STATS
                        } else {
                                /* Account the rcode & TC... */
                                STATUP2(data->nsd, rcode, RCODE(q->packet));
-                               ZTATUP2(q->zone, rcode, RCODE(q->packet));
+# ifdef USE_ZONE_STATS
+                               if (q->zone)
+                                       ZTATUP2(q->zone, rcode, 
RCODE(q->packet));
+# endif
                                if (TC(q->packet)) {
                                        STATUP(data->nsd, truncated);
-                                       ZTATUP(q->zone, truncated);
+# ifdef USE_ZONE_STATS
+                                       if (q->zone)
+                                               ZTATUP(q->zone, truncated);
+# endif
                                }
 #endif /* BIND8_STATS */
                        }
@@ -1665,12 +1680,16 @@ handle_tcp_reading(netio_type *netio,
            && !AA(data->query->packet))
        {
                STATUP(data->nsd, nona);
-               ZTATUP(data->query->zone, nona);
+# ifdef USE_ZONE_STATS
+               if (data->query->zone)
+                       ZTATUP(data->query->zone, nona);
+# endif
        }
 
 # ifdef USE_ZONE_STATS
+       if (data->query->zone) {
 #  ifndef INET6
-       ZTATUP(data->query->zone, ctcp);
+               ZTATUP(data->query->zone, ctcp);
 #  else
        if (data->query->addr.ss_family == AF_INET) {
                ZTATUP(data->query->zone, ctcp);
@@ -1678,6 +1697,7 @@ handle_tcp_reading(netio_type *netio,
                ZTATUP(data->query->zone, ctcp6);
        }
 #  endif
+       }
 # endif /* USE_ZONE_STATS */
 
 #endif /* BIND8_STATS */

Reply via email to