]> git.lizzy.rs Git - plan9front.git/commitdiff
devip: fix use after free in ipifcremmulti()
authorcinap_lenrek <cinap_lenrek@felloff.net>
Mon, 11 Jun 2018 01:19:42 +0000 (03:19 +0200)
committercinap_lenrek <cinap_lenrek@felloff.net>
Mon, 11 Jun 2018 01:19:42 +0000 (03:19 +0200)
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.

sys/src/9/ip/ipifc.c

index 44bc51cc05072672eae942de7d8eea83c089fcff..29b82e61a003cad8a87164ad2c172512c5bae356 100644 (file)
@@ -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 */