This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/4977] New: SEGV in strlen() of string argument of vsnprintf call on RHEL WS3/64-bit
- From: "timp at pulsic dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: 29 Aug 2007 15:28:54 -0000
- Subject: [Bug libc/4977] New: SEGV in strlen() of string argument of vsnprintf call on RHEL WS3/64-bit
- Reply-to: sourceware-bugzilla at sourceware dot org
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.