Fix memory corruption via uncanceled AIO requests on error in libkcapi's one-shot AIO path Resolves: RHEL-224809 Signed-off-by: Zoltan Fridrich <zfridric@redhat.com>
77 lines
1.9 KiB
Diff
77 lines
1.9 KiB
Diff
diff --git a/lib/kcapi-kernel-if.c b/lib/kcapi-kernel-if.c
|
|
index 0df1a02..9f93603 100644
|
|
--- a/lib/kcapi-kernel-if.c
|
|
+++ b/lib/kcapi-kernel-if.c
|
|
@@ -421,6 +421,8 @@ ssize_t _kcapi_common_vmsplice_chunk(struct kcapi_handle *handle,
|
|
int _kcapi_aio_read_all(struct kcapi_handle *handle, size_t toread,
|
|
struct timespec *timeout)
|
|
{
|
|
+ int err = 0;
|
|
+
|
|
if (toread > KCAPI_AIO_CONCURRENT)
|
|
return -EINVAL;
|
|
|
|
@@ -431,41 +433,34 @@ int _kcapi_aio_read_all(struct kcapi_handle *handle, size_t toread,
|
|
events, timeout);
|
|
|
|
if (rc < 0)
|
|
- return rc;
|
|
+ return err == 0 ? rc : err;
|
|
|
|
for (i = 0; i < rc; i++) {
|
|
struct iocb *cb;
|
|
+ uint64_t idx = events[i].data;
|
|
|
|
- /*
|
|
- * If one cipher operation fails, so will the entire
|
|
- * AIO operation
|
|
- */
|
|
- if (events[i].res < 0) {
|
|
- handle->aio.iocb_ret[events[i].data] =
|
|
- events[i].res;
|
|
- return (int)events[i].res;
|
|
+ if (idx >= KCAPI_AIO_CONCURRENT) {
|
|
+ if (err == 0)
|
|
+ err = -EOVERFLOW;
|
|
+ continue;
|
|
}
|
|
|
|
cb = (struct iocb *)(uintptr_t)events[i].obj;
|
|
|
|
- /*
|
|
- * Older symmetric AIO implementations used a wrong
|
|
- * return code.
|
|
- */
|
|
- if (events[i].res > 0) {
|
|
- handle->aio.iocb_ret[events[i].data] =
|
|
- events[i].res;
|
|
+ if (events[i].res == 0) {
|
|
+ handle->aio.iocb_ret[idx] = (__s64)cb->aio_nbytes;
|
|
} else {
|
|
- handle->aio.iocb_ret[events[i].data] =
|
|
- (__s64)cb->aio_nbytes;
|
|
+ handle->aio.iocb_ret[idx] = events[i].res;
|
|
+ if (events[i].res < 0 && err == 0)
|
|
+ err = (int)events[i].res;
|
|
}
|
|
|
|
cb->aio_fildes = 0;
|
|
}
|
|
- toread -= (uint32_t)rc;
|
|
+ toread -= (size_t)rc;
|
|
}
|
|
|
|
- return 0;
|
|
+ return err;
|
|
}
|
|
|
|
int _kcapi_aio_send_iov(struct kcapi_handle *handle, struct iovec *iov,
|
|
@@ -541,6 +536,7 @@ int _kcapi_aio_read_iov(struct kcapi_handle *handle,
|
|
} else {
|
|
kcapi_dolog(KCAPI_LOG_ERR,
|
|
"Could not sumbit AIO read\n");
|
|
+ _kcapi_aio_read_all(handle, (size_t)ret, NULL);
|
|
return -EIO;
|
|
}
|
|
}
|