Don't trust the user, and enforce the iovec limit.

Also check for negative positions smaller -1
(as -1 means using current address).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22031 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen 2007-08-21 19:07:10 +00:00
parent e9b8c538b0
commit 20c4c9e77e
2 changed files with 37 additions and 5 deletions

View File

@ -27,7 +27,7 @@
#define ARG_MAX (32768)
#define ATEXIT_MAX (32) /* XXXdbg */
#define CHILD_MAX (1024)
#define IOV_MAX (256) /* really there is no limit */
#define IOV_MAX (1024)
#define FILESIZEBITS (64)
#define LINK_MAX (1)
#define LOGIN_NAME_MAX (32) /* XXXdbg */

View File

@ -481,6 +481,9 @@ _user_read(int fd, off_t pos, void *buffer, size_t length)
if (!IS_USER_ADDRESS(buffer))
return B_BAD_ADDRESS;
if (pos < -1)
return B_BAD_VALUE;
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor)
return B_FILE_ERROR;
@ -523,6 +526,13 @@ _user_readv(int fd, off_t pos, const iovec *userVecs, size_t count)
if (!IS_USER_ADDRESS(userVecs))
return B_BAD_ADDRESS;
if (pos < -1)
return B_BAD_VALUE;
/* prevent integer overflow exploit in malloc() */
if (count > IOV_MAX)
return B_BAD_VALUE;
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor)
return B_FILE_ERROR;
@ -554,7 +564,7 @@ _user_readv(int fd, off_t pos, const iovec *userVecs, size_t count)
break;
}
if ((uint32)bytesRead + length > SSIZE_MAX)
if ((uint64)bytesRead + length > SSIZE_MAX)
bytesRead = SSIZE_MAX;
else
bytesRead += (ssize_t)length;
@ -584,6 +594,9 @@ _user_write(int fd, off_t pos, const void *buffer, size_t length)
if (IS_KERNEL_ADDRESS(buffer))
return B_BAD_ADDRESS;
if (pos < -1)
return B_BAD_VALUE;
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor)
return B_FILE_ERROR;
@ -626,6 +639,13 @@ _user_writev(int fd, off_t pos, const iovec *userVecs, size_t count)
if (!IS_USER_ADDRESS(userVecs))
return B_BAD_ADDRESS;
if (pos < -1)
return B_BAD_VALUE;
/* prevent integer overflow exploit in malloc() */
if (count > IOV_MAX)
return B_BAD_VALUE;
descriptor = get_fd(get_current_io_context(false), fd);
if (!descriptor)
return B_FILE_ERROR;
@ -657,7 +677,7 @@ _user_writev(int fd, off_t pos, const iovec *userVecs, size_t count)
break;
}
if ((uint32)bytesWritten + length > SSIZE_MAX)
if ((uint64)bytesWritten + length > SSIZE_MAX)
bytesWritten = SSIZE_MAX;
else
bytesWritten += (ssize_t)length;
@ -795,6 +815,9 @@ _kern_read(int fd, off_t pos, void *buffer, size_t length)
struct file_descriptor *descriptor;
ssize_t bytesRead;
if (pos < -1)
return B_BAD_VALUE;
descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor)
return B_FILE_ERROR;
@ -832,6 +855,9 @@ _kern_readv(int fd, off_t pos, const iovec *vecs, size_t count)
status_t status;
uint32 i;
if (pos < -1)
return B_BAD_VALUE;
descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor)
return B_FILE_ERROR;
@ -852,7 +878,7 @@ _kern_readv(int fd, off_t pos, const iovec *vecs, size_t count)
break;
}
if ((uint32)bytesRead + length > SSIZE_MAX)
if ((uint64)bytesRead + length > SSIZE_MAX)
bytesRead = SSIZE_MAX;
else
bytesRead += (ssize_t)length;
@ -874,6 +900,9 @@ _kern_write(int fd, off_t pos, const void *buffer, size_t length)
struct file_descriptor *descriptor;
ssize_t bytesWritten;
if (pos < -1)
return B_BAD_VALUE;
descriptor = get_fd(get_current_io_context(true), fd);
if (descriptor == NULL)
return B_FILE_ERROR;
@ -911,6 +940,9 @@ _kern_writev(int fd, off_t pos, const iovec *vecs, size_t count)
status_t status;
uint32 i;
if (pos < -1)
return B_BAD_VALUE;
descriptor = get_fd(get_current_io_context(true), fd);
if (!descriptor)
return B_FILE_ERROR;
@ -931,7 +963,7 @@ _kern_writev(int fd, off_t pos, const iovec *vecs, size_t count)
break;
}
if ((uint32)bytesWritten + length > SSIZE_MAX)
if ((uint64)bytesWritten + length > SSIZE_MAX)
bytesWritten = SSIZE_MAX;
else
bytesWritten += (ssize_t)length;