From 97f592f474ebaeba0c9a0f50db8f5627cc444aca Mon Sep 17 00:00:00 2001 From: Steven Date: Sat, 8 Sep 2018 14:06:16 -0700 Subject: vlib: crash in linux_epoll_input_inline for accessing free file index [VPP-1412] Under rare scenario, epoll may still post an event to VPP although the file descriptor is already deleted via epoll_ctl (EPOLL_CTL_DEL) and the file descriptor is close. VPP tries to access the free file index entry and crash. The fix is to throw away the events which the file descriptor is already deleted. Change-Id: Ieca3a1873aecb28630c3abc42c40341f27c2faa7 Signed-off-by: Steven (cherry picked from commit aec7297ba012e1fe4bbf85cdaec8e810aa476cea) --- src/vlib/unix/input.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/vlib/unix/input.c b/src/vlib/unix/input.c index 0a61c05d471..8be0770bfd3 100644 --- a/src/vlib/unix/input.c +++ b/src/vlib/unix/input.c @@ -247,11 +247,40 @@ linux_epoll_input_inline (vlib_main_t * vm, vlib_node_runtime_t * node, for (e = em->epoll_events; e < em->epoll_events + n_fds_ready; e++) { u32 i = e->data.u32; - clib_file_t *f = pool_elt_at_index (fm->file_pool, i); + clib_file_t *f = fm->file_pool + i; clib_error_t *errors[4]; int n_errors = 0; - if (PREDICT_TRUE (!(e->events & EPOLLERR))) + if (PREDICT_FALSE (pool_is_free (fm->file_pool, f))) + { + /* + * Under rare scenerop, epoll may still post us events for the + * deleted file descriptor. We just deal with it and throw away the + * events for the corresponding file descriptor. + */ + if (e->events & EPOLLIN) + { + errors[n_errors] = + clib_error_return (0, "epoll event EPOLLIN dropped due " + "to free index %u", i); + n_errors++; + } + if (e->events & EPOLLOUT) + { + errors[n_errors] = + clib_error_return (0, "epoll event EPOLLOUT dropped due " + "to free index %u", i); + n_errors++; + } + if (e->events & EPOLLERR) + { + errors[n_errors] = + clib_error_return (0, "epoll event EPOLLERR dropped due " + "to free index %u", i); + n_errors++; + } + } + else if (PREDICT_TRUE (!(e->events & EPOLLERR))) { if (e->events & EPOLLIN) { -- cgit 1.2.3-korg