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 typedef struct generic_io_vec { 13 generic_addr_t base; 14 generic_size_t length; 15 } generic_io_vec; 16 17 18 #ifdef _KERNEL_VM_VM_H 19 20 static inline status_t 21 generic_memcpy(generic_addr_t dest, bool destPhysical, generic_addr_t src, bool srcPhysical, 22 generic_size_t size, bool user = false) 23 { 24 if (!srcPhysical && !destPhysical) { 25 if (user) 26 return user_memcpy((void*)dest, (void*)src, size); 27 memcpy((void*)dest, (void*)src, size); 28 return B_OK; 29 } else if (destPhysical && !srcPhysical) { 30 return vm_memcpy_to_physical(dest, (const void*)src, size, user); 31 } else if (!destPhysical && srcPhysical) { 32 return vm_memcpy_from_physical((void*)dest, src, size, user); 33 } 34 35 panic("generic_memcpy: physical -> physical not supported!"); 36 return B_NOT_SUPPORTED; 37 } 38 39 #endif 40 41 42 #ifdef IS_USER_ADDRESS 43 44 static inline status_t 45 get_iovecs_from_user(const iovec* userVecs, size_t vecCount, iovec*& vecs, 46 bool permitNull = false) 47 { 48 // prevent integer overflow 49 if (vecCount > IOV_MAX || vecCount == 0) 50 return B_BAD_VALUE; 51 52 if (!IS_USER_ADDRESS(userVecs)) 53 return B_BAD_ADDRESS; 54 55 vecs = (iovec*)malloc(sizeof(iovec) * vecCount); 56 if (vecs == NULL) 57 return B_NO_MEMORY; 58 59 if (user_memcpy(vecs, userVecs, sizeof(iovec) * vecCount) != B_OK) { 60 free(vecs); 61 return B_BAD_ADDRESS; 62 } 63 64 size_t total = 0; 65 for (size_t i = 0; i < vecCount; i++) { 66 if (permitNull && vecs[i].iov_base == NULL) 67 continue; 68 if (!is_user_address_range(vecs[i].iov_base, vecs[i].iov_len)) { 69 free(vecs); 70 return B_BAD_ADDRESS; 71 } 72 if (vecs[i].iov_len > SSIZE_MAX || total > (SSIZE_MAX - vecs[i].iov_len)) { 73 free(vecs); 74 return B_BAD_VALUE; 75 } 76 total += vecs[i].iov_len; 77 } 78 79 return B_OK; 80 } 81 82 #endif 83 84 85 #endif // _UTIL_IOVEC_SUPPORT_H 86