git: 9front

Download patch

ref: 1246287cd4b1898467274ebd6faf7ed652c81825
parent: 0efc80f4dd0c16942b4efaeed966c93993383aeb
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri May 19 19:42:54 EDT 2023

devip: don't leak temporary buffers on error

when reading the status files from a conversation, ipread()
allocates a temporary buffer and calls the protocols
generator to fill the buffer and the calls
readstr() to handle the read request.

if the generator or readstr() erors, we must free the
temporary buffer.

also, allocate a more reasonable size for the "local"
and "remote" strings. allocating and zeroing 32K big
buffers for them is excessive.

--- a/sys/src/9/ip/devip.c
+++ b/sys/src/9/ip/devip.c
@@ -610,7 +610,9 @@
 
 enum
 {
-	Statelen=	32*1024,
+	Maxstring=	128,
+	Maxstate=	32*1024,
+	Maxstats=	32*1024,
 };
 
 static long
@@ -647,42 +649,54 @@
 		return netlogread(f, a, offset, n);
 	case Qctl:
 		buf = smalloc(16);
+		if(waserror()){
+			free(buf);
+			nexterror();
+		}
 		snprint(buf, 16, "%lud", CONV(ch->qid));
+	Readstr:
 		rv = readstr(offset, p, n, buf);
 		free(buf);
+		poperror();
 		return rv;
 	case Qremote:
-		buf = smalloc(Statelen);
+		buf = smalloc(Maxstring);
+		if(waserror()){
+			free(buf);
+			nexterror();
+		}
 		x = f->p[PROTO(ch->qid)];
 		c = x->conv[CONV(ch->qid)];
 		if(x->remote == nil) {
-			snprint(buf, Statelen, "%I!%d\n", c->raddr, c->rport);
+			snprint(buf, Maxstring, "%I!%d\n", c->raddr, c->rport);
 		} else {
-			(*x->remote)(c, buf, Statelen-2);
+			(*x->remote)(c, buf, Maxstring);
 		}
-		rv = readstr(offset, p, n, buf);
-		free(buf);
-		return rv;
+		goto Readstr;
 	case Qlocal:
-		buf = smalloc(Statelen);
+		buf = smalloc(Maxstring);
+		if(waserror()){
+			free(buf);
+			nexterror();
+		}
 		x = f->p[PROTO(ch->qid)];
 		c = x->conv[CONV(ch->qid)];
 		if(x->local == nil) {
-			snprint(buf, Statelen, "%I!%d\n", c->laddr, c->lport);
+			snprint(buf, Maxstring, "%I!%d\n", c->laddr, c->lport);
 		} else {
-			(*x->local)(c, buf, Statelen-2);
+			(*x->local)(c, buf, Maxstring);
 		}
-		rv = readstr(offset, p, n, buf);
-		free(buf);
-		return rv;
+		goto Readstr;
 	case Qstatus:
-		buf = smalloc(Statelen);
+		buf = smalloc(Maxstate);
+		if(waserror()){
+			free(buf);
+			nexterror();
+		}
 		x = f->p[PROTO(ch->qid)];
 		c = x->conv[CONV(ch->qid)];
-		(*x->state)(c, buf, Statelen-2);
-		rv = readstr(offset, p, n, buf);
-		free(buf);
-		return rv;
+		(*x->state)(c, buf, Maxstate);
+		goto Readstr;
 	case Qdata:
 		c = f->p[PROTO(ch->qid)]->conv[CONV(ch->qid)];
 		return qread(c->rq, a, n);
@@ -696,11 +710,13 @@
 		x = f->p[PROTO(ch->qid)];
 		if(x->stats == nil)
 			error("stats not implemented");
-		buf = smalloc(Statelen);
-		(*x->stats)(x, buf, Statelen);
-		rv = readstr(offset, p, n, buf);
-		free(buf);
-		return rv;
+		buf = smalloc(Maxstats);
+		if(waserror()){
+			free(buf);
+			nexterror();
+		}
+		(*x->stats)(x, buf, Maxstats);
+		goto Readstr;
 	}
 }
 
--