summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2018-06-11 03:19:42 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2018-06-11 03:19:42 +0200
commit71402b2ea15d0e2bf939b6e095ad56fa14ab2d0a (patch)
treeb851df04c4d1c040aa3fc62ce932f82d90faf99f
parent94f6f89ac1e8731a27c38b54b54348bc063fb6c3 (diff)
downloadplan9front-71402b2ea15d0e2bf939b6e095ad56fa14ab2d0a.tar.xz
devip: fix use after free in ipifcremmulti()
closeconv() calls ipifcremmulti() like: while((mp = cv->multi) != nil) ipifcremmulti(cv, mp->ma, mp->ia); so we have to defer freeing the entry after doing: if((lifc = iplocalonifc(ifc, ia)) != nil) remselfcache(f, ifc, lifc, ma); which accesses the otherwise free'd ia and ma arguments.
-rw-r--r--sys/src/9/ip/ipifc.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/sys/src/9/ip/ipifc.c b/sys/src/9/ip/ipifc.c
index 44bc51cc0..29b82e61a 100644
--- a/sys/src/9/ip/ipifc.c
+++ b/sys/src/9/ip/ipifc.c
@@ -1510,21 +1510,19 @@ ipifcremmulti(Conv *c, uchar *ma, uchar *ia)
return; /* we don't have it open */
*l = multi->next;
- free(multi);
+ multi->next = nil;
f = c->p->f;
if((ifc = findipifc(f, ia, ma, Rmulti)) != nil){
wlock(ifc);
- if(waserror()){
- wunlock(ifc);
- nexterror();
+ if(!waserror()){
+ if((lifc = iplocalonifc(ifc, ia)) != nil)
+ remselfcache(f, ifc, lifc, ma);
+ poperror();
}
- if((lifc = iplocalonifc(ifc, ia)) != nil)
- remselfcache(f, ifc, lifc, ma);
wunlock(ifc);
- poperror();
}
-
+ free(multi);
}
/* register the address on this network for address resolution */