kernel: Rework iovec copying from userland.

Create a utility function which performs all necessary checks,
allocates memory, and copies the structures, and then make use of it
in the three places in the kernel which did all this manually.

None of them were previously complete: the fd and socket code only
checked iov_base and not iov_len, while the port code did not check
anything at all.

Part of #14961.
This commit is contained in:
Augustin Cavalier
2022-06-03 16:32:11 -04:00
parent e52da6c73b
commit 00f1e7c5e4
4 changed files with 57 additions and 45 deletions
@@ -0,0 +1,41 @@
/*
* Copyright 2022, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef _UTIL_IOVEC_SUPPORT_H
#define _UTIL_IOVEC_SUPPORT_H
#include <KernelExport.h>
static inline status_t
get_iovecs_from_user(const iovec* userVecs, size_t vecCount, iovec*& vecs,
bool permitNull = false)
{
// prevent integer overflow
if (vecCount > IOV_MAX)
return B_BAD_VALUE;
if (!IS_USER_ADDRESS(userVecs))
return B_BAD_ADDRESS;
vecs = (iovec*)malloc(sizeof(iovec) * vecCount);
if (vecs == NULL)
return B_NO_MEMORY;
if (user_memcpy(vecs, userVecs, sizeof(iovec) * vecCount) != B_OK)
return B_BAD_ADDRESS;
for (size_t i = 0; i < vecCount; i++) {
if (permitNull && vecs[i].iov_base == NULL)
continue;
if (!is_user_address_range(vecs[i].iov_base, vecs[i].iov_len))
return B_BAD_ADDRESS;
}
return B_OK;
}
#endif // _UTIL_IOVEC_SUPPORT_H