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