On 6/7/22 13:14, Warner Losh wrote:
+void unlock_iovec(struct iovec *vec, abi_ulong target_addr,
+ int count, int copy)
+{
+ struct target_iovec *target_vec;
+
+ target_vec = lock_user(VERIFY_READ, target_addr,
+ count * sizeof(struct target_iovec), 1);
+ if (target_vec) {
Locking the same region twice seems like a bad idea.
How about something like
typedef struct {
struct target_iovec *target;
abi_ulong target_addr;
int count;
struct iovec host[];
} IOVecMap;
IOVecMap *lock_iovec(abi_ulong target_addr, int count, bool copy_in)
{
IOVecMap *map;
if (count == 0) ...
if (count < 0) ...
map = g_try_malloc0(sizeof(IOVecNew) + sizeof(struct iovec) * count);
if (!map) ...
map->target = lock_user(...);
if (!map->target) {
g_free(map);
errno = EFAULT;
return NULL;
}
map->target_addr = target_addr;
map->count = count;
// lock loop
fail:
unlock_iovec(vec, false);
errno = err;
return NULL;
}
void unlock_iovec(IOVecMap *map, bool copy_out)
{
for (int i = 0, count = map->count; i < count; ++i) {
if (map->host[i].iov_base) {
abi_ulong target_base = tswapal(map->target[i].iov_base);
unlock_user(map->host[i].iov_base, target_base,
copy_out ? map->host[i].iov_len : 0);
}
}
unlock_user(map->target, map->target_addr, 0);
g_free(map);
}
r~