Package: w3m
Version: 0.5.3-16
Severity: important
Tags: patch

Debian has a patch to w3m, 080_gc72.patch, which appears to attempt to
fix w3m's behavior for wrapping the warning handler in versions >= 7.2
of the garbage collector, but instead breaks it very severely.

Specifically, the wrapping function wrap_GC_warn_proc() now calls
GC_get_warn_proc() to obtain the "underlying" GC_warn_proc to call, but
by that point the value returned is guaranteed to be the calling
function itself, wrap_GC_warn_proc. Thus, if built with
GC_VERSION_MAJOR >= 7 && GC_VERSION_MINOR >= 2, the patch guarantees
that an infinite recursion will take place, chewing through the stack
space until it overflows, usually visible to the user as a segmentation
violation.

Reproducing this issue is tricky, I was not able to achieve 100%
reproducibility, but it was definitely over 50% when I ran it in a
32-bit i386 chroot. I did not produce it at all on the 64-bit amd64 I
normally use. If you know of a reliable way to exercise the GC's warning
mechanisms, then you'll reliably produce this fault as well.

Regardless, a quick look at the patch will confirm that it is in fact
setting the GC's warning proc to wrap_GC_warn_proc(), and then
wrap_GC_warn_proc() itself calls that function to fetch it.

The patch in question has an associated changelog entry that claims they
got it from Gentoo, so they may be affected as well. Upstream is not
affected, because it's a Debian- (or Gentoo-?) origin change.

Will attach a proposed replacement for 080_gc72.patch shortly.

It's likely that other bugs against w3m reporting segfaults are
duplicates of this one. The ones I found didn't seem to include enough
information to determine that, though, which is why I'm filing a new
one. But if this fix is approved, it'd probably be well to confirm
whether it fixes the other reported segfaults.

-mjc
Description: Patch from Gentoo to support Boehm GC 7.2
Origin: http://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/www-client/w3m/files/w3m-0.5.2-gc72.patch?revision=1.1&view=markup

Index: w3m-0.5.3/main.c
===================================================================
--- w3m-0.5.3.orig/main.c	2014-08-21 12:22:32.000000000 -0700
+++ w3m-0.5.3/main.c	2014-08-21 12:22:52.419420062 -0700
@@ -845,7 +845,12 @@ main(int argc, char **argv, char **envp)
     mySignal(SIGPIPE, SigPipe);
 #endif
 
+#if GC_VERSION_MAJOR >= 7 && GC_VERSION_MINOR >= 2
+    orig_GC_warn_proc = GC_get_warn_proc();
+    GC_set_warn_proc(wrap_GC_warn_proc);
+#else
     orig_GC_warn_proc = GC_set_warn_proc(wrap_GC_warn_proc);
+#endif
     err_msg = Strnew();
     if (load_argc == 0) {
 	/* no URL specified */

Reply via email to