View Issue Details

IDProjectCategoryView StatusLast Update
0005669unrealircdpublic2020-05-09 12:11
ReporterGottem Assigned Tosyzop  
PrioritynormalSeveritycrashReproducibilitysometimes
Status resolvedResolutionfixed 
Product Version5.0.5 
Fixed in Version5.0.5 
Summary0005669: Rare crash issue involving third-party channel mode with param and +P
DescriptionI believe GaMbiTo initially reported the issue and PeGaSuS was able to reproduce it, but I'm not. :>

Apparently when using my joinmute module (+J <seconds>) in conjunction with +P, Unreal may or may not crash when you rehash. After letting Pegasus mess with gdb we found this:

(gdb) b channel.c:707
Breakpoint 1 at 0x5555555713c8: file channel.c, line 707.
(gdb) c
Continuing.
WARNING: Time jumped ~29 seconds ahead! (1588961268 -> 1588961297)
[TimeShift] Resetting some timers!
Loading IRCd configuration..
Configuration loaded.
Loading IRCd configuration..

Thread 1 "unrealircd" hit Breakpoint 1, channel_modes (client=<optimized out>, mbuf=0x5555555f48e5 <modebuf+5> "", mbuf@entry=0x5555555f48e0 <modebuf> "+ntPJ", 
    pbuf=pbuf@entry=0x5555555f46e0 <parabuf> "", mbuf_size=507, mbuf_size@entry=512, pbuf_size=pbuf_size@entry=512, channel=channel@entry=0x555555bab4c0) at channel.c:707
707					ircsnprintf(pbuf, pbuf_size, "%s ", cm_getparameter(channel, flag));
(gdb) p channel->chname + 0
$1 = 0x555555bab628 "#test"
(gdb) p flag
$2 = 74 'J'
(gdb) p cm_getparameter(channel, flag)

Thread 1 "unrealircd" received signal SIGSEGV, Segmentation fault.


However, when I do exactly the same steps, the line that causes a segfault for him doesn't for me:
(gdb) p cm_getparameter(channel, flag)
$6 = 0x7ffff382a800 <retbuf> "10"


I checked some shit around the get_param() module API stuff but when I compare with one of your modules (chanhistory) I don't see anything out of the ordinary, so I don't think it's an issue with the module. We're both using the dev version along with the same version of this particular module. :>

Also, here's the full backtrace:
Thread 1 "unrealircd" received signal SIGSEGV, Segmentation fault.
0x00007ffff757d510 in ?? ()
(gdb) bt
#0  0x00007ffff757d510 in ?? ()
#1  0x00005555555713cd in channel_modes (client=<optimized out>, mbuf=0x5555555f48e5 <modebuf+5> "", mbuf@entry=0x5555555f48e0 <modebuf> "+ntPJ", pbuf=pbuf@entry=0x5555555f46e0 <parabuf> "", 
    mbuf_size=507, mbuf_size@entry=512, pbuf_size=pbuf_size@entry=512, channel=channel@entry=0x555555bab500) at channel.c:707
#2  0x00007ffff75b4dce in write_channel_entry (channel=0x555555bab500, tmpfname=0x7fffffffb9a0 "/home/unrealircd/unrealircd/data/channel.db.tmp", fd=0x55555595a450) at channeldb.c:292
#3  write_channel_entry (fd=0x55555595a450, tmpfname=0x7fffffffb9a0 "/home/unrealircd/unrealircd/data/channel.db.tmp", channel=0x555555bab500) at channeldb.c:280
#4  0x00007ffff75b502e in write_channeldb () at channeldb.c:231
#5  0x00007ffff75b5111 in Mod_Unload (modinfo=0x555555a0c448) at channeldb.c:118
#6  0x000055555557c05e in Unload_all_loaded_modules () at modules.c:592
#7  0x000055555559bcbe in init_conf (rootconf=0x5555559562a0 "/home/unrealircd/unrealircd/conf/unrealircd.conf", rehash=rehash@entry=1) at conf.c:2080
0000008  0x000055555559bef5 in rehash_internal (client=client@entry=0x7ffff74e4058, sig=<optimized out>) at conf.c:10165
#9  0x000055555559bfe8 in rehash (client=client@entry=0x7ffff74e4058, sig=<optimized out>) at conf.c:10156
#10 0x00005555555a24be in cmd_rehash (client=0x7ffff74e4058, recv_mtags=<optimized out>, parc=<optimized out>, parv=0x5555558a9c40 <para>) at serv.c:687
#11 0x000055555557de46 in parse2 (cptr=cptr@entry=0x7ffff74e4058, fromptr=fromptr@entry=0x7fffffffbf90, mtags=0x0, ch=<optimized out>) at parse.c:501
#12 0x000055555557e451 in parse (cptr=cptr@entry=0x7ffff74e4058, buffer=<optimized out>, length=<optimized out>) at parse.c:228
#13 0x000055555557e5f9 in dopacket (client=client@entry=0x7ffff74e4058, buffer=buffer@entry=0x7fffffffbfe0 "rehash", length=<optimized out>) at parse.c:159
#14 0x000055555557e6bd in parse_client_queued (client=client@entry=0x7ffff74e4058) at parse.c:120
#15 0x000055555557e757 in process_packet (client=client@entry=0x7ffff74e4058, 
    readbuf=readbuf@entry=0x5555558cdfa0 <readbuf> "rehash\r\n1588909005047\r\n2\r\n\nost cap-notify userhost-in-names multi-prefix away-notify account-notify server-time\r\n", 
    length=<optimized out>, killsafely=killsafely@entry=0) at parse.c:56
#16 0x00005555555a4471 in read_packet (fd=9, revents=<optimized out>, data=0x7ffff74e4058) at socket.c:1115
0000017 0x000055555559c687 in fd_select (delay=<optimized out>) at dispatch.c:500
#18 0x0000555555577950 in SocketLoop (dummy=<optimized out>) at ircd.c:1410
#19 0x000055555556dc09 in main (argc=<optimized out>, argv=<optimized out>) at ircd.c:1377
Steps To ReproduceAccording to the others:
* Load joinmute
* Create new channel
* Set +J 10
* Set +P (separately just in case)
* Rehash
TagsNo tags attached.
3rd party modulesjoinmute

Activities

k4be

2020-05-08 21:54

developer   ~0021559

There's another stack trace from an user (because i can't reproduce this issue)

Program received signal SIGSEGV, Segmentation fault.
0x00007fd7ea443470 in ?? ()
(gdb) bt
#0 0x00007fd7ea443470 in ?? ()
#1 0x0000562fa3c3a8f1 in channel_modes (client=<optimized out>,
    mbuf=0x562fa3ebb8e5 <modebuf+5> "ooo",
    mbuf@entry=0x562fa3ebb8e0 <modebuf> "+ntPJooo",
    pbuf=pbuf@entry=0x562fa3ebb6e0 <parabuf> "", mbuf_size=507,
    mbuf_size@entry=512, pbuf_size=pbuf_size@entry=512,
    channel=channel@entry=0x562fa4d67d50) at channel.c:707
#2 0x00007fd7ff91ddf9 in write_channel_entry (channel=0x562fa4d67d50,
    tmpfname=0x7fffd11cc4a0 "/home/gabriel/unrealircd/data/channel.db.tmp",
    fd=0x562fa4de8af0) at channeldb.c:292
#3 write_channel_entry (fd=0x562fa4de8af0,
    tmpfname=0x7fffd11cc4a0 "/home/gabriel/unrealircd/data/channel.db.tmp",
    channel=0x562fa4d67d50) at channeldb.c:280
#4 0x00007fd7ff91e04e in write_channeldb () at channeldb.c:231
#5 0x00007fd7ff91e12d in Mod_Unload (modinfo=0x562fa4e69a78)
    at channeldb.c:118
#6 0x0000562fa3c4542d in Unload_all_loaded_modules () at modules.c:592
#7 0x0000562fa3c64e08 in init_conf (
    rootconf=0x562fa4b71260 "/home/gabriel/unrealircd/conf/unrealircd.conf",
    rehash=rehash@entry=1) at conf.c:2078
0000008 0x0000562fa3c65045 in rehash_internal (client=client@entry=0x7fd815914058,
    sig=<optimized out>) at conf.c:10152
#9 0x0000562fa3c65134 in rehash (client=client@entry=0x7fd815914058,
--Type <RET> for more, q to quit, c to continue without paging--

syzop

2020-05-09 08:34

administrator   ~0021560

Could it be related to the order in which modules are loaded? eg if the loadmodule is before or after the include for modules.default.conf etc.

k4be

2020-05-09 11:35

developer   ~0021561

You're right, it can be reproduced even without using any addon modules (5.0.5-dev).
Steps:
1. Set a channel +P
2. Move the line loadmodule "chanmodes/link"; at the end of modules.default.conf
3. Set a channel +L #something
4. /rehash

Strangely, a core file is not generated for me.
Backtrace:

#0 0x00007ffff35806bd in ?? ()
#1 0x0000555555646fae in cm_getparameter (channel=channel@entry=0x613000014e80, mode=<optimized out>) at api-channelmode.c:410
#2 0x00005555555b5b78 in channel_modes (client=<optimized out>, mbuf=0x5555556fa6a6 <modebuf+6> "", mbuf@entry=0x5555556fa6a0 <modebuf> "+ntPSL", pbuf=0x5555556fa480 <parabuf> "", mbuf_size=506, mbuf_size@entry=512, pbuf_size=pbuf_size@entry=512,
    channel=channel@entry=0x613000014e80) at channel.c:707
#3 0x00007ffff35c4433 in write_channel_entry (fd=fd@entry=0x616000093f80, tmpfname=tmpfname@entry=0x7fffffffa880 "/home/k4be/unrealircd/data/channel.db.tmp", channel=channel@entry=0x613000014e80) at channeldb.c:292
#4 0x00007ffff35c4c61 in write_channeldb () at channeldb.c:231
#5 0x00007ffff35c4e43 in Mod_Unload (modinfo=0x60b000007ef8) at channeldb.c:118
#6 0x00005555555d0846 in Unload_all_loaded_modules () at modules.c:592
#7 0x0000555555613876 in init_conf (rootconf=0x604000000010 "/home/k4be/unrealircd/conf/unrealircd.conf", rehash=rehash@entry=1) at conf.c:2080
0000008 0x0000555555613c0b in rehash_internal (client=<optimized out>, sig=<optimized out>) at conf.c:10165
#9 0x0000555555613d8a in rehash (client=client@entry=0x614000003e40, sig=<optimized out>) at conf.c:10156
#10 0x00005555556207d3 in cmd_rehash (client=0x614000003e40, recv_mtags=<optimized out>, parc=<optimized out>, parv=0x5555559ae660 <para>) at serv.c:687
#11 0x00005555555d4d3c in parse2 (cptr=cptr@entry=0x614000003e40, fromptr=fromptr@entry=0x7fffffffae20, mtags=<optimized out>, ch=<optimized out>) at parse.c:501
#12 0x00005555555d53c8 in parse (cptr=cptr@entry=0x614000003e40, buffer=<optimized out>, length=<optimized out>) at parse.c:228
#13 0x00005555555d5988 in dopacket (client=client@entry=0x614000003e40, buffer=buffer@entry=0x7fffffffaf50 "rehash", length=<optimized out>) at parse.c:159
#14 0x00005555555d5cb9 in parse_client_queued (client=client@entry=0x614000003e40) at parse.c:120
#15 0x00005555555d5d93 in process_packet (client=client@entry=0x614000003e40,
    readbuf=readbuf@entry=0x5555559d5ae0 <readbuf> "rehash\r\ne asdf\r\n30238\r\n2\r\n\nost cap-notify userhost-in-names multi-prefix away-notify account-notify server-time\r\n74 :Reserved for services\r\n:test2.pirc.pl TKL + Q * Bot serwisy.pirc.pl 0 1577621474 :R"...,
    length=<optimized out>, killsafely=killsafely@entry=0) at parse.c:56
#16 0x00005555556258e8 in read_packet (fd=<optimized out>, revents=<optimized out>, data=0x614000003e40) at socket.c:1092
0000017 0x0000555555614c5a in fd_select (delay=<optimized out>) at dispatch.c:500
#18 0x00005555555c575b in SocketLoop (dummy=<optimized out>) at ircd.c:1410
#19 0x00005555555c6e35 in main (argc=<optimized out>, argv=<optimized out>) at ircd.c:1377

k4be

2020-05-09 11:36

developer   ~0021562

I can't edit the above post. I've missed one step i did: insert another /rehash between 2 and 3.

syzop

2020-05-09 12:09

administrator   ~0021563

Last edited: 2020-05-09 12:11

Fixed now. For the record, as k4be pointed out, the workaround in versions before this fix, is to move the loadmodule line for the 3rd party channel mode parameter module(s) before the other modules. For example to the top of unrealircd.conf.

Fixed in https://github.com/unrealircd/unrealircd/commit/8d2e05f5ef5d72baa05ea9ebf6c6b58ace6d6a68

commit 8d2e05f5ef5d72baa05ea9ebf6c6b58ace6d6a68 (HEAD -> unreal50, origin/unreal50)
Author: Bram Matthys <[email protected]>
Date:   Sat May 9 11:58:26 2020 +0200

    Fix crash when combining +P with a 3rd party module, or actually
    any parameter channel mode module loaded after channeldb.
    Reported by GaMbiTo, with help from PeGaSuS, Gottem and k4be
    in https://bugs.unrealircd.org/view.php?id=5669
    
    It is not safe to call channel mode parameter functions when
    unloading modules. Makes sense I think.
    
    We now no longer write the db on rehash, which is something i
    didn't like anyway (wasted CPU cycles). The problem was that
    one could not just scratch the write db call, as otherwise if
    someone rehashes every minute would cause the db never to
    be saved. This is because on each rehash the event to write
    the db gets rescheduled to +5 minutes in the future.
    We now work around that in the same way as connthrottle does.
    Obviously it would be better to make the event system itself
    deal with this, but that is (way) too much for now.

Issue History

Date Modified Username Field Change
2020-05-08 20:33 Gottem New Issue
2020-05-08 20:33 Gottem Status new => assigned
2020-05-08 20:33 Gottem Assigned To => syzop
2020-05-08 20:34 Gottem Steps to Reproduce Updated
2020-05-08 20:34 Gottem Steps to Reproduce Updated
2020-05-08 20:58 Gottem Description Updated
2020-05-08 21:54 k4be Note Added: 0021559
2020-05-09 08:34 syzop Note Added: 0021560
2020-05-09 08:44 syzop Priority high => normal
2020-05-09 11:35 k4be Note Added: 0021561
2020-05-09 11:36 k4be Note Added: 0021562
2020-05-09 12:09 syzop Status assigned => resolved
2020-05-09 12:09 syzop Resolution open => fixed
2020-05-09 12:09 syzop Fixed in Version => 5.0.5
2020-05-09 12:09 syzop Note Added: 0021563
2020-05-09 12:11 syzop Note Edited: 0021563