summaryrefslogtreecommitdiff
path: root/sys/src/9/ip
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2018-04-22 18:42:22 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2018-04-22 18:42:22 +0200
commit575398eb9bc2c6f1bcfce7bf8fffbce73a96e8da (patch)
treed1b6a38fabde37b8c4b31d6d31c8cd608ac435e3 /sys/src/9/ip
parent638b4a1ec113adebdd6a85d647574a46e0b7feab (diff)
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.
Diffstat (limited to 'sys/src/9/ip')
-rw-r--r--sys/src/9/ip/iproute.c36
1 files changed, 27 insertions, 9 deletions
diff --git a/sys/src/9/ip/iproute.c b/sys/src/9/ip/iproute.c
index ef59b2f5f..0681b2464 100644
--- a/sys/src/9/ip/iproute.c
+++ b/sys/src/9/ip/iproute.c
@@ -22,6 +22,7 @@ freeroute(Route *r)
{
Route **l;
+ r->ref = 0;
r->left = nil;
r->right = nil;
if(r->type & Rv4)
@@ -541,8 +542,13 @@ v4lookup(Fs *f, uchar *a, uchar *s, Routehint *rh)
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 @@ v4lookup(Fs *f, uchar *a, uchar *s, Routehint *rh)
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 @@ v6lookup(Fs *f, uchar *a, uchar *s, Routehint *rh)
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 @@ v6lookup(Fs *f, uchar *a, uchar *s, Routehint *rh)
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]);