From: Amos Jeffries Date: Mon, 28 Apr 2008 14:01:46 +0000 (-0600) Subject: Import strnstr from FreeBSD sources. X-Git-Tag: SQUID_3_0_STABLE5~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=64ecfefbe82e6ee1b7d81dcc7157ee7c8f999fcd;p=thirdparty%2Fsquid.git Import strnstr from FreeBSD sources. Needed for some string-safe operations. strnstr() is not provided on all OS (Linux with gcc 3.x for one). And some OS are known to bundle an unsafe version (MacOS X 10.4 has a buffer overrun) So code should use the function named squid_strnstr() and auto-tools will test to see if the OS provided version is usable. --- diff --git a/configure.in b/configure.in index 56104443c5..1abf2aa172 100644 --- a/configure.in +++ b/configure.in @@ -2666,6 +2666,34 @@ if test "$ac_cv_func_setresuid" = "yes" ; then AC_DEFINE(HAVE_SETRESUID,1,[Yay! Another Linux brokenness. Its not good enough to know that setresuid() exists, because RedHat 5.0 declare setresuid() but doesn't implement it.]) fi +dnl Yay! This one is a MacOSX brokenness. Its not good enough +dnl to know that strnstr() exists, because MacOSX 10.4 have a bad +dnl copy that crashes with a buffer over-run! +dnl +AC_CACHE_CHECK(if strnstr is well implemented, ac_cv_func_strnstr, + AC_TRY_RUN([ +#include +#include +#include + // we expect this to succeed, or crash on over-run. + // if it passes otherwise we may need a better check. +int main(int argc, char **argv) +{ + int size = 20; + char *str = malloc(size); + memset(str, 'x', size); + strnstr(str, "fubar", size); + return 0; +} + ],ac_cv_func_strnstr="yes",ac_cv_func_strnstr="no") +) +if test "$ac_cv_func_strnstr" = "yes" ; then + AC_DEFINE(HAVE_STRNSTR,1,[Yay! We have a working strnstr!]) +else + AC_DEFINE(HAVE_STRNSTR,0,[Yay! A MacOS X brokenness. Its not good enough to know that strnstr() exists, because MacOSX 10.4 and earlier may have a buffer overrun.]) +fi + + AM_CONDITIONAL(NEED_OWN_STRSEP, false) if test "$ac_cv_func_strsep" = "no" ; then AM_CONDITIONAL(NEED_OWN_STRSEP, true) diff --git a/include/config.h b/include/config.h index a72ec50b5e..9c2b2479cd 100644 --- a/include/config.h +++ b/include/config.h @@ -461,4 +461,10 @@ typedef union { #define RUNNING_ON_VALGRIND 0 #endif /* WITH_VALGRIND */ + +/* + * strnstr() is needed. The OS may not provide a working copy. + */ +#include "strnstr.h" + #endif /* SQUID_CONFIG_H */ diff --git a/include/strnstr.h b/include/strnstr.h new file mode 100644 index 0000000000..bb3dc01ffc --- /dev/null +++ b/include/strnstr.h @@ -0,0 +1,16 @@ +/* + * Squid VCS $Id$ + */ +#include "config.h" + +#if HAVE_STRNSTR + +/* Is strnstr exists and is usablewe do so. */ +#define squid_strnstr(a,b,c) strnstr(a,b,c) + +#else /* not HAVE_STRNSTR */ + +/* If its not usable we have our own copy imported from FreeBSD */ +const char * squid_strnstr(const char *s, const char *find, size_t slen); + +#endif /* HAVE_STRNSTR*/ diff --git a/lib/Makefile.am b/lib/Makefile.am index 04e6125178..0ee91c1eb8 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -68,6 +68,8 @@ libmiscutil_a_SOURCES = \ safe_inet_addr.c \ $(SNPRINTFSOURCE) \ Splay.cc \ + strnstr.h \ + strnstr.cc \ $(STRSEPSOURCE) \ $(STRTOLLSOURCE) \ stub_memaccount.c \ diff --git a/lib/strnstr.cc b/lib/strnstr.cc new file mode 100644 index 0000000000..1758a48675 --- /dev/null +++ b/lib/strnstr.cc @@ -0,0 +1,100 @@ +#ifndef _SQUID_COMPAT_STRNSTR_C_ +#define _SQUID_COMPAT_STRNSTR_C_ +/* + * Shamelessly duplicated from the FreeBSD public sources + * for use by the Squid Project under GNU Public License. + * + * Update/Maintenance History: + * + * 26-Apr-2008 : Copied from FreeBSD via OpenGrok + * - added protection around libray headers + * - added squid_ prefix for uniqueness + * so we can use it where OS copy is broken. + * + * Squid VCS $Id$ + * + * Original License and code follows. + */ + +#include "config.h" +#include "strnstr.h" + +#if !HAVE_STRNSTR + +/*- + * Copyright (c) 2001 Mike Barcroft + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)strstr.c 8.1 (Berkeley) 6/4/93 + * $FreeBSD: src/lib/libc/string/strnstr.c,v 1.2.2.1 2001/12/09 06:50:03 mike Exp $ + * $DragonFly: src/lib/libc/string/strnstr.c,v 1.4 2006/03/20 17:24:20 dillon Exp $ + */ + +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_STRING_H +#include +#endif + +/* + * Find the first occurrence of find in s, where the search is limited to the + * first slen characters of s. + */ +const char * +squid_strnstr(const char *s, const char *find, size_t slen) +{ + char c, sc; + size_t len; + + if ((c = *find++) != '\0') { + len = strlen(find); + do { + do { + if (slen < 1 || (sc = *s) == '\0') + return (NULL); + --slen; + ++s; + } while (sc != c); + if (len > slen) + return (NULL); + } while (strncmp(s, find, len) != 0); + s--; + } + return s; +} + +#endif /* !HAVE_STRNSTR */ +#endif /* _SQUID_COMPAT_STRNSTR_C_ */ diff --git a/src/client_side.cc b/src/client_side.cc index 37344a9590..cdf7a2b301 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -55,6 +55,7 @@ * stream calls occur. Then we simply read as normal. */ +#include "config.h" #include "squid.h" #include "client_side.h" #include "clientStream.h" @@ -1923,7 +1924,7 @@ parseHttpRequest(ConnStateData::Pointer & conn, HttpParser *hp, method_t * metho * Check that the headers don't have double-CR. * NP: strnstr is required so we don't search any possible binary body blobs. */ - if ( strnstr(req_hdr, "\r\r\n", req_sz) ) { + if ( squid_strnstr(req_hdr, "\r\r\n", req_sz) ) { debugs(33, 1, "WARNING: suspicious HTTP request contains double CR"); xfree(url); return parseHttpRequestAbort(conn, "error:double-CR");