Nmap Development mailing list archives
Re: Assertion error related to Lua garbage collection of nsock pcap objects
From: Daniel Miller <bonsaiviking () gmail com>
Date: Tue, 31 Jul 2012 07:06:51 -0500
On Mon, Jul 30, 2012 at 10:38 PM, Patrick Donnelly <batrick () batbytes com> wrote:
On Mon, Jul 30, 2012 at 6:35 PM, Daniel Miller <bonsaiviking () gmail com> wrote:A different solution would be to make sure that the Lua garbage collector can reach the nsock_iod from the nse_nsock_udata.This is already in the code: lua_getuservalue(L, 1); /* the socket user value */ lua_pushvalue(L, -2); /* the pcap socket nsiod */ lua_pushboolean(L, 1); /* dummy variable */ lua_rawset(L, -3); The pcap nsiod is anchored in the nsock userdata's uservalue (what used to be a userdata environment in Lua 5.1). What is the callstack for the error? -- - Patrick Donnelly
I've got it! But first, backtraces. The backtrace for the original assertion error: #0 __GI_abort () at abort.c:53 #1 0x00502095 in __assert_fail_base (fmt=0x63b8b8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=0x8313bb8 "msiod->state != NSIOD_STATE_DELETED", file=0x8313de0 "nsock_event.c", line=406, function=0x8313db8 "msevent_new") at assert.c:94 #2 0x00502147 in __GI___assert_fail (assertion=0x8313bb8 "msiod->state != NSIOD_STATE_DELETED", file=0x8313de0 "nsock_event.c", line=406, function=0x8313db8 "msevent_new") at assert.c:103 #3 0x08268021 in msevent_new (nsp=0x84c2b10, type=NSE_TYPE_PCAP_READ, msiod=0x85a8c10, timeout_msecs=90, handler= 0x82470ef <pcap_receive_handler(nsock_pool, nsock_event, void*)>, userdata=0x85aa70c) at nsock_event.c:406 #4 0x08269053 in nsock_pcap_read_packet (nsp=0x84c2b10, nsiod=0x85a8c10, handler=0x82470ef <pcap_receive_handler(nsock_pool, nsock_event, void*)>, timeout_msecs=90, userdata=0x85aa70c) at nsock_pcap.c:342 #5 0x082474d9 in l_pcap_receive (L=0x85a7c78) at nse_nsock.cc:970 #6 0x08289ad3 in luaD_precall (L=0x85a7c78, func=0x85bc268, nresults=4) at ldo.c:317 #7 0x082a846a in luaV_execute (L=0x85a7c78) at lvm.c:710 #8 0x0828a470 in unroll (L=0x85a7c78, ud=0x0) at ldo.c:430 #9 0x0828aaae in resume (L=0x85a7c78, ud=0x85bc278) at ldo.c:517 #10 0x08288cc4 in luaD_rawrunprotected (L=0x85a7c78, f=0x828a7c1 <resume>, ud=0x85bc278) at ldo.c:131 #11 0x0828ab5d in lua_resume (L=0x85a7c78, from=0x84bea38, nargs=5) at ldo.c:530 #12 0x082bb013 in auxresume (L=0x84bea38, co=0x85a7c78, narg=5) at lcorolib.c:31 #13 0x082bb2ff in luaB_coresume (L=0x84bea38) at lcorolib.c:53 #14 0x08289ad3 in luaD_precall (L=0x84bea38, func=0x85b8708, nresults=2) at ldo.c:317 #15 0x082a846a in luaV_execute (L=0x84bea38) at lvm.c:710 #16 0x0828a1ae in luaD_call (L=0x84bea38, func=0x84f48b0, nResults=0, allowyield=0) at ldo.c:393 #17 0x0828478d in lua_callk (L=0x84bea38, nargs=2, nresults=0, ctx=0, k=0) at lapi.c:902 #18 0x0823d6fb in run_main (L=0x84bea38) at nse_main.cc:504 #19 0x08289ad3 in luaD_precall (L=0x84bea38, func=0x84f48a0, nresults=0) at ldo.c:317 #20 0x0828a165 in luaD_call (L=0x84bea38, func=0x84f48a0, nResults=0, allowyield=0) at ldo.c:392 #21 0x0828487c in f_call (L=0x84bea38, ud=0xbfffeb78) at lapi.c:920 #22 0x08288cc4 in luaD_rawrunprotected (L=0x84bea38, f=0x8284829 <f_call>, ud=0xbfffeb78) at ldo.c:131 #23 0x0828aec1 in luaD_pcall (L=0x84bea38, func=0x8284829 <f_call>, u=0xbfffeb78, old_top=16, ef=8) at ldo.c:590 #24 0x082849a8 in lua_pcallk (L=0x84bea38, nargs=1, nresults=0, errfunc=1, ctx=0, k=0) at lapi.c:946 #25 0x0823e4fa in script_scan (targets=..., scantype=SCRIPT_SCAN) at nse_main.cc:657 #26 0x080cfe9d in nmap_main (argc=11, argv=0xbffff704) at nmap.cc:1997 #27 0x080c1501 in main (argc=11, argv=0xbffff704) at main.cc:198 The backtrace for the only call to nsi_delete: Breakpoint 2, nsi_delete (nsockiod=0x84e8ea8, pending_response=1) at nsock_iod.c:162 162 void nsi_delete(nsock_iod nsockiod, int pending_response) { (gdb) bt #0 nsi_delete (nsockiod=0x84e8ea8, pending_response=1) at nsock_iod.c:162 #1 0x082468c8 in pcap_gc (L=0x84bea38) at nse_nsock.cc:885 #2 0x08289ad3 in luaD_precall (L=0x84bea38, func=0x85af308, nresults=0) at ldo.c:317 #3 0x0828a165 in luaD_call (L=0x84bea38, func=0x85af308, nResults=0, allowyield=0) at ldo.c:392 #4 0x08290936 in dothecall (L=0x84bea38, ud=0x0) at lgc.c:807 #5 0x08288cc4 in luaD_rawrunprotected (L=0x84bea38, f=0x82908e7 <dothecall>, ud=0x0) at ldo.c:131 #6 0x0828aec1 in luaD_pcall (L=0x84bea38, func=0x82908e7 <dothecall>, u=0x0, old_top=264, ef=0) at ldo.c:590 #7 0x08290b19 in GCTM (L=0x84bea38, propagateerrors=1) at lgc.c:826 #8 0x0829229c in luaC_forcestep (L=0x84bea38) at lgc.c:1153 #9 0x082850ce in lua_gc (L=0x84bea38, what=5, data=0) at lapi.c:1056 #10 0x082b8234 in luaB_collectgarbage (L=0x84bea38) at lbaselib.c:169 #11 0x08289ad3 in luaD_precall (L=0x84bea38, func=0x85af2f8, nresults=0) at ldo.c:317 #12 0x082a846a in luaV_execute (L=0x84bea38) at lvm.c:710 #13 0x0828a1ae in luaD_call (L=0x84bea38, func=0x84e9420, nResults=0, allowyield=0) at ldo.c:393 #14 0x0828478d in lua_callk (L=0x84bea38, nargs=2, nresults=0, ctx=0, k=0) at lapi.c:902 #15 0x0823d6fb in run_main (L=0x84bea38) at nse_main.cc:504 #16 0x08289ad3 in luaD_precall (L=0x84bea38, func=0x84e9410, nresults=0) at ldo.c:317 #17 0x0828a165 in luaD_call (L=0x84bea38, func=0x84e9410, nResults=0, allowyield=0) at ldo.c:392 #18 0x0828487c in f_call (L=0x84bea38, ud=0xbfffeb78) at lapi.c:920 #19 0x08288cc4 in luaD_rawrunprotected (L=0x84bea38, f=0x8284829 <f_call>, ud=0xbfffeb78) at ldo.c:131 #20 0x0828aec1 in luaD_pcall (L=0x84bea38, func=0x8284829 <f_call>, u=0xbfffeb78, old_top=16, ef=8) at ldo.c:590 #21 0x082849a8 in lua_pcallk (L=0x84bea38, nargs=1, nresults=0, errfunc=1, ctx=0, k=0) at lapi.c:946 #22 0x0823e4fa in script_scan (targets=..., scantype=SCRIPT_SCAN) at nse_main.cc:657 #23 0x080cfe9d in nmap_main (argc=11, argv=0xbffff704) at nmap.cc:1997 #24 0x080c1501 in main (argc=11, argv=0xbffff704) at main.cc:198 Ok, now! Using the uservalue is much cleaner than altering the metatable, but the bug was that it was only set when a new nsiod was created. If an existing nsiod could be reused, no reference was added from the socket object to that nsiod, so when the first socket got garbage-collected, the nsiod was no longer reachable. It didn't get deleted immediately, since the nsock_gc routine knows that pcap nsiods can be shared, but the next iteration of the garbage collector wouldn't be able to reach it. I'm attaching a patch that adds the pcap nsiod to the socket's uservalue every time. This seems to be working well so far. Dan
Attachment:
nsock_uv.patch
Description:
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- Assertion error related to Lua garbage collection of nsock pcap objects Daniel Miller (Jul 30)
- Re: Assertion error related to Lua garbage collection of nsock pcap objects Daniel Miller (Jul 30)
- Re: Assertion error related to Lua garbage collection of nsock pcap objects Patrick Donnelly (Jul 30)
- Re: Assertion error related to Lua garbage collection of nsock pcap objects Daniel Miller (Jul 31)
- Re: Assertion error related to Lua garbage collection of nsock pcap objects Patrick Donnelly (Jul 31)
- Re: Assertion error related to Lua garbage collection of nsock pcap objects Daniel Miller (Jul 31)
- Re: Assertion error related to Lua garbage collection of nsock pcap objects jah (Jul 31)
- Re: Assertion error related to Lua garbage collection of nsock pcap objects Daniel Miller (Jul 31)