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

Reply via email to