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 */