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>
			
			
This commit is contained in:
		
							parent
							
								
									8c6b0356b5
								
							
						
					
					
						commit
						ff29ed3a33
					
				@ -105,17 +105,18 @@ static void aio_epoll_update(AioContext *ctx, AioHandler *node, bool is_new)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int aio_epoll(AioContext *ctx, GPollFD *pfds,
 | 
					static int aio_epoll(AioContext *ctx, int64_t timeout)
 | 
				
			||||||
                     unsigned npfd, int64_t timeout)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    GPollFD pfd = {
 | 
				
			||||||
 | 
					        .fd = ctx->epollfd,
 | 
				
			||||||
 | 
					        .events = G_IO_IN | G_IO_OUT | G_IO_HUP | G_IO_ERR,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
    AioHandler *node;
 | 
					    AioHandler *node;
 | 
				
			||||||
    int i, ret = 0;
 | 
					    int i, ret = 0;
 | 
				
			||||||
    struct epoll_event events[128];
 | 
					    struct epoll_event events[128];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(npfd == 1);
 | 
					 | 
				
			||||||
    assert(pfds[0].fd == ctx->epollfd);
 | 
					 | 
				
			||||||
    if (timeout > 0) {
 | 
					    if (timeout > 0) {
 | 
				
			||||||
        ret = qemu_poll_ns(pfds, npfd, timeout);
 | 
					        ret = qemu_poll_ns(&pfd, 1, timeout);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (timeout <= 0 || ret > 0) {
 | 
					    if (timeout <= 0 || ret > 0) {
 | 
				
			||||||
        ret = epoll_wait(ctx->epollfd, events,
 | 
					        ret = epoll_wait(ctx->epollfd, events,
 | 
				
			||||||
@ -669,13 +670,8 @@ bool aio_poll(AioContext *ctx, bool blocking)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        /* wait until next event */
 | 
					        /* wait until next event */
 | 
				
			||||||
        if (aio_epoll_check_poll(ctx, pollfds, npfd, timeout)) {
 | 
					        if (aio_epoll_check_poll(ctx, pollfds, npfd, timeout)) {
 | 
				
			||||||
            AioHandler epoll_handler;
 | 
					            npfd = 0; /* pollfds[] is not being used */
 | 
				
			||||||
 | 
					            ret = aio_epoll(ctx, timeout);
 | 
				
			||||||
            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);
 | 
					 | 
				
			||||||
        } else  {
 | 
					        } else  {
 | 
				
			||||||
            ret = qemu_poll_ns(pollfds, npfd, timeout);
 | 
					            ret = qemu_poll_ns(pollfds, npfd, timeout);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user