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:
parent
c89fe8a6a3
commit
1525c11928
1 changed files with 10 additions and 3 deletions
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue