ports/87260: devel/str uses the same va_list ap twice causing segfault

Vasil Dimov vd at datamax.bg
Tue Oct 11 16:10:17 UTC 2005


>Number:         87260
>Category:       ports
>Synopsis:       devel/str uses the same va_list ap twice causing segfault
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 11 16:10:15 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Vasil Dimov
>Release:        FreeBSD 6.0-RC1 amd64
>Organization:
DataMax
>Environment:

System: FreeBSD qlovarnika.bg.datamax 6.0-RC1 FreeBSD 6.0-RC1 #0: Mon Oct 10 17:41:04 EEST 2005     root at qlovarnika.bg.datamax:/usr/obj/usr/src/sys/QLOVARNIKA  amd64

>Description:

I discovered the following bug in devel/str port on my brand new
architecture (amd64):

* String Parsing test in `make check' fails

* Example code from str(3) "Substitute Text in a String"
  the one with str_parse(var, "s/^(.+?):(.+)$/$1-%s-$2/", &new, subst);
  causes signal 11 to be delivered

Here is the backtrace of the above str_parse() call:

Program received signal SIGSEGV, Segmentation fault.
0x000000080063fe84 in str_len (
    s=0xffffffff804617d0 <Error reading address 0xffffffff804617d0: Bad address>) at str_basic.c:43
43	    while (*t++ != NUL)
#0  0x000000080063fe84 in str_len (
    s=0xffffffff804617d0 <Error reading address 0xffffffff804617d0: Bad address>) at str_basic.c:43
#1  0x00000008006447a2 in str_vformat (vbuff=0x7fffffffe6f0, 
    fmt=0x7fffffffe7d7 "s-%{2}R", ap=0x7fffffffe920) at str_format.c:886
#2  0x0000000800642b25 in str_parse_va (string=0x400a0c "foo:bar", 
    pattern=0x400a19 "s/^(.+?):(.+)$/$1-%s-$2/", ap=0x7fffffffe920)
    at str_parse.c:588
#3  0x0000000800641cb7 in str_parse (string=0x400a0c "foo:bar", 
    pattern=0x400a19 "s/^(.+?):(.+)$/$1-%s-$2/") at str_parse.c:268
#4  0x0000000000400942 in main (argc=1, argv=0x7fffffffeaa0) at tmp.c:29

the problem is that `ap' is used twice:
on str_parse.c:567 and str_parse.c:588, the first usage "exhausts" it
and makes it unusable (the actual exhaustion with va_arg is done in
str_vformat() in str_format.c).

The bug reveals itself only on amd64, it waits in ambush on i386.

>How-To-Repeat:

# uname -m
amd64

/usr/ports/devel/str# make check

>Fix:

--- str-ap.diff begins here ---
diff -urN --exclude=CVS --exclude=README.html str/Makefile /usr/ports/devel/str/Makefile
--- str/Makefile	Tue Oct  4 08:21:23 2005
+++ /usr/ports/devel/str/Makefile	Tue Oct 11 18:00:16 2005
@@ -7,6 +7,7 @@
 
 PORTNAME=	str
 PORTVERSION=	0.9.11
+PORTREVISION=	1
 CATEGORIES=	devel
 MASTER_SITES=	${MASTER_SITE_OSSP}
 MASTER_SITE_SUBDIR=	lib/${PORTNAME}
diff -urN --exclude=CVS --exclude=README.html str/files/patch-str_parse.c.diff /usr/ports/devel/str/files/patch-str_parse.c.diff
--- str/files/patch-str_parse.c.diff	Thu Jan  1 02:00:00 1970
+++ /usr/ports/devel/str/files/patch-str_parse.c.diff	Tue Oct 11 17:56:44 2005
@@ -0,0 +1,14 @@
+--- str_parse.c.orig	Tue Oct 11 17:44:45 2005
++++ str_parse.c	Tue Oct 11 17:49:35 2005
+@@ -564,7 +564,10 @@
+         sf.data[3].p = (char *)string;
+         sf.data[4].p = cap_vec;
+         sf.data[5].i = cap_num;
+-        l = str_vformat(&sf, buf_ptr, ap);
++        /* we shall need `ap' untouched later */
++        va_list ap_temp;
++        va_copy(ap_temp, ap);
++        l = str_vformat(&sf, buf_ptr, ap_temp);
+ 
+         /* allocate output buffer */
+         if ((*cpp = (char *)malloc(l+1)) == NULL) {
--- str-ap.diff ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list