From bf8035f68b0748d1380977aafc4349331b74cbda Mon Sep 17 00:00:00 2001 From: Evan Green Date: Tue, 22 Jan 2019 15:49:55 -0800 Subject: [PATCH] watch: Fix buffer overflow diag_ffs_recv copies mbuf->offset bytes into a fixed 16k buffer. watch_handle_eventfd sets pending_aio->offset to ev->res, assuming that ev->res represents the number of bytes read. But res can be negative in error cases. This causes diag_ffs_recv to copy a very large amount into a 16k buffer, smashing the stack. Avoid populating pending_aio->offset if the result is failure. Also, it appears that if the status code is EAGAIN, the I/O is actually still in the system, and comes back later. Signed-off-by: Evan Green --- router/watch.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/router/watch.c b/router/watch.c index 98aeac9..9c101d3 100644 --- a/router/watch.c +++ b/router/watch.c @@ -337,7 +337,10 @@ static void watch_handle_eventfd(int evfd, aio_context_t ioctx) if (iocb->aio_fildes == w->fd) { assert(w->pending_aio); - if (!w->is_write) + if (ev[i].res == -EAGAIN) + continue; + + if (!w->is_write && ev[i].res >= 0) w->pending_aio->offset = ev[i].res; w->aio_complete(w->pending_aio, w->data);