git: 9front

Download patch

ref: 92488893530cedc6bacc04ecc07045c1464a96f1
parent: 5f89083773b59db9d83f1207c18e805fba69233e
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jun 10 23:19:42 EDT 2018

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.

--- a/sys/src/9/ip/ipifc.c
+++ b/sys/src/9/ip/ipifc.c
@@ -1510,21 +1510,19 @@
 		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 */
--