Bug#372171: w3m: Searching causes a segfault
Ben Okopnik, le Sat 12 Jan 2008 13:38:25 -0500, a écrit : > > I've run this through gdb with handle SIGPIPE nopass, and then I > > wouldn't get the segfault. Digging a bit in the SIGPIPE handler showed > > me that it calls init_migemo(), which itself calls fclose(), which > > is not safe since that function is not in the list of signal-safe > > functions. I commented these fclose() calls, and now I can't reproduce > > the bug any more. I'll keep that "fixed" version of w3m for some more > > long-term testing, but I really think the problem is here: I guess that > > fclose() frees something, so that it may corrupt the heap, thus the > > segfault on the next malloc (which happens to be due to searching the > > page). So the solution is probably to have the signal handler just set > > a variable and move the call to init_migemo into the main stream of > > instruction. > > I'd wonder what's going to be left open as a result of those two > "fclose()" calls not happening. I'd hate to see you create more > problems by fixing this one. :) Sure, my patch wasn't meant to be any proper fix, but just a way to show the precise bits that poses problem. > Is there a signal-safe way of releasing those handles? No, the FILE structure is essentially a non-signal-safe structure. The only proper solution (which should probably be made upstream) is to set a volatile variable from the handler, and from the main loop detect that and call the fclose. Regards, Samuel -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Bug#372171: w3m: Searching causes a segfault
Hi, Samuel - On Sun, Jan 06, 2008 at 03:13:46PM +, Samuel Thibault wrote: > Hello, > > I've dug a bit, since I've got an administration website which allows me > to reproduce the bug quite reliably. > > Benjamin A. Okopnik, le Mon 03 Jul 2006 11:26:34 -0400, a écrit : > > ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo > > ...}) = 0 > > rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 > > pipe([5, 7])= 0 > > pipe([9, 10]) = 0 > > clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, > > child_tidptr=0xb7bd0928) = 4518 > > --- SIGCHLD (Child exited) @ 0 (0) --- > > waitpid(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 127}], WNOHANG) = 4518 > > waitpid(-1, 0xbfa3e120, WNOHANG)= -1 ECHILD (No child processes) > > rt_sigaction(SIGCHLD, {0x804ba60, [], SA_RESTART}, {0x804ba60, [], > > SA_RESTART}, 8) = 0 > > sigreturn() = ? (mask now []) > > close(7)= 0 > > fcntl64(5, F_GETFL) = 0 (flags O_RDONLY) > > fstat64(5, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 > > mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > > 0xb7f26000 > > _llseek(5, 0, 0xbfa3e33c, SEEK_CUR) = -1 ESPIPE (Illegal seek) > > close(9)= 0 > > fcntl64(10, F_GETFL)= 0x1 (flags O_WRONLY) > > fstat64(10, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 > > mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > > 0xb7f25000 > > _llseek(10, 0, 0xbfa3e33c, SEEK_CUR)= -1 ESPIPE (Illegal seek) > > write(10, "foo\n", 4) = -1 EPIPE (Broken pipe) > > --- SIGPIPE (Broken pipe) @ 0 (0) --- > > close(5)= 0 > > munmap(0xb7f26000, 4096)= 0 > > write(10, "foo\n", 4) = -1 EPIPE (Broken pipe) > > close(10) = 0 > > munmap(0xb7f25000, 4096)= 0 > > kill(4518, SIGKILL) = -1 ESRCH (No such process) > > rt_sigaction(SIGPIPE, {0x804c3c0, [], SA_RESTART}, {0x804c3c0, [], > > SA_RESTART}, 8) = 0 > > sigreturn() = ? (mask now []) > > --- SIGPIPE (Broken pipe) @ 0 (0) --- > > rt_sigaction(SIGPIPE, {0x804c3c0, [], SA_RESTART}, {0x804c3c0, [], > > SA_RESTART}, 8) = 0 > > sigreturn() = ? (mask now []) > > --- SIGSEGV (Segmentation fault) @ 0 (0) --- > > +++ killed by SIGSEGV +++ > > Note that at this point the segfault happens in malloc called by putenv > (which itself is called by the / command). > > I've run this through gdb with handle SIGPIPE nopass, and then I > wouldn't get the segfault. Digging a bit in the SIGPIPE handler showed > me that it calls init_migemo(), which itself calls fclose(), which > is not safe since that function is not in the list of signal-safe > functions. I commented these fclose() calls, and now I can't reproduce > the bug any more. I'll keep that "fixed" version of w3m for some more > long-term testing, but I really think the problem is here: I guess that > fclose() frees something, so that it may corrupt the heap, thus the > segfault on the next malloc (which happens to be due to searching the > page). So the solution is probably to have the signal handler just set > a variable and move the call to init_migemo into the main stream of > instruction. I'd wonder what's going to be left open as a result of those two "fclose()" calls not happening. Is there a signal-safe way of releasing those handles? I'd hate to see you create more problems by fixing this one. :) Regards, -- * Ben Okopnik * Editor-in-Chief, Linux Gazette * http://LinuxGazette.NET *
Bug#372171: w3m: Searching causes a segfault
Hello, I've dug a bit, since I've got an administration website which allows me to reproduce the bug quite reliably. Benjamin A. Okopnik, le Mon 03 Jul 2006 11:26:34 -0400, a écrit : > ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo > ...}) = 0 > rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 > pipe([5, 7])= 0 > pipe([9, 10]) = 0 > clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, > child_tidptr=0xb7bd0928) = 4518 > --- SIGCHLD (Child exited) @ 0 (0) --- > waitpid(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 127}], WNOHANG) = 4518 > waitpid(-1, 0xbfa3e120, WNOHANG)= -1 ECHILD (No child processes) > rt_sigaction(SIGCHLD, {0x804ba60, [], SA_RESTART}, {0x804ba60, [], > SA_RESTART}, 8) = 0 > sigreturn() = ? (mask now []) > close(7)= 0 > fcntl64(5, F_GETFL) = 0 (flags O_RDONLY) > fstat64(5, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 > mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > 0xb7f26000 > _llseek(5, 0, 0xbfa3e33c, SEEK_CUR) = -1 ESPIPE (Illegal seek) > close(9)= 0 > fcntl64(10, F_GETFL)= 0x1 (flags O_WRONLY) > fstat64(10, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0 > mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = > 0xb7f25000 > _llseek(10, 0, 0xbfa3e33c, SEEK_CUR)= -1 ESPIPE (Illegal seek) > write(10, "foo\n", 4) = -1 EPIPE (Broken pipe) > --- SIGPIPE (Broken pipe) @ 0 (0) --- > close(5)= 0 > munmap(0xb7f26000, 4096)= 0 > write(10, "foo\n", 4) = -1 EPIPE (Broken pipe) > close(10) = 0 > munmap(0xb7f25000, 4096)= 0 > kill(4518, SIGKILL) = -1 ESRCH (No such process) > rt_sigaction(SIGPIPE, {0x804c3c0, [], SA_RESTART}, {0x804c3c0, [], > SA_RESTART}, 8) = 0 > sigreturn() = ? (mask now []) > --- SIGPIPE (Broken pipe) @ 0 (0) --- > rt_sigaction(SIGPIPE, {0x804c3c0, [], SA_RESTART}, {0x804c3c0, [], > SA_RESTART}, 8) = 0 > sigreturn() = ? (mask now []) > --- SIGSEGV (Segmentation fault) @ 0 (0) --- > +++ killed by SIGSEGV +++ Note that at this point the segfault happens in malloc called by putenv (which itself is called by the / command). I've run this through gdb with handle SIGPIPE nopass, and then I wouldn't get the segfault. Digging a bit in the SIGPIPE handler showed me that it calls init_migemo(), which itself calls fclose(), which is not safe since that function is not in the list of signal-safe functions. I commented these fclose() calls, and now I can't reproduce the bug any more. I'll keep that "fixed" version of w3m for some more long-term testing, but I really think the problem is here: I guess that fclose() frees something, so that it may corrupt the heap, thus the segfault on the next malloc (which happens to be due to searching the page). So the solution is probably to have the signal handler just set a variable and move the call to init_migemo into the main stream of instruction. Samuel -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]
Bug#372171: w3m: Searching causes a segfault
Package: w3m Version: 0.5.1-4 Followup-For: Bug #372171 w3m segfaults (about 70% of the time, based on my informal testing) when searching either forward (/) or in reverse (?). Like the previous reporter, I'm marking this one grave for the same reasons: it's my primary means of navigation within long pages, and I believe that this is true for most users as well. Relevant part of an strace dump (I'm opening a file, "foo.html", that has no content beyond the basic HTML structure): stat64("/tmp/foo.html", {st_mode=S_IFREG|0644, st_size=60, ...}) = 0 open("/tmp/foo.html", O_RDONLY) = 5 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 rt_sigaction(SIGINT, {0x8058ef0, [], SA_RESTART}, {0x8091640, [], SA_RESTART}, 8) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost -isig -icanon -echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost -isig -icanon -echo ...}) = 0 ioctl(3, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon -echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon -echo ...}) = 0 rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0 rt_sigaction(SIGINT, {0x8058ef0, [], SA_RESTART}, {0x8058ef0, [], SA_RESTART}, 8) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon -echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon -echo ...}) = 0 ioctl(3, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 ioctl(3, SNDCTL_TMR_START or TCSETS, {B38400 opost isig icanon -echo ...}) = 0 ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon -echo ...}) = 0 read(5, "\nhttp://linuxgazette.net * -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (990, 'unstable'), (500, 'testing') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.16.1 Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Versions of packages w3m depends on: ii libc6 2.3.6-15 GNU C Library: Shared libraries ii libgc1c2 1:6.7-1conservative garbage collector for ii libgpmg1 1.19.6-22 General Purpose Mouse - shared lib ii libncurses5 5.5-2 Shared libraries for terminal hand ii libssl0.9.7 0.9.7i-1 SSL shared libraries ii zlib1g1:1.2.3-11 compression library - runtime Versions of packages w3m recommends: ii ca-certificates 20050804 Common CA Certificates PEM files -- no debconf information -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]