Hi Ray,

Ray Lai <r...@raylai.com> writes:
> 
> (terminal 1)
> $ ii
> 
> (terminal 2)
> $ echo '/j #test123' >> ~/irc/irc.freenode.net/in
> $ echo '/l #test123' >> ~/irc/irc.freenode.net/'#test123'/in
> 
> (terminal 1)
> Bus error (core dumped) 
> $ egdb ./ii ~/ii.core
> GNU gdb (GDB) 7.11
> Copyright (C) 2016 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-unknown-openbsd6.0".
> Type "show configuration" for configuration details.
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>.
> Find the GDB manual and other documentation resources online at:
> <http://www.gnu.org/software/gdb/documentation/>.
> For help, type "help".
> Type "apropos word" to search for commands related to "word"...
> Reading symbols from ./ii...done.
> [New process 99191]
> Core was generated by `ii'.
> Program terminated with signal SIGBUS, Bus error.
> #0  run () at ii.c:479
> 479                           if(FD_ISSET(c->fd, &rd))
> (gdb) frame 0
> #0  run () at ii.c:479
> 479                           if(FD_ISSET(c->fd, &rd))
> (gdb) print c
> $1 = <optimized out>
> (gdb) print c->fd
> value has been optimized out
> (gdb) print rd
> $2 = {fds_bits = {32, 0 <repeats 31 times>}}
> (gdb) print channels
> $3 = (Channel *) 0x6368a267f40
> (gdb) print *channels
> $4 = {fd = 4, name = 0x637221ee350 "", next = 0x0}
> (gdb) 
> 
> ii.c:
>       for(;;) {
>               FD_ZERO(&rd);
>               maxfd = irc->irc;
>               FD_SET(irc->irc, &rd);
>               for(c = channels; c; c = c->next) {
>                       if(maxfd < c->fd)
>                               maxfd = c->fd;
>                       FD_SET(c->fd, &rd);
>               }
> 
>               tv.tv_sec = 120;
>               tv.tv_usec = 0;
>               r = select(maxfd + 1, &rd, 0, 0, &tv);
>               if(r < 0) {
>                       if(errno == EINTR)
>                               continue;
>                       perror("ii: error on select()");
>                       exit(EXIT_FAILURE);
>               } else if(r == 0) {
>                       if(time(NULL) - last_response >= PING_TIMEOUT) {
>                               print_out(NULL, "-!- ii shutting down: ping 
> timeout");
>                               exit(EXIT_FAILURE);
>                       }
>                       WRITE(irc, ping_msg, strlen(ping_msg));
>                       continue;
>               }
>               if(FD_ISSET(irc->irc, &rd)) {
>                       handle_server_output();
>                       last_response = time(NULL);
>               }
>               for(c = channels; c; c = c->next)
> /*479*/                       if(FD_ISSET(c->fd, &rd))
>                               handle_channels_input(c);
>       }
> 

Looks like there's an use after freeing in main loop
Attached diff should fix it. Could you try?
Thanks,

Index: patch-ii_c
===================================================================
RCS file: patch-ii_c
diff -N patch-ii_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patch-ii_c  4 Jun 2016 18:50:57 -0000
@@ -0,0 +1,28 @@
+$OpenBSD$
+
+# 
http://git.suckless.org/ii/commit/?id=f79e2f09534d92a6fe4e062b06449a925fef1c41
+
+--- ii.c.orig  Sat Jan  5 10:15:13 2013
++++ ii.c       Sat Jun  4 15:39:10 2016
+@@ -410,7 +410,7 @@ static void handle_server_output() {
+ }
+ 
+ static void run() {
+-      Channel *c;
++      Channel *c, *n;
+       int r, maxfd;
+       fd_set rd;
+       struct timeval tv;
+@@ -447,9 +447,11 @@ static void run() {
+                       handle_server_output();
+                       last_response = time(NULL);
+               }
+-              for(c = channels; c; c = c->next)
++              for(c = channels; c; c = n) {
++                      n = c->next;
+                       if(FD_ISSET(c->fd, &rd))
+                               handle_channels_input(c);
++              }
+       }
+ }
+ 

Reply via email to