From 1525c119284a9d021ff039eb8ea9c8155c60fb54 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 5 Jan 2020 10:16:19 +0100 Subject: [PATCH] Kernel: Add missing iovec base validation for writev() syscall We were forgetting to validate the base pointers of iovecs passed into the writev() syscall. Thanks to braindead for finding this bug! :^) --- Kernel/Process.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index bd91a75ce41..d0a3d1bf71a 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1282,8 +1282,15 @@ ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count) return -EFAULT; u64 total_length = 0; + Vector vecs; + vecs.ensure_capacity(iov_count); for (int i = 0; i < iov_count; ++i) { - total_length += iov[i].iov_len; + void* base = iov[i].iov_base; + size_t len = iov[i].iov_len; + if (!validate_read(base, len)) + return -EFAULT; + vecs.append({ base, len }); + total_length += len; if (total_length > INT32_MAX) return -EINVAL; } @@ -1296,8 +1303,8 @@ ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count) return -EBADF; int nwritten = 0; - for (int i = 0; i < iov_count; ++i) { - int rc = do_write(*description, (const u8*)iov[i].iov_base, iov[i].iov_len); + for (auto& vec : vecs) { + int rc = do_write(*description, (const u8*)vec.iov_base, vec.iov_len); if (rc < 0) { if (nwritten == 0) return rc;