diff -u -r -N squid-3.1.21/ChangeLog squid-3.1.22/ChangeLog --- squid-3.1.21/ChangeLog 2012-09-24 02:01:02.000000000 +1200 +++ squid-3.1.22/ChangeLog 2012-12-02 23:02:17.000000000 +1300 @@ -1,3 +1,11 @@ +Changes to squid-3.1.22 (03 Dec 2012): + + - Bug 3685: Squid hangs in Delay Pools ClassCBucket::update + - Bug 3659: read_timeout problem with HTTPS + - Bug 3654: Fix IPv6 enabled squidclient + - Bug 3189: AIO thread race on pipe() initialization + - cachemgr.cgi: Memory Leaks and DoS Vulnerability + Changes to squid-3.1.21 (23 Sep 2012): - Bug 3622: peerClearRRStart scheduling multiple events diff -u -r -N squid-3.1.21/configure squid-3.1.22/configure --- squid-3.1.21/configure 2012-09-24 02:02:46.000000000 +1200 +++ squid-3.1.22/configure 2012-12-02 23:03:29.000000000 +1300 @@ -1,7 +1,7 @@ #! /bin/sh # From configure.ac Revision. # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.1.21. +# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.1.22. # # Report bugs to . # @@ -575,8 +575,8 @@ # Identity of this package. PACKAGE_NAME='Squid Web Proxy' PACKAGE_TARNAME='squid' -PACKAGE_VERSION='3.1.21' -PACKAGE_STRING='Squid Web Proxy 3.1.21' +PACKAGE_VERSION='3.1.22' +PACKAGE_STRING='Squid Web Proxy 3.1.22' PACKAGE_BUGREPORT='http://www.squid-cache.org/bugs/' PACKAGE_URL='' @@ -1540,7 +1540,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures Squid Web Proxy 3.1.21 to adapt to many kinds of systems. +\`configure' configures Squid Web Proxy 3.1.22 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1610,7 +1610,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of Squid Web Proxy 3.1.21:";; + short | recursive ) echo "Configuration of Squid Web Proxy 3.1.22:";; esac cat <<\_ACEOF @@ -1941,7 +1941,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -Squid Web Proxy configure 3.1.21 +Squid Web Proxy configure 3.1.22 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2952,7 +2952,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by Squid Web Proxy $as_me 3.1.21, which was +It was created by Squid Web Proxy $as_me 3.1.22, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -3771,7 +3771,7 @@ # Define the identity of the package. PACKAGE='squid' - VERSION='3.1.21' + VERSION='3.1.22' cat >>confdefs.h <<_ACEOF @@ -28243,7 +28243,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by Squid Web Proxy $as_me 3.1.21, which was +This file was extended by Squid Web Proxy $as_me 3.1.22, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -28309,7 +28309,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -Squid Web Proxy config.status 3.1.21 +Squid Web Proxy config.status 3.1.22 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff -u -r -N squid-3.1.21/configure.ac squid-3.1.22/configure.ac --- squid-3.1.21/configure.ac 2012-09-24 02:02:46.000000000 +1200 +++ squid-3.1.22/configure.ac 2012-12-02 23:03:29.000000000 +1300 @@ -2,7 +2,7 @@ dnl dnl $Id$ dnl -AC_INIT([Squid Web Proxy],[3.1.21],[http://www.squid-cache.org/bugs/],[squid]) +AC_INIT([Squid Web Proxy],[3.1.22],[http://www.squid-cache.org/bugs/],[squid]) AC_PREREQ(2.61) AC_CONFIG_HEADERS([include/autoconf.h]) AC_CONFIG_AUX_DIR(cfgaux) diff -u -r -N squid-3.1.21/include/version.h squid-3.1.22/include/version.h --- squid-3.1.21/include/version.h 2012-09-24 02:02:46.000000000 +1200 +++ squid-3.1.22/include/version.h 2012-12-02 23:03:29.000000000 +1300 @@ -9,7 +9,7 @@ */ #ifndef SQUID_RELEASE_TIME -#define SQUID_RELEASE_TIME 1348408851 +#define SQUID_RELEASE_TIME 1354442534 #endif #ifndef APP_SHORTNAME diff -u -r -N squid-3.1.21/RELEASENOTES.html squid-3.1.22/RELEASENOTES.html --- squid-3.1.21/RELEASENOTES.html 2012-09-24 02:25:29.000000000 +1200 +++ squid-3.1.22/RELEASENOTES.html 2012-12-02 23:23:45.000000000 +1300 @@ -2,10 +2,10 @@ - Squid 3.1.21 release notes + Squid 3.1.22 release notes -

Squid 3.1.21 release notes

+

Squid 3.1.22 release notes

Squid Developers


@@ -71,7 +71,7 @@

1. Notice

-

The Squid Team are pleased to announce the release of Squid-3.1.21

+

The Squid Team are pleased to announce the release of Squid-3.1.22

This new release is available for download from http://www.squid-cache.org/Versions/v3/3.1/ or the mirrors.

diff -u -r -N squid-3.1.21/src/comm.cc squid-3.1.22/src/comm.cc --- squid-3.1.21/src/comm.cc 2012-09-24 02:01:02.000000000 +1200 +++ squid-3.1.22/src/comm.cc 2012-12-02 23:02:17.000000000 +1300 @@ -2362,19 +2362,23 @@ fdc_table[fd].acceptNext(); } -void CommIO::Initialise() +void +CommIO::Initialize() { + if (CommIO::Initialized) + return; + /* Initialize done pipe signal */ int DonePipe[2]; if (pipe(DonePipe)) {} DoneFD = DonePipe[1]; DoneReadFD = DonePipe[0]; - fd_open(DoneReadFD, FD_PIPE, "async-io completetion event: main"); - fd_open(DoneFD, FD_PIPE, "async-io completetion event: threads"); + fd_open(DoneReadFD, FD_PIPE, "async-io completion event: main"); + fd_open(DoneFD, FD_PIPE, "async-io completion event: threads"); commSetNonBlocking(DoneReadFD); commSetNonBlocking(DoneFD); commSetSelect(DoneReadFD, COMM_SELECT_READ, NULLFDHandler, NULL, 0); - Initialised = true; + Initialized = true; } void CommIO::NotifyIOClose() @@ -2385,10 +2389,10 @@ close(DoneReadFD); fd_close(DoneFD); fd_close(DoneReadFD); - Initialised = false; + Initialized = false; } -bool CommIO::Initialised = false; +bool CommIO::Initialized = false; bool CommIO::DoneSignalled = false; int CommIO::DoneFD = -1; int CommIO::DoneReadFD = -1; diff -u -r -N squid-3.1.21/src/CommIO.h squid-3.1.22/src/CommIO.h --- squid-3.1.21/src/CommIO.h 2012-09-24 02:01:02.000000000 +1200 +++ squid-3.1.22/src/CommIO.h 2012-12-02 23:02:17.000000000 +1300 @@ -9,25 +9,25 @@ public: static inline void NotifyIOCompleted(); static void ResetNotifications(); - static void Initialise(); + static void Initialize(); static void NotifyIOClose(); private: static void NULLFDHandler(int, void *); static void FlushPipe(); - static bool Initialised; + static bool Initialized; static bool DoneSignalled; static int DoneFD; static int DoneReadFD; }; - -/* Inline code. TODO: make structued approach to inlining */ +/* Inline code. TODO: make structured approach to inlining */ void CommIO::NotifyIOCompleted() { - if (!Initialised) - Initialise(); + if (!Initialized) { + fatalf("Disk Threads I/O pipes not initialized before first use."); + } if (!DoneSignalled) { DoneSignalled = true; diff -u -r -N squid-3.1.21/src/delay_pools.cc squid-3.1.22/src/delay_pools.cc --- squid-3.1.21/src/delay_pools.cc 2012-09-24 02:01:02.000000000 +1200 +++ squid-3.1.22/src/delay_pools.cc 2012-12-02 23:02:17.000000000 +1300 @@ -366,7 +366,7 @@ /* If we aren't active, don't try to update us ! */ assert (rate.restore_bps != -1); - for (unsigned char j = 0; j < individuals.size(); ++j) + for (unsigned int j = 0; j < individuals.size(); ++j) individuals.values[j].update (rate, incr); } diff -u -r -N squid-3.1.21/src/DiskIO/DiskThreads/aiops.cc squid-3.1.22/src/DiskIO/DiskThreads/aiops.cc --- squid-3.1.21/src/DiskIO/DiskThreads/aiops.cc 2012-09-24 02:01:02.000000000 +1200 +++ squid-3.1.22/src/DiskIO/DiskThreads/aiops.cc 2012-12-02 23:02:17.000000000 +1300 @@ -309,6 +309,10 @@ done_queue.blocked = 0; + // Initialize the thread I/O pipes before creating any threads + // see bug 3189 comment 5 about race conditions. + CommIO::Initialize(); + /* Create threads and get them to sit in their wait loop */ squidaio_thread_pool = memPoolCreate("aio_thread", sizeof(squidaio_thread_t)); diff -u -r -N squid-3.1.21/src/tests/stub_CommIO.cc squid-3.1.22/src/tests/stub_CommIO.cc --- squid-3.1.21/src/tests/stub_CommIO.cc 2012-09-24 02:01:02.000000000 +1200 +++ squid-3.1.22/src/tests/stub_CommIO.cc 2012-12-02 23:02:17.000000000 +1300 @@ -1,7 +1,7 @@ #include "squid.h" #include "CommIO.h" -bool CommIO::Initialised = false; +bool CommIO::Initialized = false; bool CommIO::DoneSignalled = false; int CommIO::DoneFD = -1; int CommIO::DoneReadFD = -1; @@ -13,7 +13,7 @@ } void -CommIO::Initialise() +CommIO::Initialize() { fatal("Not Implemented"); } diff -u -r -N squid-3.1.21/src/tunnel.cc squid-3.1.22/src/tunnel.cc --- squid-3.1.21/src/tunnel.cc 2012-09-24 02:01:02.000000000 +1200 +++ squid-3.1.22/src/tunnel.cc 2012-12-02 23:02:17.000000000 +1300 @@ -308,9 +308,14 @@ */ cbdataInternalLock(this); /* ??? should be locked by the caller... */ - /* Bump the server connection timeout on any activity */ - if (!fd_closed(server.fd())) - commSetTimeout(server.fd(), Config.Timeout.read, tunnelTimeout, this); + /* Bump the source connection timeout on any activity */ + if (!fd_closed(from.fd())) + commSetTimeout(from.fd(), Config.Timeout.read, tunnelTimeout, this); + + /* Bump the dest connection read timeout on any activity */ + /* see Bug 3659: tunnels can be weird, with very long one-way transfers */ + if (!fd_closed(to.fd())) + commSetTimeout(to.fd(), Config.Timeout.read, tunnelTimeout, this); if (errcode) from.error (xerrno); diff -u -r -N squid-3.1.21/tools/cachemgr.cc squid-3.1.22/tools/cachemgr.cc --- squid-3.1.21/tools/cachemgr.cc 2012-09-24 02:01:02.000000000 +1200 +++ squid-3.1.22/tools/cachemgr.cc 2012-12-02 23:02:17.000000000 +1300 @@ -586,12 +586,15 @@ if ((p = strchr(x, '\n'))) *p = '\0'; action = xstrtok(&x, '\t'); + if (!action) { + xfree(buf); + return ""; + } description = xstrtok(&x, '\t'); if (!description) description = action; - if (!action) - return ""; snprintf(html, sizeof(html), " %s", menu_url(req, action), description); + xfree(buf); return html; } @@ -820,7 +823,7 @@ } if (!check_target_acl(req->hostname, req->port)) { - snprintf(buf, 1024, "target %s:%d not allowed in cachemgr.conf\n", req->hostname, req->port); + snprintf(buf, sizeof(buf), "target %s:%d not allowed in cachemgr.conf\n", req->hostname, req->port); error_html(buf); return 1; } @@ -832,7 +835,7 @@ } else if ((S = req->hostname)) (void) 0; else { - snprintf(buf, 1024, "Unknown host: %s\n", req->hostname); + snprintf(buf, sizeof(buf), "Unknown host: %s\n", req->hostname); error_html(buf); return 1; } @@ -846,17 +849,19 @@ #else if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { #endif - snprintf(buf, 1024, "socket: %s\n", xstrerror()); + snprintf(buf, sizeof(buf), "socket: %s\n", xstrerror()); error_html(buf); + S.FreeAddrInfo(AI); return 1; } if (connect(s, AI->ai_addr, AI->ai_addrlen) < 0) { - snprintf(buf, 1024, "connect %s: %s\n", + snprintf(buf, sizeof(buf), "connect %s: %s\n", S.ToURL(ipbuf,MAX_IPSTRLEN), xstrerror()); error_html(buf); S.FreeAddrInfo(AI); + close(s); return 1; } @@ -917,8 +922,6 @@ read_post_request(void) { char *s; - char *buf; - int len; if ((s = getenv("REQUEST_METHOD")) == NULL) return NULL; @@ -929,15 +932,34 @@ if ((s = getenv("CONTENT_LENGTH")) == NULL) return NULL; - if ((len = atoi(s)) <= 0) + if (*s == '-') // negative length content huh? return NULL; - buf = (char *)xmalloc(len + 1); + uint64_t len; - if (fread(buf, len, 1, stdin) == 0) + char *endptr = s+ strlen(s); + if ((len = strtoll(s, &endptr, 10)) <= 0) return NULL; - buf[len] = '\0'; + // limit the input to something reasonable. + // 4KB should be enough for the GET/POST data length, but may be extended. + size_t bufLen = (len >= 4096 ? len : 4095); + char *buf = (char *)xmalloc(bufLen + 1); + + size_t readLen = fread(buf, bufLen, 1, stdin); + if (readLen == 0) { + xfree(buf); + return NULL; + } + buf[readLen] = '\0'; + len -= readLen; + + // purge the remainder of the request entity + while (len > 0) { + char temp[65535]; + readLen = fread(temp, 65535, 1, stdin); + len -= readLen; + } return buf; } @@ -1077,37 +1099,49 @@ debug(3) fprintf(stderr, "cmgr: length ok\n"); /* parse ( a lot of memory leaks, but that is cachemgr style :) */ - if ((host_name = strtok(buf, "|")) == NULL) + if ((host_name = strtok(buf, "|")) == NULL) { + xfree(buf); return; + } debug(3) fprintf(stderr, "cmgr: decoded host: '%s'\n", host_name); - if ((time_str = strtok(NULL, "|")) == NULL) + if ((time_str = strtok(NULL, "|")) == NULL) { + xfree(buf); return; + } debug(3) fprintf(stderr, "cmgr: decoded time: '%s' (now: %d)\n", time_str, (int) now); - if ((user_name = strtok(NULL, "|")) == NULL) + if ((user_name = strtok(NULL, "|")) == NULL) { + xfree(buf); return; + } debug(3) fprintf(stderr, "cmgr: decoded uname: '%s'\n", user_name); - if ((passwd = strtok(NULL, "|")) == NULL) + if ((passwd = strtok(NULL, "|")) == NULL) { + xfree(buf); return; + } debug(2) fprintf(stderr, "cmgr: decoded passwd: '%s'\n", passwd); /* verify freshness and validity */ - if (atoi(time_str) + passwd_ttl < now) + if (atoi(time_str) + passwd_ttl < now) { + xfree(buf); return; + } - if (strcasecmp(host_name, req->hostname)) + if (strcasecmp(host_name, req->hostname)) { + xfree(buf); return; + } debug(1) fprintf(stderr, "cmgr: verified auth. info.\n"); /* ok, accept */ - xfree(req->user_name); + safe_free(req->user_name); req->user_name = xstrdup(user_name); @@ -1145,6 +1179,7 @@ snprintf(&buf[stringLength], sizeof(buf) - stringLength, "Proxy-Authorization: Basic %s\r\n", str64); + xxfree(str64); return buf; } diff -u -r -N squid-3.1.21/tools/squidclient.cc squid-3.1.22/tools/squidclient.cc --- squid-3.1.21/tools/squidclient.cc 2012-09-24 02:01:02.000000000 +1200 +++ squid-3.1.22/tools/squidclient.cc 2012-12-02 23:02:17.000000000 +1300 @@ -34,6 +34,7 @@ #include "config.h" #include "ip/IpAddress.h" +#include "ip/tools.h" #include "util.h" #include "squid_types.h" @@ -206,6 +207,7 @@ pcount = 0; ping_int = 1 * 1000; + Ip::ProbeTransport(); // determine IPv4 or IPv6 capabilities before parsing. if (argc < 2) { usage(argv[0]); /* need URL */ } else if (argc >= 2) {