From fcdfb151e2a0dfa36687972dade5978386355d6c Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 20 Oct 2024 12:07:08 +0000 Subject: [PATCH] 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. --- sys/man/9/parsecmd | 8 ++++++++ sys/src/9/port/parse.c | 5 ++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/sys/man/9/parsecmd b/sys/man/9/parsecmd index 84ed5feb2..6affda444 100644 --- a/sys/man/9/parsecmd +++ b/sys/man/9/parsecmd @@ -67,6 +67,14 @@ is allocated by .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 diff --git a/sys/src/9/port/parse.c b/sys/src/9/port/parse.c index 9d59b5672..20a6941ff 100644 --- a/sys/src/9/port/parse.c +++ b/sys/src/9/port/parse.c @@ -36,10 +36,13 @@ ncmdfield(char *p, int n) 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); /* allocate Cmdbuf plus string pointers plus copy of string including \0 */