code: plan9front

Download patch

ref: 014b9a62ac919b4f7ada38b8649f6a4a062cd207
parent: 4bc5793a2c0a02ad85b853904603c896c3c77fb5
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Oct 14 13:50:55 EDT 2023

idn: fix crash with long domain names

When a domain name gets long enough, we can end
up passing a remaining length of 0 to seprint.
When seprint has no buffer space at all, it returns
nil, which then crashes our DNS server.

This checks for a nil return from seprint and returns
an error

--- a/sys/src/libc/9sys/idn.c
+++ b/sys/src/libc/9sys/idn.c
@@ -211,7 +211,8 @@
 		if(cistrncmp(cp, "xn--", 4) == 0)
 			if((nr = punydecode(nc-4, cp+4, nelem(rb), rb)) < 0)
 				return -1;
-		dp = seprint(dp, de, "%.*S", nr, rb);
+		if((dp = seprint(dp, de, "%.*S", nr, rb)) == nil)
+			return -1;
 		if(dp >= de)
 			return -1;
 		if(cp[nc] == 0)
@@ -251,10 +252,12 @@
 			rb[nr++] = r;
 			nc += n;
 		}
-		if(nc == nr)
-			dp = seprint(dp, de, "%.*s", nc, cp);
-		else {
-			dp = seprint(dp, de, "xn--");
+		if(nc == nr){
+			if((dp = seprint(dp, de, "%.*s", nc, cp)) == nil)
+				return -1;
+		}else{
+			if((dp = seprint(dp, de, "xn--")) == nil)
+				return -1;
 			if((n = punyencode(nr, rb, de - dp, dp)) < 0)
 				return -1;
 			dp += n;