diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2020-02-14 17:17:08 +0000 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2020-02-22 08:26:47 +0000 |
commit | ff29ed3a331d0cd26bcd30f7cd6c0c96c7d44eed (patch) | |
tree | 6bdf3c28cedf4f6cb5a63321d846f298fceb1ab9 | |
parent | 8c6b0356b53977bcfdea5299db07884915425b0c (diff) | |
download | qemu-ff29ed3a331d0cd26bcd30f7cd6c0c96c7d44eed.zip qemu-ff29ed3a331d0cd26bcd30f7cd6c0c96c7d44eed.tar.gz qemu-ff29ed3a331d0cd26bcd30f7cd6c0c96c7d44eed.tar.bz2 |
aio-posix: fix use after leaving scope in aio_poll()
epoll_handler is a stack variable and must not be accessed after it goes
out of scope:
if (aio_epoll_check_poll(ctx, pollfds, npfd, timeout)) {
AioHandler epoll_handler;
...
add_pollfd(&epoll_handler);
ret = aio_epoll(ctx, pollfds, npfd, timeout);
} ...
...
/* if we have any readable fds, dispatch event */
if (ret > 0) {
for (i = 0; i < npfd; i++) {
nodes[i]->pfd.revents = pollfds[i].revents;
}
}
nodes[0] is &epoll_handler, which has already gone out of scope.
There is no need to use pollfds[] for epoll. We don't need an
AioHandler for the epoll fd.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Sergio Lopez <slp@redhat.com>
Message-id: 20200214171712.541358-2-stefanha@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r-- | util/aio-posix.c | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/util/aio-posix.c b/util/aio-posix.c index f67f5b3..c964627 100644 --- a/util/aio-posix.c +++ b/util/aio-posix.c @@ -105,17 +105,18 @@ static void aio_epoll_update(AioContext *ctx, AioHandler *node, bool is_new) } } -static int aio_epoll(AioContext *ctx, GPollFD *pfds, - unsigned npfd, int64_t timeout) +static int aio_epoll(AioContext *ctx, int64_t timeout) { + GPollFD pfd = { + .fd = ctx->epollfd, + .events = G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR, + }; AioHandler *node; int i, ret = 0; struct epoll_event events[128]; - assert(npfd == 1); - assert(pfds[0].fd == ctx->epollfd); if (timeout > 0) { - ret = qemu_poll_ns(pfds, npfd, timeout); + ret = qemu_poll_ns(&pfd, 1, timeout); } if (timeout <= 0 || ret > 0) { ret = epoll_wait(ctx->epollfd, events, @@ -669,13 +670,8 @@ bool aio_poll(AioContext *ctx, bool blocking) /* wait until next event */ if (aio_epoll_check_poll(ctx, pollfds, npfd, timeout)) { - AioHandler epoll_handler; - - epoll_handler.pfd.fd = ctx->epollfd; - epoll_handler.pfd.events = G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR; - npfd = 0; - add_pollfd(&epoll_handler); - ret = aio_epoll(ctx, pollfds, npfd, timeout); + npfd = 0; /* pollfds[] is not being used */ + ret = aio_epoll(ctx, timeout); } else { ret = qemu_poll_ns(pollfds, npfd, timeout); } |