ref: 6a1f4122194c4717bafb329aa588f3292ea3102d
parent: a249149cfaaa9a70b3f423fc7269262e17a08a9d
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Apr 22 14:42:22 EDT 2018
devip: verify ifcid on routehint check, check Route.ref for free'd routes v4lookup() and v6lookup() do not acquire the routelock, so it is possible to hit routes that are on the freelist. to detect these, we set ref to 0 and check for this case, avoiding overriding the ifc. re-evaluate routes when the ifcid on the route hint doesnt match.
--- a/sys/src/9/ip/iproute.c
+++ b/sys/src/9/ip/iproute.c
@@ -22,6 +22,7 @@
{Route **l;
+ r->ref = 0;
r->left = nil;
r->right = nil;
if(r->type & Rv4)
@@ -541,8 +542,13 @@
Route *p, *q;
Ipifc *ifc;
- if(rh != nil && rh->r != nil && rh->r->ifc != nil && rh->rgen == v4routegeneration)
- return rh->r;
+ if(rh != nil
+ && rh->rgen == v4routegeneration
+ && (q = rh->r) != nil
+ && (ifc = q->ifc) != nil
+ && q->ifcid == ifc->ifcid
+ && q->ref > 0)
+ return q;
la = nhgetl(a);
ls = nhgetl(s);
@@ -570,7 +576,10 @@
p = p->mid;
}
- if(q != nil && (q->ifc == nil || q->ifcid != q->ifc->ifcid)){+ if(q == nil || q->ref == 0)
+ return nil;
+
+ if(q->ifc == nil || q->ifcid != q->ifc->ifcid){ if(q->type & Rifc) {hnputl(gate+IPv4off, q->v4.address);
memmove(gate, v4prefix, IPv4off);
@@ -602,13 +611,19 @@
Ipifc *ifc;
int h;
- if(isv4(a) && isv4(s))
- return v4lookup(f, a+IPv4off, s+IPv4off, rh);
- if(isv4(s))
+ if(isv4(s)){+ if(isv4(a))
+ return v4lookup(f, a+IPv4off, s+IPv4off, rh);
return nil;
+ }
- if(rh != nil && rh->r != nil && rh->r->ifc != nil && rh->rgen == v6routegeneration)
- return rh->r;
+ if(rh != nil
+ && rh->rgen == v6routegeneration
+ && (q = rh->r) != nil
+ && (ifc = q->ifc) != nil
+ && q->ifcid == ifc->ifcid
+ && q->ref > 0)
+ return q;
for(h = 0; h < IPllen; h++){la[h] = nhgetl(a+4*h);
@@ -668,7 +683,10 @@
next: ;
}
- if(q != nil && (q->ifc == nil || q->ifcid != q->ifc->ifcid)){+ if(q == nil || q->ref == 0)
+ return nil;
+
+ if(q->ifc == nil || q->ifcid != q->ifc->ifcid){ if(q->type & Rifc) {for(h = 0; h < IPllen; h++)
hnputl(gate+4*h, q->v6.address[h]);
--
⑨