#372171 w3m: searching without migemo causes segfault

Package:
w3m
Source:
w3m
Description:
WWW browsable pager with excellent tables/frames support
Submitter:
Date:
2011-11-11 01:42:06 UTC
Severity:
normal
#372171#5
Date:
2006-06-08 16:48:23 UTC
From:
To:
Searching on any page with either "/" or "C-s" causes a segfault after entering
the string to search for and hitting RET.

I can't pinpoint exactly when, but I've been using w3m on this unstable system
for years, and this has only started happening in the last month or two.

It might matter that I'm using w3m under GNU Screen.

I'm marking this grave because searching is probably the prime method of page
navigation for most people in a text browser. It is for me.

#372171#10
Date:
2006-06-08 17:15:44 UTC
From:
To:
I have no idea why, but moving my ~/.w3m directory out of the way and
restarting w3m has solved the problem.

#372171#19
Date:
2006-07-03 15:26:34 UTC
From:
To:
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, "<html>\n<head><title></title></he"..., 8192) = 60
read(5, "", 8192)                       = 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_sigaction(SIGINT, {0x8058ef0, [], SA_RESTART}, {0x8058ef0, [], SA_RESTART}, 8) = 0
rt_sigaction(SIGINT, {SIG_IGN}, {0x8058ef0, [], SA_RESTART}, 8) = 0
close(5)                                = 0
rt_sigaction(SIGINT, {0x8058ef0, [], SA_RESTART}, {SIG_IGN}, 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
rt_sigaction(SIGINT, {0x8091640, [], SA_RESTART}, {0x8058ef0, [], SA_RESTART}, 8) = 0
write(3, "\33[?1049h\33[H\33[2J\33[41;1H\33[7m\342\211\252 \342\206"..., 69) = 69
stat64("/dev/vc/0", 0xbfa3e29c)         = -1 ENOENT (No such file or directory)
stat64("/dev/tty0", {st_mode=S_IFCHR|0600, st_rdev=makedev(4, 0), ...}) = 0
fstat64(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f27000
write(1, "\33[?1001s", 8)               = 8
write(1, "\33[?1000h", 8)               = 8
write(1, "\33[?1000l", 8)               = 8
write(1, "\33[?1001r", 8)               = 8
rt_sigaction(SIGTSTP, {SIG_DFL}, NULL, 8) = 0
rt_sigaction(SIGWINCH, {SIG_DFL}, NULL, 8) = 0
close(-1)                               = -1 EBADF (Bad file descriptor)
write(3, "\33[?1001s\33[?1000h", 16)    = 16
rt_sigaction(SIGWINCH, {0x804c3a0, [], SA_RESTART}, {SIG_DFL}, 8) = 0
read(3, "/", 1)                         = 1
rt_sigaction(SIGWINCH, {0x804c340, [], SA_RESTART}, {0x804c3a0, [], SA_RESTART}, 8) = 0
write(3, "\33[?1000l\33[?1001r", 16)    = 16
brk(0x824a000)                          = 0x824a000
write(3, "\33[41;10H\33[K\33[41;1HForward: \33[41;"..., 35) = 35
read(3, "f", 1)                         = 1
write(3, "\33[41;10Hf\33[41;11H", 17)   = 17
read(3, "o", 1)                         = 1
write(3, "\33[41;11Ho\33[41;12H", 17)   = 17
read(3, "o", 1)                         = 1
write(3, "\33[41;12Ho\33[41;13H", 17)   = 17
read(3, "\n", 1)                        = 1
write(3, "\33[41;1H", 7)                = 7
rt_sigaction(SIGINT, {0x804c320, [], 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
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 +++
------------------------------------------------------------------------


Regards,
* Ben Okopnik * Editor-in-Chief, Linux Gazette * http://linuxgazette.net *

#372171#24
Date:
2007-08-01 18:37:21 UTC
From:
To:
I also sometimes experience segfaults after a search and got a core
dump, available on

http://dept-info.labri.fr/~thibault/tmp/core

and I've put my gdb-enabled binary on

http://dept-info.labri.fr/~thibault/tmp/w3m

The backtrace is

(gdb) bt
#0  0x414cabf2 in mallopt () from /lib/i686/cmov/libc.so.6
#1  0x414cc94e in malloc () from /lib/i686/cmov/libc.so.6
#2  0x4153247c in tsearch () from /lib/i686/cmov/libc.so.6
#3  0x4148dba0 in unsetenv () from /lib/i686/cmov/libc.so.6
#4  0x4148dc42 in setenv () from /lib/i686/cmov/libc.so.6
#5  0x0808dfa0 in set_environ (var=0x80cfb2e "W3M_CURRENT_WORD", value=0x83cec98 "brlapi") at local.c:206
#6  0x08059f4c in set_buffer_environ (buf=0x8233c60) at main.c:5609
#7  0x0804f1fe in main (argc=2, argv=0xbffda164, envp=0xbffda170) at main.c:1135

Which seems to point out either a bogus environment variable use (the
string returned by getenv() shouldn't ever be modified, maybe a "const"
qualifier would help tracking those) or a memory corruption (way harder
to track).

Samuel

#372171#29
Date:
2008-01-06 15:13:46 UTC
From:
To:
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 :

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

#372171#34
Date:
2008-01-12 18:38:25 UTC
From:
To:
Hi, Samuel -

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,

#372171#39
Date:
2008-01-12 18:44:05 UTC
From:
To:
Ben Okopnik, le Sat 12 Jan 2008 13:38:25 -0500, a écrit :

Sure, my patch wasn't meant to be any proper fix, but just a way to show
the precise bits that poses problem.

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

#372171#48
Date:
2010-07-20 16:01:24 UTC
From:
To:
forcemerge 372171 475199 532921
retitle 372171 w3m: searching without migemo causes segfault
thanks

#372171#57
Date:
2010-08-12 03:14:45 UTC
From:
To:
tags 372171 + help
thanks

There is another reason that w3m SEGV without migemo.
Simply uninstalling migemo, w3m does not SEGV on my environment.
Upstream maintainer also says unreproducible.
So, I need more info for fixing this bug.

#372171#64
Date:
2011-11-11 01:38:38 UTC
From:
To:
tags 372171 unreproducible moreinfo
severity 372171 normal
thanks