From 98d5fd7625e9247eb0e55117880825e54885a7c8 Mon Sep 17 00:00:00 2001 From: dmiller Date: Thu, 21 Jul 2016 21:36:40 +0000 Subject: [PATCH] Fix a segfault due to Nsock event leak in NSE. --- CHANGELOG | 5 +++++ nse_nsock.cc | 13 +++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 17835c923..970e60121 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,10 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Solved a memory corruption issue that would happen if a socket connect + operation produced an error immediately, such as Network Unreachable. The + event handler was throwing a Lua error, preventing Nsock from cleaning up + properly, leaking events. [Abhishek Singh, Daniel Miller] + o [NSE] Added the datetime library for performing date and time calculations, and as a helper to the clock-skew script. diff --git a/nse_nsock.cc b/nse_nsock.cc index 70c60a066..c81190dd8 100644 --- a/nse_nsock.cc +++ b/nse_nsock.cc @@ -352,12 +352,12 @@ static void callback (nsock_pool nsp, nsock_event nse, void *ud) lua_State *L = nu->thread; if (lua_status(L) == LUA_OK && nse_status(nse) == NSE_STATUS_ERROR) { // Sometimes Nsock fails immediately and callback is called before - // l_connect has a chance to yield. TODO: Figure out how to return an error - // to the calling thread without falling into an infinite loop somewhere. + // l_connect has a chance to yield. We'll use nu->action to signal + // l_connect to return an error instead of yielding. // http://seclists.org/nmap-dev/2016/q1/201 trace(nse_iod(nse), nu->action, nu->direction); - nsock_iod_delete(nu->nsiod, NSOCK_PENDING_NOTIFY); - luaL_error(L, "Nsock immediate error"); + nu->action = "ERROR"; + return; } assert(lua_status(L) == LUA_YIELD); trace(nse_iod(nse), nu->action, nu->direction); @@ -549,6 +549,11 @@ static int connect (lua_State *L, int status, lua_KContext ctx) if (dest != NULL) freeaddrinfo(dest); + + if (!strncmp(nu->action, "ERROR", 5)) { + // Immediate error + return nseU_safeerror(L, "Nsock connect failed immediately"); + } return yield(L, nu, "CONNECT", TO, 0, NULL); }