Fix ipv6 icmp bugs in locking and freeing in icmphostunr() per current Plan 9.
authorGeoff Collyer <geoffc@google.com>
Tue, 12 Jan 2016 01:05:19 +0000 (17:05 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 14 Jan 2016 19:46:55 +0000 (14:46 -0500)
Signed-off-by: Geoff Collyer <geoff@collyer.net>
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/net/icmp6.c

index fd316de..4bc2ed3 100644 (file)
@@ -500,7 +500,7 @@ icmphostunr(struct Fs *f, struct Ipifc *ifc,
        p = (struct ip6hdr *)bp->rp;
 
        if (isv6mcast(p->src))
-               goto clean;
+               goto freebl;
 
        nbp = newIPICMP(sz);
        np = (struct IPICMP *)nbp->rp;
@@ -510,11 +510,9 @@ icmphostunr(struct Fs *f, struct Ipifc *ifc,
                netlog(f, Logicmp, "send icmphostunr -> s%I d%I\n", p->src, p->dst);
        } else {
                netlog(f, Logicmp, "icmphostunr fail -> s%I d%I\n", p->src, p->dst);
+               runlock(&ifc->rwlock);
                freeblist(nbp);
-               if (free)
-                       goto clean;
-               else
-                       return;
+               goto freebl;
        }
 
        memmove(np->dst, p->src, IPaddrlen);
@@ -529,14 +527,12 @@ icmphostunr(struct Fs *f, struct Ipifc *ifc,
 
        if (free)
                ipiput6(f, ifc, nbp);
-       else {
+       else
                ipoput6(f, nbp, 0, MAXTTL, DFLTTOS, NULL);
-               return;
-       }
-
-clean:
        runlock(&ifc->rwlock);
-       freeblist(bp);
+freebl:
+       if (free)
+               freeblist(bp);
 }
 
 extern void icmpttlexceeded6(struct Fs *f, struct Ipifc *ifc, struct block *bp)