diff options
| author | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-06-11 03:19:42 +0200 |
|---|---|---|
| committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2018-06-11 03:19:42 +0200 |
| commit | 71402b2ea15d0e2bf939b6e095ad56fa14ab2d0a (patch) | |
| tree | b851df04c4d1c040aa3fc62ce932f82d90faf99f | |
| parent | 94f6f89ac1e8731a27c38b54b54348bc063fb6c3 (diff) | |
| download | plan9front-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.c | 14 |
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 */ |
