1 /* 2 * Copyright 2022, Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT license. 4 */ 5 #ifndef _UTIL_IOVEC_SUPPORT_H 6 #define _UTIL_IOVEC_SUPPORT_H 7 8 9 #include <KernelExport.h> 10 11 12 static inline status_t 13 get_iovecs_from_user(const iovec* userVecs, size_t vecCount, iovec*& vecs, 14 bool permitNull = false) 15 { 16 // prevent integer overflow 17 if (vecCount > IOV_MAX || vecCount == 0) 18 return B_BAD_VALUE; 19 20 if (!IS_USER_ADDRESS(userVecs)) 21 return B_BAD_ADDRESS; 22 23 vecs = (iovec*)malloc(sizeof(iovec) * vecCount); 24 if (vecs == NULL) 25 return B_NO_MEMORY; 26 27 if (user_memcpy(vecs, userVecs, sizeof(iovec) * vecCount) != B_OK) { 28 free(vecs); 29 return B_BAD_ADDRESS; 30 } 31 32 size_t total = 0; 33 for (size_t i = 0; i < vecCount; i++) { 34 if (permitNull && vecs[i].iov_base == NULL) 35 continue; 36 if (!is_user_address_range(vecs[i].iov_base, vecs[i].iov_len)) { 37 free(vecs); 38 return B_BAD_ADDRESS; 39 } 40 if (vecs[i].iov_len > SSIZE_MAX || total > (SSIZE_MAX - vecs[i].iov_len)) { 41 free(vecs); 42 return B_BAD_VALUE; 43 } 44 total += vecs[i].iov_len; 45 } 46 47 return B_OK; 48 } 49 50 51 #endif // _UTIL_IOVEC_SUPPORT_H 52