git: 9front

Download patch

ref: 913cf047adb28f0d9484cdf3bea246f2589d5002
parent: b37b35e087440c941104629cdceb2d5b239cff42
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Oct 20 08:07:08 EDT 2024

kernel: Limit parsecmd() to a maximum of READSTR bytes

A user can create a large demand paged segment
and then do write to a ctl file with a very large buffer
driving the kernel into an out-of-memory condition.

For all practcal purposes, limit the input buffer size
to something reasonable. READSTR is 8000 bytes, which
would be enougth for even the largest ctl messages.

--- a/sys/man/9/parsecmd
+++ b/sys/man/9/parsecmd
@@ -67,6 +67,14 @@
 .IR malloc (9)),
 and the caller is responsible for freeing it using
 .IR free .
+To prevent denial of service to the kernel,
+.I parsecmd
+will error out if
+.I n
+exceeds
+.B READSTR
+bytes.
+.PP
 .I Cmderror
 prepends the given format with the original command,
 then calls
--- a/sys/src/9/port/parse.c
+++ b/sys/src/9/port/parse.c
@@ -36,9 +36,12 @@
 Cmdbuf*
 parsecmd(char *p, int n)
 {
-	Cmdbuf *volatile cb;
+	Cmdbuf *cb;
 	int nf;
 	char *sp;
+
+	if(up!=nil && (uint)n > READSTR)
+		error("control message too big");
 
 	nf = ncmdfield(p, n);
 
--