diff -u -r -N squid-3.1.18/ChangeLog squid-3.1.19/ChangeLog --- squid-3.1.18/ChangeLog 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/ChangeLog 2012-02-06 00:51:32.000000000 +1300 @@ -1,3 +1,17 @@ +Changes to squid-3.1.19 (06 Feb 2011): + + - Regression Bug 3441: part 2: Prevent further cache size corruption of swap.state + - Bug 3473: erase last uses of obsolete auth_user_hash_pointer + - Bug 3470: GCC 4.7 + - Bug 3442: assertion failed: external_acl.cc:908: ch->auth_user_request != NULL + - Bug 3441: part 1: Minimize cache size corruption by malformed swap.state + - Bug 3440: compile error in Adaptation + - Bug 3420: Request body consumption races and !theConsumer exception + - Bug 3370: external ACL sometimes skipping + - Bug 3085: Crash when parsing esi:include + - HTTP/1.1: do not add 110 and 111 Warnings to revalidated responses + - Fix SSL library dependency fixes + Changes to squid-3.1.18 (03 Dec 2011): - Regression: compile error in FTP diff -u -r -N squid-3.1.18/configure squid-3.1.19/configure --- squid-3.1.18/configure 2011-12-03 19:21:25.000000000 +1300 +++ squid-3.1.19/configure 2012-02-06 00:56:56.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.18. +# Generated by GNU Autoconf 2.68 for Squid Web Proxy 3.1.19. # # Report bugs to . # @@ -575,8 +575,8 @@ # Identity of this package. PACKAGE_NAME='Squid Web Proxy' PACKAGE_TARNAME='squid' -PACKAGE_VERSION='3.1.18' -PACKAGE_STRING='Squid Web Proxy 3.1.18' +PACKAGE_VERSION='3.1.19' +PACKAGE_STRING='Squid Web Proxy 3.1.19' 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.18 to adapt to many kinds of systems. +\`configure' configures Squid Web Proxy 3.1.19 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.18:";; + short | recursive ) echo "Configuration of Squid Web Proxy 3.1.19:";; 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.18 +Squid Web Proxy configure 3.1.19 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.18, which was +It was created by Squid Web Proxy $as_me 3.1.19, 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.18' + VERSION='3.1.19' cat >>confdefs.h <<_ACEOF @@ -28231,7 +28231,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.18, which was +This file was extended by Squid Web Proxy $as_me 3.1.19, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -28297,7 +28297,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.18 +Squid Web Proxy config.status 3.1.19 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff -u -r -N squid-3.1.18/configure.ac squid-3.1.19/configure.ac --- squid-3.1.18/configure.ac 2011-12-03 19:21:24.000000000 +1300 +++ squid-3.1.19/configure.ac 2012-02-06 00:56:55.000000000 +1300 @@ -2,7 +2,7 @@ dnl dnl $Id$ dnl -AC_INIT([Squid Web Proxy],[3.1.18],[http://www.squid-cache.org/bugs/],[squid]) +AC_INIT([Squid Web Proxy],[3.1.19],[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.18/include/version.h squid-3.1.19/include/version.h --- squid-3.1.18/include/version.h 2011-12-03 19:21:25.000000000 +1300 +++ squid-3.1.19/include/version.h 2012-02-06 00:56:56.000000000 +1300 @@ -9,7 +9,7 @@ */ #ifndef SQUID_RELEASE_TIME -#define SQUID_RELEASE_TIME 1322893123 +#define SQUID_RELEASE_TIME 1328442684 #endif #ifndef APP_SHORTNAME diff -u -r -N squid-3.1.18/RELEASENOTES.html squid-3.1.19/RELEASENOTES.html --- squid-3.1.18/RELEASENOTES.html 2011-12-03 20:05:31.000000000 +1300 +++ squid-3.1.19/RELEASENOTES.html 2012-02-06 02:18:34.000000000 +1300 @@ -2,10 +2,10 @@ - Squid 3.1.18 release notes + Squid 3.1.19 release notes -

Squid 3.1.18 release notes

+

Squid 3.1.19 release notes

Squid Developers


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

1. Notice

-

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

+

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

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

@@ -126,7 +126,7 @@
  • eCAP Adaptation Module support
  • ICAP Bypass and Retry enhancements
  • ICY streaming protocol support
  • -
  • Dynamic SSL Certificate Generation (3.1.12.1 and later)
  • +
  • Dynamic SSL Certificate Generation (3.1.13 and later)
  • Most user-facing changes are reflected in squid.conf (see below).

    @@ -1280,12 +1280,13 @@
    external_acl_type

    New options 'ipv4' and 'ipv6' are added to set the IPv4/v6 protocol between Squid and its helpers. -Please be aware of some limits to these options. These options only affect the transport protocol used -to send data to and from the helpers. IPv6 enabled Squid will still send %SRC addresses in IPv4 or IPv6 +Please be aware of some limits to these options. These options only affet the transport protocol used +to send data to and from the helpers. Squid in IPv6-mode may still send %SRC addresses in IPv4 or IPv6 format, so all helpers will need to be checked and converted to cope with such information cleanly.

    -          ipv4 / ipv6   IP transport used to communicate to this helper over localhost.
    -                        For compatability with systems lacking IPv6 support in the system kernel the default is 'ipv4'.
    +          ipv4 / ipv6   IP-mode used to communicate to this helper.
    +                        For compatability with older configurations and helpers
    +                        the default is 'ipv4'.
             
     

    diff -u -r -N squid-3.1.18/src/auth/digest/auth_digest.cc squid-3.1.19/src/auth/digest/auth_digest.cc --- squid-3.1.18/src/auth/digest/auth_digest.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/auth/digest/auth_digest.cc 2012-02-06 00:51:32.000000000 +1300 @@ -490,10 +490,10 @@ AuthUser *auth_user; debugs(29, 9, HERE << "Looking for user '" << username << "'"); - if (username && (usernamehash = static_cast < auth_user_hash_pointer * >(hash_lookup(proxy_auth_username_cache, username)))) { + if (username && (usernamehash = static_cast < AuthUserHashPointer * >(hash_lookup(proxy_auth_username_cache, username)))) { while ((usernamehash->user()->auth_type != AUTH_DIGEST) && (usernamehash->next)) - usernamehash = static_cast < auth_user_hash_pointer * >(usernamehash->next); + usernamehash = static_cast < AuthUserHashPointer * >(usernamehash->next); auth_user = NULL; @@ -515,7 +515,7 @@ AuthUser *auth_user; hash_first(proxy_auth_username_cache); - while ((usernamehash = ((auth_user_hash_pointer *) hash_next(proxy_auth_username_cache)))) { + while ((usernamehash = ((AuthUserHashPointer *) hash_next(proxy_auth_username_cache)))) { auth_user = usernamehash->user(); if (strcmp(auth_user->config->type(), "digest") == 0) diff -u -r -N squid-3.1.18/src/auth/ntlm/auth_ntlm.cc squid-3.1.19/src/auth/ntlm/auth_ntlm.cc --- squid-3.1.18/src/auth/ntlm/auth_ntlm.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/auth/ntlm/auth_ntlm.cc 2012-02-06 00:51:32.000000000 +1300 @@ -393,7 +393,7 @@ debugs(29, 4, "AuthNTLMUserRequest::authenticate: authenticated user " << ntlm_user->username()); /* see if this is an existing user with a different proxy_auth * string */ - auth_user_hash_pointer *usernamehash = static_cast(hash_lookup(proxy_auth_username_cache, ntlm_user->username())); + AuthUserHashPointer *usernamehash = static_cast(hash_lookup(proxy_auth_username_cache, ntlm_user->username())); AuthUser *local_auth_user = ntlm_request->user(); while (usernamehash && (usernamehash->user()->auth_type != AUTH_NTLM || strcmp(usernamehash->user()->username(), ntlm_user->username()) != 0)) usernamehash = static_cast(usernamehash->next); diff -u -r -N squid-3.1.18/src/client_side.cc squid-3.1.19/src/client_side.cc --- squid-3.1.18/src/client_side.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/client_side.cc 2012-02-06 00:51:32.000000000 +1300 @@ -1390,6 +1390,7 @@ */ } +/// called when we have successfully finished writing the response void ClientSocketContext::keepaliveNextRequest() { @@ -1406,6 +1407,26 @@ } /** \par + * We are done with the response, and we are either still receiving request + * body (early response!) or have already stopped receiving anything. + * + * If we are still receiving, then clientParseRequest() below will fail. + * (XXX: but then we will call readNextRequest() which may succeed and + * execute a smuggled request as we are not done with the current request). + * + * If we stopped because we got everything, then try the next request. + * + * If we stopped receiving because of an error, then close now to avoid + * getting stuck and to prevent accidental request smuggling. + */ + + if (const char *reason = conn->stoppedReceiving()) { + debugs(33, 3, HERE << "closing for earlier request error: " << reason); + comm_close(conn->fd); + return; + } + + /** \par * Attempt to parse a request from the request buffer. * If we've been fed a pipelined request it may already * be in our read buffer. @@ -1634,44 +1655,36 @@ comm_close(fd()); } -/** Called to initiate (and possibly complete) closing of the context. - * The underlying socket may be already closed */ +/// called when we encounter a response-related error void ClientSocketContext::initiateClose(const char *reason) { - debugs(33, 5, HERE << "initiateClose: closing for " << reason); + http->getConn()->stopSending(reason); // closes ASAP +} - if (http != NULL) { - ConnStateData * conn = http->getConn(); +void +ConnStateData::stopSending(const char *error) +{ + debugs(33, 4, HERE << "sending error (FD " << fd << "): " << error << + "; old receiving error: " << + (stoppedReceiving() ? stoppedReceiving_ : "none")); - if (conn != NULL) { - if (const int64_t expecting = conn->bodySizeLeft()) { - debugs(33, 5, HERE << "ClientSocketContext::initiateClose: " << - "closing, but first " << conn << " needs to read " << - expecting << " request body bytes with " << - conn->in.notYetUsed << " notYetUsed"); - - if (conn->closing()) { - debugs(33, 2, HERE << "avoiding double-closing " << conn); - return; - } - - /* - * XXX We assume the reply fits in the TCP transmit - * window. If not the connection may stall while sending - * the reply (before reaching here) if the client does not - * try to read the response while sending the request body. - * As of yet we have not received any complaints indicating - * this may be an issue. - */ - conn->startClosing(reason); + if (const char *oldError = stoppedSending()) { + debugs(33, 3, HERE << "already stopped sending: " << oldError); + return; // nothing has changed as far as this connection is concerned + } - return; - } + stoppedSending_ = error; + + if (!stoppedReceiving()) { + if (const int64_t expecting = bodySizeLeft()) { + debugs(33, 5, HERE << "must still read " << expecting << + " request body bytes with " << in.notYetUsed << " unused"); + return; // wait for the request receiver to finish reading } } - doClose(); + comm_close(fd); } void @@ -2928,16 +2941,11 @@ if (!bodyPipe) { debugs(33,5, HERE << "produced entire request body for FD " << fd); - if (closing()) { + if (const char *reason = stoppedSending()) { /* we've finished reading like good clients, * now do the close that initiateClose initiated. - * - * XXX: do we have to close? why not check keepalive et. - * - * XXX: To support chunked requests safely, we need to handle - * the case of an endless request. This if-statement does not, - * because mayNeedMoreData is true if request size is not known. */ + debugs(33, 3, HERE << "closing for earlier sending error: " << reason); comm_close(fd); return false; } @@ -2952,7 +2960,7 @@ return; // too late to read more body - if (!isOpen() || closing()) + if (!isOpen() || stoppedReceiving()) return; readSomeData(); @@ -2961,8 +2969,11 @@ void ConnStateData::noteBodyConsumerAborted(BodyPipe::Pointer ) { - if (!closing()) - startClosing("body consumer aborted"); + // request reader may get stuck waiting for space if nobody consumes body + if (bodyPipe != NULL) + bodyPipe->enableAutoConsumption(); + + stopReceiving("virgin request body consumer aborted"); // closes ASAP } /** general lifetime handler for HTTP requests */ @@ -3755,7 +3766,9 @@ CBDATA_CLASS_INIT(ConnStateData); -ConnStateData::ConnStateData() :AsyncJob("ConnStateData"), transparent_ (false), closing_ (false), switchedToHttps_(false) +ConnStateData::ConnStateData() :AsyncJob("ConnStateData"), transparent_ (false), + switchedToHttps_(false), + stoppedSending_(NULL), stoppedReceiving_(NULL) { pinning.fd = -1; pinning.pinned = false; @@ -3798,33 +3811,24 @@ return bodyPipe; } -bool -ConnStateData::closing() const -{ - return closing_; -} - -/** - * Called by ClientSocketContext to give the connection a chance to read - * the entire body before closing the socket. - */ void -ConnStateData::startClosing(const char *reason) +ConnStateData::stopReceiving(const char *error) { - debugs(33, 5, HERE << "startClosing " << this << " for " << reason); - assert(!closing()); - closing_ = true; + debugs(33, 4, HERE << "receiving error (FD " << fd << "): " << error << + "; old sending error: " << + (stoppedSending() ? stoppedSending_ : "none")); - assert(bodyPipe != NULL); - assert(bodySizeLeft() > 0); + if (const char *oldError = stoppedReceiving()) { + debugs(33, 3, HERE << "already stopped receiving: " << oldError); + return; // nothing has changed as far as this connection is concerned + } - // We do not have to abort the body pipeline because we are going to - // read the entire body anyway. - // Perhaps an ICAP server wants to log the complete request. - - // If a consumer abort have caused this closing, we may get stuck - // as nobody is consuming our data. Allow auto-consumption. - bodyPipe->enableAutoConsumption(); + stoppedReceiving_ = error; + + if (const char *sendError = stoppedSending()) { + debugs(33, 3, HERE << "closing because also stopped sending: " << sendError); + comm_close(fd); + } } void diff -u -r -N squid-3.1.18/src/client_side.h squid-3.1.19/src/client_side.h --- squid-3.1.18/src/client_side.h 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/client_side.h 2012-02-06 00:51:32.000000000 +1300 @@ -214,8 +214,15 @@ bool reading() const; void stopReading(); ///< cancels comm_read if it is scheduled - bool closing() const; - void startClosing(const char *reason); + /// true if we stopped receiving the request + const char *stoppedReceiving() const { return stoppedReceiving_; } + /// true if we stopped sending the response + const char *stoppedSending() const { return stoppedSending_; } + /// note request receiving error and close as soon as we write the response + void stopReceiving(const char *error); + /// note response sending error and close as soon as we read the request + void stopSending(const char *error); + void expectNoForwarding(); ///< cleans up virgin request [body] forwarding state BodyPipe::Pointer expectRequestBody(int64_t size); @@ -293,9 +300,14 @@ private: CBDATA_CLASS2(ConnStateData); bool transparent_; - bool closing_; bool switchedToHttps_; + + /// the reason why we no longer write the response or nil + const char *stoppedSending_; + /// the reason why we no longer read the request or nil + const char *stoppedReceiving_; + String sslHostName; ///< Host name for SSL certificate generation AsyncCall::Pointer reader; ///< set when we are reading BodyPipe::Pointer bodyPipe; // set when we are reading request body diff -u -r -N squid-3.1.18/src/client_side_reply.cc squid-3.1.19/src/client_side_reply.cc --- squid-3.1.18/src/client_side_reply.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/client_side_reply.cc 2012-02-06 00:51:32.000000000 +1300 @@ -359,6 +359,7 @@ // origin replied 304 if (status == HTTP_NOT_MODIFIED) { http->logType = LOG_TCP_REFRESH_UNMODIFIED; + http->request->flags.stale_if_hit = 0; // old_entry is no longer stale // update headers on existing entry old_rep->updateOnNotModified(http->storeEntry()->getReply()); diff -u -r -N squid-3.1.18/src/client_side_request.cc squid-3.1.19/src/client_side_request.cc --- squid-3.1.18/src/client_side_request.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/client_side_request.cc 2012-02-06 00:51:32.000000000 +1300 @@ -873,18 +873,22 @@ request->flags.auth = 1; ConnStateData *http_conn = http->getConn(); - assert(http_conn); - request->flags.connection_auth_disabled = http_conn->port->connection_auth_disabled; - if (!request->flags.connection_auth_disabled) { - if (http_conn->pinning.fd != -1) { - if (http_conn->pinning.auth) { - request->flags.connection_auth = 1; - request->flags.auth = 1; - } else { - request->flags.connection_proxy_auth = 1; + if (http_conn) { + request->flags.connection_auth_disabled = http_conn->port->connection_auth_disabled; + if (!request->flags.connection_auth_disabled) { + if (http_conn->pinning.fd != -1) { + if (http_conn->pinning.auth) { + request->flags.connection_auth = 1; + request->flags.auth = 1; + } else { + request->flags.connection_proxy_auth = 1; + } + request->setPinnedConnection(http_conn); } - request->setPinnedConnection(http_conn); } + } else { + // internal requests and ESI don't have client conn. + request->flags.connection_auth_disabled = 1; } /* check if connection auth is used, and flag as candidate for pinning diff -u -r -N squid-3.1.18/src/external_acl.cc squid-3.1.19/src/external_acl.cc --- squid-3.1.18/src/external_acl.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/external_acl.cc 2012-02-06 00:51:32.000000000 +1300 @@ -681,6 +681,27 @@ safe_free (class_); } +static void +copyResultsFromEntry(HttpRequest *req, external_acl_entry *entry) +{ + if (req) { + if (entry->user.size()) + req->extacl_user = entry->user; + + if (entry->password.size()) + req->extacl_passwd = entry->password; + + if (!req->tag.size()) + req->tag = entry->tag; + + if (entry->log.size()) + req->extacl_log = entry->log; + + if (entry->message.size()) + req->extacl_message = entry->message; + } +} + static int aclMatchExternal(external_acl_data *acl, ACLFilledChecklist *ch) { @@ -762,24 +783,7 @@ external_acl_message = entry->message.termedBuf(); debugs(82, 2, "aclMatchExternal: " << acl->def->name << " = " << result); - - if (ch->request) { - if (entry->user.size()) - ch->request->extacl_user = entry->user; - - if (entry->password.size()) - ch->request->extacl_passwd = entry->password; - - if (!ch->request->tag.size()) - ch->request->tag = entry->tag; - - if (entry->log.size()) - ch->request->extacl_log = entry->log; - - if (entry->message.size()) - ch->request->extacl_message = entry->message; - } - + copyResultsFromEntry(ch->request, entry); return result; } @@ -838,8 +842,13 @@ switch (format->type) { case _external_acl_format::EXT_ACL_LOGIN: - assert (ch->auth_user_request); - str = ch->auth_user_request->username(); + // if this ACL line was the cause of credentials fetch + // they may not already be in the checklist + if (ch->auth_user_request == NULL && ch->request) + ch->auth_user_request = ch->request->auth_user_request; + + if (ch->auth_user_request != NULL) + str = ch->auth_user_request->username(); break; #if USE_IDENT @@ -1348,7 +1357,7 @@ (long unsigned int) entry->date << ", result=" << entry->result << ", user=" << entry->user << " tag=" << entry->tag << " log=" << entry->log << " }"); - + copyResultsFromEntry(ch->request, entry); } callback(callback_data, entry); diff -u -r -N squid-3.1.18/src/fs/ufs/store_dir_ufs.cc squid-3.1.19/src/fs/ufs/store_dir_ufs.cc --- squid-3.1.18/src/fs/ufs/store_dir_ufs.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/fs/ufs/store_dir_ufs.cc 2012-02-06 00:51:32.000000000 +1300 @@ -733,14 +733,15 @@ file_close(swaplog_fd); if (xrename(new_path, swaplog_path) < 0) { - fatal("commonUfsDirCloseTmpSwapLog: rename failed"); + debugs(50, DBG_IMPORTANT, "ERROR: " << swaplog_path << ": " << xstrerror()); + fatalf("Failed to rename log file %s to %s.new", swaplog_path, swaplog_path); } fd = file_open(swaplog_path, O_WRONLY | O_CREAT | O_BINARY); if (fd < 0) { - debugs(50, 1, "" << swaplog_path << ": " << xstrerror()); - fatal("commonUfsDirCloseTmpSwapLog: Failed to open swap log."); + debugs(50, DBG_IMPORTANT, "ERROR: " << swaplog_path << ": " << xstrerror()); + fatalf("Failed to open swap log %s", swaplog_path); } safe_free(swaplog_path); @@ -749,13 +750,6 @@ debugs(47, 3, "Cache Dir #" << index << " log opened on FD " << fd); } -static void -FreeHeader(void *address) -{ - StoreSwapLogHeader *anObject = static_cast (address); - delete anObject; -} - FILE * UFSSwapDir::openTmpSwapLog(int *clean_flag, int *zero_flag) { @@ -794,9 +788,16 @@ swaplog_fd = fd; { - StoreSwapLogHeader *header = new StoreSwapLogHeader; - file_write(swaplog_fd, -1, header, sizeof(*header), - NULL, NULL, FreeHeader); + const StoreSwapLogHeader header; + MemBuf buf; + buf.init(header.record_size, header.record_size); + buf.append(reinterpret_cast(&header), sizeof(header)); + // Pad to keep in sync with UFSSwapDir::writeCleanStart(). + // TODO: When MemBuf::spaceSize() is fixed not to subtract one, + // memset() space() with zeroes and use spaceSize() below. + buf.appended(static_cast(header.record_size) - sizeof(header)); + file_write(swaplog_fd, -1, buf.content(), buf.contentSize(), + NULL, NULL, buf.freeFunc()); } /* open a read-only stream of the old log */ @@ -882,6 +883,7 @@ state->outbuf_offset = 0; /*copy the header */ xmemcpy(state->outbuf, &header, sizeof(StoreSwapLogHeader)); + // Leave a gap to keep in sync with UFSSwapDir::openTmpSwapLog(). state->outbuf_offset += header.record_size; state->walker = repl->WalkInit(repl); diff -u -r -N squid-3.1.18/src/fs/ufs/ufscommon.cc squid-3.1.19/src/fs/ufs/ufscommon.cc --- squid-3.1.18/src/fs/ufs/ufscommon.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/fs/ufs/ufscommon.cc 2012-02-06 00:51:32.000000000 +1300 @@ -604,11 +604,10 @@ n_read++; - if (swapData.op <= SWAP_LOG_NOP) - continue; - - if (swapData.op >= SWAP_LOG_MAX) + if (!swapData.sane()) { + counts.invalid++; continue; + } /* * BC: during 2.4 development, we changed the way swap file diff -u -r -N squid-3.1.18/src/Makefile.am squid-3.1.19/src/Makefile.am --- squid-3.1.18/src/Makefile.am 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/Makefile.am 2012-02-06 00:51:32.000000000 +1300 @@ -531,8 +531,8 @@ $(SNMPLIB) \ ${ADAPTATION_LIBS} \ $(ESI_LIBS) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ -lmiscutil \ $(EPOLL_LIBS) \ $(MINGW_LIBS) \ @@ -1203,8 +1203,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testCacheManager_LDFLAGS = $(LIBADD_DL) tests_testCacheManager_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ @@ -1379,8 +1379,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testEvent_LDFLAGS = $(LIBADD_DL) tests_testEvent_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ @@ -1530,8 +1530,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testEventLoop_LDFLAGS = $(LIBADD_DL) tests_testEventLoop_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ @@ -1676,8 +1676,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_test_http_range_LDFLAGS = $(LIBADD_DL) tests_test_http_range_DEPENDENCIES = \ @@ -1827,8 +1827,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testHttpRequest_LDFLAGS = $(LIBADD_DL) tests_testHttpRequest_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ @@ -2262,8 +2262,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testURL_LDFLAGS = $(LIBADD_DL) tests_testURL_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ diff -u -r -N squid-3.1.18/src/Makefile.in squid-3.1.19/src/Makefile.in --- squid-3.1.18/src/Makefile.in 2011-12-03 19:20:35.000000000 +1300 +++ squid-3.1.19/src/Makefile.in 2012-02-06 00:55:16.000000000 +1300 @@ -1890,7 +1890,7 @@ ../compat/libcompat.la -L../lib $(XTRA_OBJS) $(DISK_LINKOBJS) \ $(REPL_OBJS) $(DISK_LIBS) $(DISK_OS_LIBS) $(CRYPTLIB) \ $(REGEXLIB) $(SNMPLIB) ${ADAPTATION_LIBS} $(ESI_LIBS) \ - $(SSLLIB) $(SSL_LIBS) -lmiscutil $(EPOLL_LIBS) $(MINGW_LIBS) \ + $(SSL_LIBS) $(SSLLIB) -lmiscutil $(EPOLL_LIBS) $(MINGW_LIBS) \ $(XTRA_LIBS) $(am__append_6) squid_DEPENDENCIES = $(top_builddir)/lib/libmiscutil.a \ $(DISK_LIBS) \ @@ -2397,8 +2397,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testCacheManager_LDFLAGS = $(LIBADD_DL) @@ -2577,8 +2577,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testEvent_LDFLAGS = $(LIBADD_DL) @@ -2730,8 +2730,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testEventLoop_LDFLAGS = $(LIBADD_DL) @@ -2879,8 +2879,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_test_http_range_LDFLAGS = $(LIBADD_DL) @@ -3031,8 +3031,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testHttpRequest_LDFLAGS = $(LIBADD_DL) @@ -3477,8 +3477,8 @@ -L../lib -lmiscutil \ $(SQUID_CPPUNIT_LIBS) \ $(SQUID_CPPUNIT_LA) \ - $(SSLLIB) \ $(SSL_LIBS) \ + $(SSLLIB) \ $(XTRA_LIBS) tests_testURL_LDFLAGS = $(LIBADD_DL) diff -u -r -N squid-3.1.18/src/ssl_support.cc squid-3.1.19/src/ssl_support.cc --- squid-3.1.18/src/ssl_support.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/ssl_support.cc 2012-02-06 00:51:32.000000000 +1300 @@ -355,7 +355,7 @@ #endif #ifdef SSL_OP_ALL { - "ALL", SSL_OP_ALL + "ALL", (long)SSL_OP_ALL }, #endif #ifdef SSL_OP_SINGLE_DH_USE diff -u -r -N squid-3.1.18/src/store.cc squid-3.1.19/src/store.cc --- squid-3.1.18/src/store.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/store.cc 2012-02-06 00:51:32.000000000 +1300 @@ -368,7 +368,7 @@ #if USE_ADAPTATION void -StoreEntry::deferProducer(const AsyncCall::Pointer &producer) +StoreEntry::deferProducer(AsyncCall::Pointer &producer) { if (!deferredProducer) deferredProducer = producer; diff -u -r -N squid-3.1.18/src/StoreEntryStream.h squid-3.1.19/src/StoreEntryStream.h --- squid-3.1.18/src/StoreEntryStream.h 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/StoreEntryStream.h 2012-02-06 00:51:32.000000000 +1300 @@ -70,7 +70,10 @@ return traits_type::eof(); if (aChar != traits_type::eof()) { - char chars[1] = {aChar}; + // NP: cast because GCC promotes int_type to 32-bit type + // std::basic_streambuf::int_type {aka int} + // despite the definition with 8-bit type value. + char chars[1] = {char(aChar)}; if (aChar != traits_type::eof()) theEntry->append(chars, 1); diff -u -r -N squid-3.1.18/src/Store.h squid-3.1.19/src/Store.h --- squid-3.1.18/src/Store.h 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/Store.h 2012-02-06 00:51:32.000000000 +1300 @@ -191,7 +191,7 @@ #if USE_ADAPTATION /// call back producer when more buffer space is available - void deferProducer(const AsyncCall::Pointer &producer); + void deferProducer(AsyncCall::Pointer &producer); /// calls back producer registered with deferProducer void kickProducer(); #endif diff -u -r -N squid-3.1.18/src/StoreSwapLogData.cc squid-3.1.19/src/StoreSwapLogData.cc --- squid-3.1.18/src/StoreSwapLogData.cc 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/StoreSwapLogData.cc 2012-02-06 00:51:32.000000000 +1300 @@ -39,6 +39,24 @@ memset (key, '\0', sizeof(key)); } +bool +StoreSwapLogData::sane() const +{ + // TODO: These checks are rather weak. A corrupted swap.state may still + // cause havoc (e.g., cur_size may become astronomical). Add checksums? + + const time_t minTime = -2; // -1 is common; expires sometimes uses -2 + + // Check what we safely can; for some fields any value might be valid + return SWAP_LOG_NOP < op && op < SWAP_LOG_MAX && + swap_filen >= 0 && + timestamp >= minTime && + lastref >= minTime && + expires >= minTime && + lastmod >= minTime && + swap_file_sz > 0; // because swap headers ought to consume space +} + StoreSwapLogHeader::StoreSwapLogHeader():op(SWAP_LOG_VERSION), version(1) { record_size = sizeof(StoreSwapLogData); diff -u -r -N squid-3.1.18/src/StoreSwapLogData.h squid-3.1.19/src/StoreSwapLogData.h --- squid-3.1.18/src/StoreSwapLogData.h 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/StoreSwapLogData.h 2012-02-06 00:51:32.000000000 +1300 @@ -86,6 +86,9 @@ MEMPROXY_CLASS(StoreSwapLogData); StoreSwapLogData(); + /// consistency self-check: whether the data appears to make sense + bool sane() const; + /** * Either SWAP_LOG_ADD when an object is added to the disk storage, * or SWAP_LOG_DEL when an object is deleted. diff -u -r -N squid-3.1.18/src/typedefs.h squid-3.1.19/src/typedefs.h --- squid-3.1.18/src/typedefs.h 2011-12-03 19:18:46.000000000 +1300 +++ squid-3.1.19/src/typedefs.h 2012-02-06 00:51:32.000000000 +1300 @@ -49,11 +49,6 @@ //UNUSED typedef struct _acl_deny_info_list acl_deny_info_list; //UNUSED typedef class AuthUser auth_user_t; - -/// \ingroup AuthAPI -/// \deprecated Use AuthUserHashPointer instead. -typedef struct AuthUserHashPointer auth_user_hash_pointer; - /// \ingroup AuthAPI /// \deprecated Use AuthUserIP instead. typedef struct AuthUserIP auth_user_ip_t;