eggheads / eggdrop

The Eggdrop IRC Bot
GNU General Public License v2.0
509 stars 84 forks source link

memory leak in got353() / ismember() / newmember() #1666

Open michaelortmann opened 4 months ago

michaelortmann commented 4 months ago

start local irc server for testing

$ ~/opt/solanum-20230413/bin/solanum
  notice: starting solanum-1.0-dev ...
  notice: librb version: 20240413-519d9bc0 - OpenSSL: compiled (0x30200010, OpenSSL 3.2.1 30 Jan 2024), library (0x30300010, OpenSSL 3.3.1 4 Jun 2024)
  notice: now running in background mode from /home/michael/opt/solanum-20230413 as pid 3253 ...

compile current git eggdrop with CFLAGS of our choice:

$ git rev-parse HEAD
74c786165272a9a7c7a7374d1906d2b30201d862
$ CFLAGS="-Og -g3" ./configure
$ make config
$ make eggdrop
$ make install

run eggdrop with valgrinds memcheck memory leak detector:

$ valgrind --leak-check=full --show-possibly-lost=no ./eggdrop -t BotA.conf
==10755== Memcheck, a memory error detector
==10755== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==10755== Using Valgrind-3.23.0 and LibVEX; rerun with -h for copyright info
==10755== Command: ./eggdrop -t BotA.conf
==10755== 

Eggdrop v1.9.5+accounttracking (C) 1997 Robey Pointer (C) 1999-2024 Eggheads Development Team
--- Loading eggdrop v1.9.5+accounttracking (Thu Aug  1 2024)
[...]

after eggdrop is fully connected to server and idle:

.console +* .+chan #test

after eggdrop is fully joined to #test:

.die

result is the following leak log:

.+chan #test[15:20:00] [m->] PING :1722518400
[15:20:04] tcl: builtin dcc call: *dcc:+chan -HQ 1 #test
[15:20:04] [!s] JOIN #test
[15:20:04] #-HQ# +chan #test
[15:20:04] [s->] JOIN #test
[15:20:04] [@] :BotA!~eggdrop@localhost JOIN #test * :A deranged product of evil coders
[15:20:04] BotA joined #test.
[15:20:04] [!m] MODE #test +b
[15:20:04] [m->] MODE #test +b
[15:20:04] [!m] MODE #test +e
[15:20:04] [m->] MODE #test +e
[15:20:04] [!m] MODE #test +I
[15:20:04] [m->] MODE #test +I
[15:20:04] [!m] MODE #test
[15:20:04] [!m] WHO #test c%chnufat,222
[15:20:04] [@] :zen.home.arpa MODE #test +nt
[15:20:04] #test: mode change '+nt ' by zen.home.arpa
[15:20:04] [@] :zen.home.arpa 353 BotA = #test :@BotA
[15:20:04] [@] :zen.home.arpa 366 BotA #test :End of /NAMES list.
[15:20:04] [@] :zen.home.arpa 368 BotA #test :End of Channel Ban List
[15:20:04] [@] :zen.home.arpa 349 BotA #test :End of Channel Exception List
[15:20:04] [@] :zen.home.arpa 347 BotA #test :End of Channel Invite List
[15:20:05] [m->] MODE #test
[15:20:05] [@] :zen.home.arpa 324 BotA #test +nt
[15:20:05] [@] :zen.home.arpa 329 BotA #test 1722518404
[15:20:07] [m->] WHO #test c%chnufat,222
[15:20:07] [@] :zen.home.arpa 354 BotA 222 #test ~eggdrop localhost BotA H@ 0
[15:20:07] [@] :zen.home.arpa 315 BotA #test :End of /WHO list.
.die
[15:20:42] tcl: builtin dcc call: *dcc:die -HQ 1 
[15:20:42] #-HQ# die 
[15:20:42] [->] QUIT :-HQ
[15:20:45] triggering bind quotepong_unbind
[15:20:45] triggered bind quotepong_unbind, user 8.362ms sys 0.075ms
*** BOT SHUTDOWN (Authorized by -HQ)
[15:20:45] Writing user file...
[15:20:42] Writing channel file...
[15:20:42] * DIE BY -HQ!llama@console (request)
==10906== 
==10906== HEAP SUMMARY:
==10906==     in use at exit: 1,098,893 bytes in 4,277 blocks
==10906==   total heap usage: 15,877 allocs, 11,600 frees, 3,123,226 bytes allocated
==10906== 
==10906== 456 bytes in 1 blocks are definitely lost in loss record 424 of 524
==10906==    at 0x48447A8: malloc (vg_replace_malloc.c:446)
==10906==    by 0x13FF41: n_malloc (mem.c:342)
==10906==    by 0x143B92: mod_malloc (modules.c:1008)
==10906==    by 0x4870313: channel_malloc (channels.c:64)
==10906==    by 0x5A6140B: newmember (chan.c:51)
==10906==    by 0x5A7E6A1: got352or4 (chan.c:1073)
==10906==    by 0x5A7EC6F: got353 (chan.c:1296)
==10906==    by 0x5A3E207: server_raw (server.c:1410)
==10906==    by 0x1483D2: tcl_call_stringproc_cd (tcl.c:332)
==10906==    by 0x48B97FF: TclNRRunCallbacks (tclBasic.c:4539)
==10906==    by 0x48BB7E4: TclEvalEx (tclBasic.c:5408)
==10906==    by 0x48BC096: Tcl_EvalEx (tclBasic.c:5073)
==10906== 
==10906== LEAK SUMMARY:
==10906==    definitely lost: 456 bytes in 1 blocks
==10906==    indirectly lost: 0 bytes in 0 blocks
==10906==      possibly lost: 762,544 bytes in 565 blocks
==10906==    still reachable: 335,893 bytes in 3,711 blocks
==10906==         suppressed: 0 bytes in 0 blocks
==10906== Reachable blocks (those to which a pointer was found) are not shown.
==10906== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==10906== 
==10906== For lists of detected and suppressed errors, rerun with: -s
==10906== ERROR SUMMARY: 96 errors from 96 contexts (suppressed: 0 from 0)

Analysis:

Bug since 05377ac00e8c8e2e1f0e41d3b0e723999d9f8884

[15:20:04] [@] :zen.home.arpa 353 BotA = #test :@BotA triggers got353(), which parses this line, determines variable nick = "" and calls got352or4().

btw: this is a misleading function name, for got352or4() can be called for a 353 also. ismember() returns NULL for members in chan-memberlist, but / so newmember() is called for nick= "" and the member-nick is set to "".

I also wonder, if i understand the code line: https://github.com/eggheads/eggdrop/blob/74c786165272a9a7c7a7374d1906d2b30201d862/src/mod/irc.mod/chan.c#L1266 correctly. This evaluates to true, while .status server shows Active CAP negotiations: account-notify extended-join sasl. Also makes me wonder, if eggdrop lacks a function to check for active / negotiated cap? Other places, that check for those currently manually loop / check, like here: https://github.com/eggheads/eggdrop/blob/74c786165272a9a7c7a7374d1906d2b30201d862/src/mod/irc.mod/irc.c#L1075

I also wonder, if Errata about userhost-in-names in https://github.com/eggheads/eggdrop/blob/74c786165272a9a7c7a7374d1906d2b30201d862/doc/sphinx_source/using/ircv3.rst is related. Am i triggering a known bug or did i mis-configure eggdrop?