[prev in list] [next in list] [prev in thread] [next in thread] 

List:       thttpd
Subject:    [THTTPD] memmove() patch
From:       zell () zell ! best ! vwh ! net
Date:       2003-12-02 6:45:54
[Download RAW message or body]

Hello,

The following patch turns overlapping strcpy() calls into memmove().  This
prevents undefined behavior, and quiets valgrind.  To reproduce, run thttpd
under valgrind with a cgi pattern of "foo|/bar".

Ex:

[ 9 server ~/thttpd-2.24 ] valgrind ./thttpd -D -p 80 -c "foo|/bar"
==7102== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
==7102== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
==7102== Using valgrind-2.0.0, a program supervision framework for x86-linux.
==7102== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
==7102== Estimated CPU clock rate is 939 MHz
==7102== For more details, rerun with: -v
==7102==
==7102== Source and destination overlap in strcpy(0x40d08ec8, 0x40d08ec9)
==7102==    at 0x4002446F: strcpy (mac_replace_strmem.c:87)
==7102==    by 0x804CB77: httpd_initialize (in /home/zell/A/thttpd-2.24/thttpd)
==7102==    by 0x804A362: main (in /home/zell/A/thttpd-2.24/thttpd)
==7102==    by 0x4028E656: __libc_start_main (../sysdeps/generic/libc-start.c:129)
==7102==
==7102== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 3 from 1)

diff -Naur thttpd-2.24/libhttpd.c thttpd-2.24-patch/libhttpd.c
--- thttpd-2.24/libhttpd.c	Sun Oct 26 17:23:59 2003
+++ thttpd-2.24-patch/libhttpd.c	Tue Dec  2 06:36:12 2003
@@ -283,7 +283,7 @@
 	    }
 	/* Nuke any leading slashes in the cgi pattern. */
 	while ( ( cp = strstr( hs->cgi_pattern, "|/" ) ) != (char*) 0 )
-	    (void) strcpy( cp + 1, cp + 2 );
+	    (void) memmove( cp + 1, cp + 2, strlen( cp + 2 ) + 1 );
 	}
     hs->charset = strdup( charset );
     hs->p3p = strdup( p3p );
@@ -1477,7 +1477,7 @@
 	/* Remove any leading slashes. */
 	while ( rest[0] == '/' )
 	    {
-	    (void) strcpy( rest, &(rest[1]) );
+	    (void) memmove( rest, &(rest[1]), strlen( &(rest[1]) ) + 1 );
 	    --restlen;
 	    }
     r = rest;
@@ -2296,9 +2296,11 @@
 	if ( strncmp(
 		 hc->expnfilename, hc->hs->cwd, strlen( hc->hs->cwd ) ) == 0 )
 	    {
+	    int i;
+	    i = strlen( hc->hs->cwd );
 	    /* Elide the current directory. */
-	    (void) strcpy(
-		hc->expnfilename, &hc->expnfilename[strlen( hc->hs->cwd )] );
+	    (void) memmove(
+		hc->expnfilename, &hc->expnfilename[i], strlen( &hc->expnfilename[i] ) + 1 );
 	    }
 #ifdef TILDE_MAP_2
 	else if ( hc->altdir[0] != '\0' &&
@@ -2364,26 +2366,26 @@
 	{
 	for ( cp2 = cp + 2; *cp2 == '/'; ++cp2 )
 	    continue;
-	(void) strcpy( cp + 1, cp2 );
+	(void) memmove( cp + 1, cp2, strlen( cp2 ) + 1 );
 	}
 
     /* Remove leading ./ and any /./ sequences. */
     while ( strncmp( file, "./", 2 ) == 0 )
-	(void) strcpy( file, file + 2 );
+	(void) memmove( file, file + 2, strlen( file + 2 ) + 1 );
     while ( ( cp = strstr( file, "/./") ) != (char*) 0 )
-	(void) strcpy( cp, cp + 2 );
+	(void) memmove( cp, cp + 2, strlen( cp + 2 ) + 1 );
 
     /* Alternate between removing leading ../ and removing xxx/../ */
     for (;;)
 	{
 	while ( strncmp( file, "../", 3 ) == 0 )
-	    (void) strcpy( file, file + 3 );
+	    (void) memmove( file, file + 3, strlen( file + 3 ) + 1 );
 	cp = strstr( file, "/../" );
 	if ( cp == (char*) 0 )
 	    break;
 	for ( cp2 = cp - 1; cp2 >= file && *cp2 != '/'; --cp2 )
 	    continue;
-	(void) strcpy( cp2 + 1, cp + 4 );
+	(void) memmove( cp2 + 1, cp + 4, strlen( cp + 4 ) + 1 );
 	}
 
     /* Also elide any xxx/.. at the end. */
@@ -4016,7 +4018,7 @@
 	}
     else if ( IN6_IS_ADDR_V4MAPPED( &saP->sa_in6.sin6_addr ) && strncmp( str, "::ffff:", 7 ) == 0 )
 	/* Elide IPv6ish prefix for IPv4 addresses. */
-	(void) strcpy( str, &str[7] );
+	(void) memmove( str, &str[7], strlen( &str[7] ) + 1 );
 
     return str;
 
diff -Naur thttpd-2.24/thttpd.c thttpd-2.24-patch/thttpd.c
--- thttpd-2.24/thttpd.c	Tue May 13 17:14:33 2003
+++ thttpd-2.24-patch/thttpd.c	Tue Dec  2 06:30:16 2003
@@ -1305,9 +1305,9 @@
 
 	/* Nuke any leading slashes in pattern. */
 	if ( pattern[0] == '/' )
-	    (void) strcpy( pattern, &pattern[1] );
+	    (void) memmove( pattern, &pattern[1], strlen( &pattern[1] ) + 1 );
 	while ( ( cp = strstr( pattern, "|/" ) ) != (char*) 0 )
-	    (void) strcpy( cp + 1, cp + 2 );
+	    (void) memmove( cp + 1, cp + 2, strlen( cp + 2 ) + 1 );
 
 	/* Check for room in throttles. */
 	if ( numthrottles >= maxthrottles )
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic