From fbb85f9b2f1aaa68407590a94ce046fa0c2271ad Mon Sep 17 00:00:00 2001 From: Ben Wiederhake Date: Mon, 15 Feb 2021 21:06:18 +0100 Subject: [PATCH] Kernel: Refuse excessively long iovec list, also in readv This bug is a good example why copy-paste code should eventually be eliminated from the code base: Apparently the code was copied from read.cpp before c6027ed7cce901dc0d2b6f68002a911178ae587f, so the same bug got introduced here. To recap: A malicious program can ask the Kernel to prepare sys-ing to a huge amount of iovecs. The Kernel must first copy all the vector locations into 'vecs', and before that allocates an arbitrary amount of memory: vecs.resize(iov_count); This can cause Kernel memory exhaustion, triggered by any malicious userland program. --- Kernel/Syscalls/read.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Kernel/Syscalls/read.cpp b/Kernel/Syscalls/read.cpp index b9c1256270..801e84d250 100644 --- a/Kernel/Syscalls/read.cpp +++ b/Kernel/Syscalls/read.cpp @@ -36,12 +36,9 @@ ssize_t Process::sys$readv(int fd, Userspace iov, int iov_c if (iov_count < 0) return -EINVAL; - { - Checked checked_iov_count = sizeof(iovec); - checked_iov_count *= iov_count; - if (checked_iov_count.has_overflow()) - return -EFAULT; - } + // Arbitrary pain threshold. + if (iov_count > (int)MiB) + return -EFAULT; u64 total_length = 0; Vector vecs;