Nmap Development mailing list archives
Re: [NSE] assertion failure in stdnse.sleep()
From: Henri Doreau <henri.doreau () gmail com>
Date: Tue, 6 Nov 2012 13:43:36 +0100
2012/10/17 Patrick Donnelly <batrick () batbytes com>
Hi David, On Wed, Oct 17, 2012 at 4:59 PM, David Fifield <david () bamsoftware com> wrote:One is that calling sleep or another yielding function doesn't seem to work from an exception handler: local stdnse = require('stdnse') prerule = function() return true end action = function() local catch = function() stdnse.sleep(20) end local try = nmap.new_try(catch) try(false) end attempt to yield across metamethod/C-call boundary stack traceback: [C]: in function 'sleep' a.nse:4: in function <a.nse:4> [C]: in function 'try' a.nse:6: in function <a.nse:3> (...tail calls...) I'm confused by this error because I thought that "yield across metamethod/C-call boundary" wasn't a thing anymore with Lua 5.2.It still exists. A regular lua_call (in C [1]) does not allow coroutine yields to cross the call boundary. We still use lua_call in new_try_finalize. To contrast, many call paths in Lua have been adapted so that you never see this C boundary error anymore, e.g. pcall [2] or dofile [3]. These functions use lua_callk or lua_pcallk. Lua allows yields across these functions because the caller passes a continuation function to Lua. This enables Lua to restart the function when the coroutine is resumed again. See for example, the continuation function for pcall [4]. Continuations are explained in the manual [5]. I wrote a quick patch (untested) which should correct the problem, attached. [1] http://www.lua.org/manual/5.2/manual.html#lua_call [2] http://www.lua.org/source/5.2/lbaselib.c.html#luaB_pcall [3] http://www.lua.org/source/5.2/lbaselib.c.html#luaB_dofile [4] http://www.lua.org/source/5.2/lbaselib.c.html#pcallcont [5] http://www.lua.org/manual/5.2/manual.html#4.7I thought about using nse_destructor to have l_sleep register a destructor that cancels the timer event; hopefully this happens before the thread is freed.Destructors are run before the thread is freed. For socket functions, they are able to associate the thread with the socket userdatum to ensure the thread is never collected before the socket userdatum is collected. [This is why it's not necessary to register a destructor for socket methods as, if the thread no longer exists, the nse_restore function will silently fail. This could happen if NSE throws out a timed out script and the nsock callback tries to nse_restore the thread.] Unfortunately, we don't have that convenience for the sleep function. I guess the appropriate way to deal with this unique problem is both making try/catch C continuation compatible (with the patch attached) and adding a destructor to sleep so this situation can't happen again. -- - Patrick Donnelly
Hi, what's the status concerning this issue? With your patch I can still reproduce a similar crash by doing the following (strange) steps: 1: Patch a random script to make it sleep for a while Index: scripts/ssh-hostkey.nse =================================================================== --- scripts/ssh-hostkey.nse (revision 30204) +++ scripts/ssh-hostkey.nse (working copy) @@ -127,6 +127,8 @@ local format = nmap.registry.args.ssh_hostkey or "hex" local all_formats = format:find( 'all', 1, true ) + stdnse.sleep(3) + key = ssh1.fetch_host_key( host, port ) if key then table.insert( keys, key ) end 2: Run ./nmap --script ssh-hostkey --host-timeout 2s localhost Starting Nmap 6.02 ( http://nmap.org ) Nmap scan report for localhost (127.0.0.1) Host is up (0.00026s latency). Skipping host localhost (127.0.0.1) due to host timeout Nmap done: 1 IP address (1 host up) scanned in 2.19 seconds nmap: nse_nsock.cc:710: void sleep_callback(void*, void*, void*): Assertion `lua_status(L) == 1' failed. Also, if I run: ./nmap --script ssh-hostkey --host-timeout 2s --max-hostgroup=1 localhost localhost (note that localhost is specified twice here) I get: Starting Nmap 6.02 ( http://nmap.org ) Nmap scan report for localhost (127.0.0.1) Host is up (0.00026s latency). Skipping host localhost (127.0.0.1) due to host timeout nmap: nse_nsock.cc:710: void sleep_callback(void*, void*, void*): Assertion `lua_status(L) == 1' failed. Aborted Although I'd have expected the crash to happen for the first hostgroup too... I'm getting very confused with this issue. Regards -- Henri _______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- [NSE] assertion failure in stdnse.sleep() Henri Doreau (Oct 06)
- Re: [NSE] assertion failure in stdnse.sleep() David Fifield (Oct 17)
- Re: [NSE] assertion failure in stdnse.sleep() Patrick Donnelly (Oct 17)
- Re: [NSE] assertion failure in stdnse.sleep() Henri Doreau (Nov 06)
- Re: [NSE] assertion failure in stdnse.sleep() Patrick Donnelly (Nov 15)
- Re: [NSE] assertion failure in stdnse.sleep() David Fifield (Nov 21)
- Re: [NSE] assertion failure in stdnse.sleep() Patrick Donnelly (Nov 22)
- Re: [NSE] assertion failure in stdnse.sleep() David Fifield (Nov 23)
- Re: [NSE] assertion failure in stdnse.sleep() Patrick Donnelly (Oct 17)
- Re: [NSE] assertion failure in stdnse.sleep() David Fifield (Oct 17)