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]

Reply via email to