Re: [PATCH 1/5] aio-posix: fix use after leaving scope in aio_poll()

2020-02-18 Thread Sergio Lopez
On Fri, Feb 14, 2020 at 05:17:08PM +, Stefan Hajnoczi wrote:
> 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 
> ---
>  util/aio-posix.c | 20 
>  1 file changed, 8 insertions(+), 12 deletions(-)

Reviewed-by: Sergio Lopez 


signature.asc
Description: PGP signature


[PATCH 1/5] aio-posix: fix use after leaving scope in aio_poll()

2020-02-14 Thread Stefan Hajnoczi
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 
---
 util/aio-posix.c | 20 
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/util/aio-posix.c b/util/aio-posix.c
index a4977f538e..31a8e03ca7 100644
--- a/util/aio-posix.c
+++ b/util/aio-posix.c
@@ -104,17 +104,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,
@@ -658,13 +659,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);
 }
-- 
2.24.1