wait, Maxdest is a count, see: dest = emalloc(Maxdest * sizeof *dest); /* dest can't be on stack */
code like: Dest *curdest; /* pointer to next to fill */ p = dp->dest; ... if (qp->ndest > qp->curdest - p) { and for(p = qp->dest; p < qp->curdest; p++) indicates that dp->curdest is an end pointer. so it should be perfectly valid for it to point at &dp->dest[Maxdest]. the check at the top of serveraddrs() should really be: if(nd >= Maxdest) /* dest array is full? */ return Maxdest; serveraddr() really returns a count. which is the same as an end pointer index. the result check of that serveraddr() call should really be: if (j < 0 || j > Maxdest) { dnslog("serveraddrs() result %d out of range", j); abort(); } qp->curdest = &qp->dest[j]; and the destck(dp->curdest); should be removed. --- a/sys/src/cmd/ndb/dnresolve.c Wed Aug 22 00:11:42 2012 +0200 +++ b/sys/src/cmd/ndb/dnresolve.c Wed Aug 22 12:28:34 2012 +0200 @@ -832,7 +832,7 @@ Dest *cur; if(nd >= Maxdest) /* dest array is full? */ - return Maxdest - 1; + return Maxdest; /* * look for a server whose address we already know. @@ -1080,13 +1080,12 @@ */ if (qp->ndest > qp->curdest - p) { j = serveraddrs(qp, qp->curdest - p, depth); - if (j < 0 || j >= Maxdest) { + if (j < 0 || j > Maxdest) { dnslog("serveraddrs() result %d out of range", j); abort(); } qp->curdest = &qp->dest[j]; } - destck(qp->curdest); /* no servers, punt */ if (qp->ndest == 0) -- cinap