From 9754682420295507066b41cc9fdf5c8325c87ec2 Mon Sep 17 00:00:00 2001 From: batrick Date: Fri, 23 Nov 2012 03:47:43 +0000 Subject: [PATCH] Cancel the sleep event if the thread is destroyed by NSE. This solves an assertion failure when the thread was garbage collected by Lua before the sleep callback occurred. Reported by Henri Doreau [1]. [1] http://seclists.org/nmap-dev/2012/q4/43 --- nse_nsock.cc | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/nse_nsock.cc b/nse_nsock.cc index 297cb39ca..47b6fa4d6 100644 --- a/nse_nsock.cc +++ b/nse_nsock.cc @@ -704,6 +704,20 @@ static int l_set_timeout (lua_State *L) return nseU_success(L); } +static int sleep_destructor (lua_State *L) +{ + nsock_pool nsp = get_pool(L); + nsock_event_id *neidp = (nsock_event_id *) lua_touserdata(L, 2); + if (o.debugging >= 2) + log_write(LOG_STDERR, "Destroying sleep callback.\n"); + assert(neidp); + int success = nsock_event_cancel(nsp, *neidp, 0); + if (success) + return nseU_success(L); + else + return nseU_safeerror(L, "could not cancel event"); +} + static void sleep_callback (nsock_pool nsp, nsock_event nse, void *ud) { lua_State *L = (lua_State *) ud; @@ -720,9 +734,15 @@ static int l_sleep (lua_State *L) if (secs < 0) luaL_error(L, "argument to sleep (%f) must not be negative\n", secs); + /* Convert to milliseconds for nsock_timer_create. */ msecs = (int) (secs * 1000 + 0.5); - nsock_timer_create(nsp, sleep_callback, msecs, L); + + nsock_event_id *neidp = (nsock_event_id *) lua_newuserdata(L, sizeof(nsock_event_id *)); + *neidp = nsock_timer_create(nsp, sleep_callback, msecs, L); + lua_pushvalue(L, NSOCK_POOL); + lua_pushcclosure(L, sleep_destructor, 1); + nse_destructor(L, 'a'); return nse_yield(L, 0, NULL); }