1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:57:35 +00:00

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! :^)
This commit is contained in:
Andreas Kling 2020-01-05 10:16:19 +01:00
parent c89fe8a6a3
commit 1525c11928

View file

@ -1282,8 +1282,15 @@ ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count)
return -EFAULT; return -EFAULT;
u64 total_length = 0; u64 total_length = 0;
Vector<iovec, 32> vecs;
vecs.ensure_capacity(iov_count);
for (int i = 0; i < iov_count; ++i) { 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) if (total_length > INT32_MAX)
return -EINVAL; return -EINVAL;
} }
@ -1296,8 +1303,8 @@ ssize_t Process::sys$writev(int fd, const struct iovec* iov, int iov_count)
return -EBADF; return -EBADF;
int nwritten = 0; int nwritten = 0;
for (int i = 0; i < iov_count; ++i) { for (auto& vec : vecs) {
int rc = do_write(*description, (const u8*)iov[i].iov_base, iov[i].iov_len); int rc = do_write(*description, (const u8*)vec.iov_base, vec.iov_len);
if (rc < 0) { if (rc < 0) {
if (nwritten == 0) if (nwritten == 0)
return rc; return rc;