This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/4977] New: SEGV in strlen() of string argument of vsnprintf call on RHEL WS3/64-bit


As per summary, a call to vsnprintf such as

vsnprintf( buf, nchar, fmt, ap )

where the va_list 'ap' has a C string argument is causing a SEGV in the strlen.
Typical stack

Program received signal SIGSEGV, Segmentation fault.
0x0000002a95707290 in strlen () from /lib64/tls/libc.so.6
(gdb) bt
#0  0x0000002a95707290 in strlen () from /lib64/tls/libc.so.6
#1  0x0000002a956d45b0 in vfprintf () from /lib64/tls/libc.so.6
#2  0x0000002a956f8949 in vsnprintf () from /lib64/tls/libc.so.6

Source code for a trivial reproducible case below, compiled on (uname -a)

Linux hpopteron 2.4.21-50.ELsmp #1 SMP Tue May 8 17:10:20 EDT 2007 x86_64 x86_64
x86_64 GNU/Linux

with

gcc --std=c9x -Wall -pedantic -g -o vsn vsn.c

using

gcc (GCC) 3.2.3 20030502 (Red Hat Linux 3.2.3-59)
GNU C Library stable release version 2.3.2, by Roland McGrath et al.

Run as

./vsn "foo"

Code follows 

---------------------%<------------------------
#include <stdio.h>
#include <stdarg.h>
#include <malloc.h>

int vssprintf
(
 char **	userBufPtr,
 const char *	format,
 va_list 	ap
)
{
    if( userBufPtr )
    {
	/* see how many formatted characters there are to process,
	 * this should work even if the format is "" or equivalent
	 * eg. ( "%s", "" ) */
	int nchar = vsnprintf( NULL, 0, format, ap ) + 1;
	char * bufPtr = (char *)malloc( nchar );

	nchar = vsnprintf( bufPtr, nchar, format, ap );

	*userBufPtr = bufPtr ; 
	return( nchar );
    }
    /* IO errors in system ..printf() funtions should normally trigger the
     * return of a negative number (e.g. in ANSI / ISO C) - do the same here */
    return -1 ;
}

int ssprintf
(
 char **	userBufPtr,
 const char *	format,
 ... 
)
{
    int	nchar = -1 ;
    if( userBufPtr )
    {
	va_list	ap;

	/* Unravel the format, args, ... into a buffer */
	va_start( ap, format );

	nchar = vssprintf( userBufPtr, format, ap );

	/* Clean up */
	va_end(ap);
    }

    return( nchar );
}


int main( int argc, char *argv[] )
{
    int n = 0 ;
    if( argc > 1 )
    {
	char * buf ;
	n = ssprintf( &buf, "Hello %s !\n", argv[1] );
	fprintf( stderr, "Printed %d characters from va_list\n", n ) ;
	n = printf( "%s\n", buf ) ;
    }
    return n ;
}
---------------------%<------------------------

Under Valgrind I get the following stack

--2099-- Reading syms from
/usr/local/lib/valgrind/amd64-linux/vgpreload_memcheck.so (0x4A17000)
--2099-- REDIR: 0x40101A0 (index) redirected to 0x4A1A7E0 (index)
--2099-- REDIR: 0x4010350 (strcmp) redirected to 0x4A1AC80 (strcmp)
--2099-- REDIR: 0x4010380 (strlen) redirected to 0x4A1AA10 (strlen)
--2099-- Reading syms from /lib64/tls/libc-2.3.2.so (0x4B1D000)
--2099-- REDIR: 0x4B9B620 (rindex) redirected to 0x4A1A700 (rindex)
--2099-- REDIR: 0x4B9B280 (strlen) redirected to 0x4A1A9D0 (strlen)
--2099-- REDIR: 0x4B93540 (malloc) redirected to 0x4A18C6F (malloc)
==2099== Invalid read of size 1
==2099==    at 0x4A1A9D2: strlen (mac_replace_strmem.c:243)
==2099==    by 0x4B685AF: vfprintf (in /lib64/tls/libc-2.3.2.so)
==2099==    by 0x4B8C948: vsnprintf (in /lib64/tls/libc-2.3.2.so)
==2099==    by 0x400600: vssprintf (vsn.c:20)
==2099==    by 0x40070A: ssprintf (vsn.c:45)
==2099==    by 0x400752: main (vsn.c:61)
==2099==  Address 0x2 is not stack'd, malloc'd or (recently) free'd
==2099== 
==2099== Process terminating with default action of signal 11 (SIGSEGV)
==2099==  Access not within mapped region at address 0x2
==2099==    at 0x4A1A9D2: strlen (mac_replace_strmem.c:243)
==2099==    by 0x4B685AF: vfprintf (in /lib64/tls/libc-2.3.2.so)
==2099==    by 0x4B8C948: vsnprintf (in /lib64/tls/libc-2.3.2.so)
==2099==    by 0x400600: vssprintf (vsn.c:20)
==2099==    by 0x40070A: ssprintf (vsn.c:45)
==2099==    by 0x400752: main (vsn.c:61)
--2099-- REDIR: 0x4B93710 (free) redirected to 0x4A197E1 (free)
--2099-- REDIR: 0x4B9CEA0 (memset) redirected to 0x4A1B140 (memset)
==2099== 
==2099== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 3 from 2)
==2099== 
==2099== 1 errors in context 1 of 1:
==2099== Invalid read of size 1
==2099==    at 0x4A1A9D2: strlen (mac_replace_strmem.c:243)
==2099==    by 0x4B685AF: vfprintf (in /lib64/tls/libc-2.3.2.so)
==2099==    by 0x4B8C948: vsnprintf (in /lib64/tls/libc-2.3.2.so)
==2099==    by 0x400600: vssprintf (vsn.c:20)
==2099==    by 0x40070A: ssprintf (vsn.c:45)
==2099==    by 0x400752: main (vsn.c:61)
==2099==  Address 0x2 is not stack'd, malloc'd or (recently) free'd
--2099-- 
--2099-- supp:    1 strlen-not-intercepted-early-enough-HACK-5
--2099-- supp:    2 dl_relocate_object
==2099== 
==2099== IN SUMMARY: 1 errors from 1 contexts (suppressed: 3 from 2)
==2099== 
==2099== malloc/free: in use at exit: 13 bytes in 1 blocks.
==2099== malloc/free: 1 allocs, 0 frees, 13 bytes allocated.
==2099== 

.............

Looks like strlen() is being given duff info. Quick Google reveals similar
bug/stack seen reported under Nessus, gnash and Firefly forums this year.
Reproduced on

- SuSE 10.1 / 64-bit platform (no details)

- RHEL WS4/64
gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-3)
Linux tornado 2.6.9-42.EL #1 Tue Aug 15 09:30:48 BST 2006 x86_64 x86_64 x86_64
GNU/Linux
GNU C Library stable release version 2.3.4, by Roland McGrath et al.


Cheers
Tim

-- 
           Summary: SEGV in strlen() of string argument of vsnprintf call on
                    RHEL WS3/64-bit
           Product: glibc
           Version: unspecified
            Status: NEW
          Severity: critical
          Priority: P2
         Component: libc
        AssignedTo: drepper at redhat dot com
        ReportedBy: timp at pulsic dot com
                CC: glibc-bugs at sources dot redhat dot com


http://sourceware.org/bugzilla/show_bug.cgi?id=4977

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]