mirror of https://gerrit.osmocom.org/libosmocore
osmo_io_uring: Cancel pending request, free msghdr on completion
There is always a completion after cancelling a uring request. Because uring requests use msghdr pointer as user data, we cannot just free the msghdr after cancelling. Upon completion (received after cancelling), the user data still points to the msghdr. To prevent a use-after-free bug, msghdr is not freed, but detached from iofd instance. Then upon completion, the msghdr (if it was detached from iofd) is freed. Related: OS#5751 Change-Id: Ic253f085dd6362db85f029f46350951472210a02
This commit is contained in:
parent
80c05877d8
commit
1a531e264f
|
@ -252,6 +252,11 @@ static void iofd_uring_cqe(struct io_uring *ring)
|
|||
io_uring_cqe_seen(ring, cqe);
|
||||
continue;
|
||||
}
|
||||
if (!msghdr->iofd) {
|
||||
io_uring_cqe_seen(ring, cqe);
|
||||
iofd_msghdr_free(msghdr);
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = cqe->res;
|
||||
/* Hand the entry back to the kernel before */
|
||||
|
@ -307,20 +312,31 @@ static int iofd_uring_register(struct osmo_io_fd *iofd)
|
|||
static int iofd_uring_unregister(struct osmo_io_fd *iofd)
|
||||
{
|
||||
struct io_uring_sqe *sqe;
|
||||
struct iofd_msghdr *msghdr;
|
||||
|
||||
if (iofd->u.uring.read_msghdr) {
|
||||
msghdr = iofd->u.uring.read_msghdr;
|
||||
sqe = io_uring_get_sqe(&g_ring.ring);
|
||||
OSMO_ASSERT(sqe != NULL);
|
||||
io_uring_sqe_set_data(sqe, NULL);
|
||||
LOGPIO(iofd, LOGL_DEBUG, "Cancelling read\n");
|
||||
io_uring_prep_cancel(sqe, iofd->u.uring.read_msghdr, 0);
|
||||
iofd->u.uring.read_msghdr = NULL;
|
||||
talloc_steal(OTC_GLOBAL, msghdr);
|
||||
msghdr->iofd = NULL;
|
||||
io_uring_prep_cancel(sqe, msghdr, 0);
|
||||
}
|
||||
|
||||
if (iofd->u.uring.write_msghdr) {
|
||||
msghdr = iofd->u.uring.write_msghdr;
|
||||
sqe = io_uring_get_sqe(&g_ring.ring);
|
||||
OSMO_ASSERT(sqe != NULL);
|
||||
io_uring_sqe_set_data(sqe, NULL);
|
||||
LOGPIO(iofd, LOGL_DEBUG, "Cancelling write\n");
|
||||
io_uring_prep_cancel(sqe, iofd->u.uring.write_msghdr, 0);
|
||||
iofd->u.uring.write_msghdr = NULL;
|
||||
talloc_steal(OTC_GLOBAL, msghdr);
|
||||
msgb_free(msghdr->msg);
|
||||
msghdr->iofd = NULL;
|
||||
io_uring_prep_cancel(sqe, msghdr, 0);
|
||||
}
|
||||
io_uring_submit(&g_ring.ring);
|
||||
|
||||
|
|
Loading…
Reference in New Issue