mirror of
https://review.haiku-os.org/haiku
synced 2025-01-31 18:56:49 +01:00
013719cfc6
* the return type for recvmsg(), sendmsg(), readv(), writev() is ssize_t. * check required by POSIX. * fix memory leaks on failure introduced in 00f1e7c5e40b41f892625b720c6a032b20f0c405 Change-Id: Ibf74ae2035b7e9c7a3db3613f60e06672ded4db0 Reviewed-on: https://review.haiku-os.org/c/haiku/+/5542 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: waddlesplash <waddlesplash@gmail.com>
52 lines
1.1 KiB
C
52 lines
1.1 KiB
C
/*
|
|
* 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 || vecCount == 0)
|
|
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) {
|
|
free(vecs);
|
|
return B_BAD_ADDRESS;
|
|
}
|
|
|
|
size_t total = 0;
|
|
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)) {
|
|
free(vecs);
|
|
return B_BAD_ADDRESS;
|
|
}
|
|
if (vecs[i].iov_len > SSIZE_MAX || total > (SSIZE_MAX - vecs[i].iov_len)) {
|
|
free(vecs);
|
|
return B_BAD_VALUE;
|
|
}
|
|
total += vecs[i].iov_len;
|
|
}
|
|
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
#endif // _UTIL_IOVEC_SUPPORT_H
|