diff options
-rw-r--r-- | main/squid/APKBUILD | 6 | ||||
-rw-r--r-- | main/squid/CVE-2014-0128.patch | 288 |
2 files changed, 292 insertions, 2 deletions
diff --git a/main/squid/APKBUILD b/main/squid/APKBUILD index 12bfe36d7c..cbdb1337da 100644 --- a/main/squid/APKBUILD +++ b/main/squid/APKBUILD @@ -1,7 +1,7 @@ # Contributor: Carlo Landmeter <clandmeter@gmail.com> # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=squid -pkgver=3.2.9 +pkgver=3.2.13 pkgrel=0 pkgdesc="A full-featured Web proxy cache server." url="http://www.squid-cache.org" @@ -21,6 +21,7 @@ langdir="/usr/share/squid/errors" source="http://www.squid-cache.org/Versions/v3/3.2/squid-$pkgver.tar.bz2 squid-3.2.0.16-loggable-urlgroup.patch cf_gen-pthread.patch + CVE-2014-0128.patch squid.initd squid.confd $pkgname.logrotate @@ -104,9 +105,10 @@ squid_kerb_auth() { mv "$pkgdir"/usr/lib/squid/squid_kerb_auth "$subpkgdir"/usr/lib/squid/ } -md5sums="de02be3c1f72e0d818374438044261a6 squid-3.2.9.tar.bz2 +md5sums="367e59c9c25da7ebbfbf7cbc36d2444e squid-3.2.13.tar.bz2 16e3b38996d4c5858e1478f8eb650876 squid-3.2.0.16-loggable-urlgroup.patch c60237de253c02937f272d3b189d7679 cf_gen-pthread.patch +7a631b0300d090d89567df8090f5368e CVE-2014-0128.patch 905e57c6d41414f54a75a5c0f9f7fac7 squid.initd 2897c725c201be53d3c9a7db0101bdf0 squid.confd 58823e0b86bc2dc71d270208b7b284b4 squid.logrotate" diff --git a/main/squid/CVE-2014-0128.patch b/main/squid/CVE-2014-0128.patch new file mode 100644 index 0000000000..7861df1335 --- /dev/null +++ b/main/squid/CVE-2014-0128.patch @@ -0,0 +1,288 @@ +diff -rNU 20 ../squid-3.2.11-o/src/client_side.cc ./src/client_side.cc +--- ../squid-3.2.11-o/src/client_side.cc 2013-04-30 06:47:06.000000000 +0200 ++++ ./src/client_side.cc 2014-04-09 15:14:50.000000000 +0200 +@@ -1249,43 +1249,41 @@ + + /* hits only - upstream peer determines correct behaviour on misses, and client_side_reply determines + * hits candidates + */ + else if (logTypeIsATcpHit(http->logType) && http->request->header.has(HDR_IF_RANGE) && !clientIfRangeMatch(http, rep)) + range_err = "If-Range match failed"; + else if (!http->request->range->canonize(rep)) + range_err = "canonization failed"; + else if (http->request->range->isComplex()) + range_err = "too complex range header"; + else if (!logTypeIsATcpHit(http->logType) && http->request->range->offsetLimitExceeded(roffLimit)) + range_err = "range outside range_offset_limit"; + + /* get rid of our range specs on error */ + if (range_err) { + /* XXX We do this here because we need canonisation etc. However, this current + * code will lead to incorrect store offset requests - the store will have the + * offset data, but we won't be requesting it. + * So, we can either re-request, or generate an error + */ +- debugs(33, 3, "clientBuildRangeHeader: will not do ranges: " << range_err << "."); +- delete http->request->range; +- http->request->range = NULL; ++ http->request->ignoreRange(range_err); + } else { + /* XXX: TODO: Review, this unconditional set may be wrong. - TODO: review. */ + httpStatusLineSet(&rep->sline, rep->sline.version, + HTTP_PARTIAL_CONTENT, NULL); + // web server responded with a valid, but unexpected range. + // will (try-to) forward as-is. + //TODO: we should cope with multirange request/responses + bool replyMatchRequest = rep->content_range != NULL ? + request->range->contains(rep->content_range->spec) : + true; + const int spec_count = http->request->range->specs.count; + int64_t actual_clen = -1; + + debugs(33, 3, "clientBuildRangeHeader: range spec count: " << + spec_count << " virgin clen: " << rep->content_length); + assert(spec_count > 0); + /* append appropriate header(s) */ + + if (spec_count == 1) { + if (!replyMatchRequest) { +diff -rNU 20 ../squid-3.2.11-o/src/client_side_reply.cc ./src/client_side_reply.cc +--- ../squid-3.2.11-o/src/client_side_reply.cc 2013-04-30 06:47:06.000000000 +0200 ++++ ./src/client_side_reply.cc 2014-04-09 15:21:57.000000000 +0200 +@@ -102,40 +102,43 @@ + err_type err, http_status status, const HttpRequestMethod& method, char const *uri, + Ip::Address &addr, HttpRequest * failedrequest, const char *unparsedrequest, + #if USE_AUTH + Auth::UserRequest::Pointer auth_user_request + #else + void* + #endif + ) + { + ErrorState *errstate = clientBuildError(err, status, uri, addr, failedrequest); + + if (unparsedrequest) + errstate->request_hdrs = xstrdup(unparsedrequest); + + if (status == HTTP_NOT_IMPLEMENTED && http->request) + /* prevent confusion over whether we default to persistent or not */ + http->request->flags.proxy_keepalive = 0; + + http->al->http.code = errstate->httpStatus; + ++ if (http->request) ++ http->request->ignoreRange("responding with a Squid-generated error"); ++ + createStoreEntry(method, request_flags()); + #if USE_AUTH + errstate->auth_user_request = auth_user_request; + #endif + assert(errstate->callback_data == NULL); + errorAppendEntry(http->storeEntry(), errstate); + /* Now the caller reads to get this */ + } + + void + clientReplyContext::removeStoreReference(store_client ** scp, + StoreEntry ** ep) + { + StoreEntry *e; + store_client *sc_tmp = *scp; + + if ((e = *ep) != NULL) { + *ep = NULL; + storeUnregister(sc_tmp, e, this); + *scp = NULL; +diff -rNU 20 ../squid-3.2.11-o/src/client_side_request.cc ./src/client_side_request.cc +--- ../squid-3.2.11-o/src/client_side_request.cc 2014-04-09 14:58:52.000000000 +0200 ++++ ./src/client_side_request.cc 2014-04-09 15:22:41.000000000 +0200 +@@ -1097,42 +1097,41 @@ + clientStreamNode *node = (clientStreamNode *)http->client_stream.tail->data; + /* XXX: This is suboptimal. We should give the stream the range set, + * and thereby let the top of the stream set the offset when the + * size becomes known. As it is, we will end up requesting from 0 + * for evey -X range specification. + * RBC - this may be somewhat wrong. We should probably set the range + * iter up at this point. + */ + node->readBuffer.offset = request->range->lowestOffset(0); + http->range_iter.pos = request->range->begin(); + http->range_iter.valid = true; + } + } + + /* Only HEAD and GET requests permit a Range or Request-Range header. + * If these headers appear on any other type of request, delete them now. + */ + else { + req_hdr->delById(HDR_RANGE); + req_hdr->delById(HDR_REQUEST_RANGE); +- delete request->range; +- request->range = NULL; ++ request->ignoreRange("neither HEAD nor GET"); + } + + if (req_hdr->has(HDR_AUTHORIZATION)) + request->flags.auth = 1; + + clientCheckPinning(http); + + if (request->login[0] != '\0') + request->flags.auth = 1; + + if (req_hdr->has(HDR_VIA)) { + String s = req_hdr->getList(HDR_VIA); + /* + * ThisCache cannot be a member of Via header, "1.1 ThisCache" can. + * Note ThisCache2 has a space prepended to the hostname so we don't + * accidentally match super-domains. + */ + + if (strListIsSubstr(&s, ThisCache2, ',')) { + debugObj(33, 1, "WARNING: Forwarding loop detected for:\n", +diff -rNU 20 ../squid-3.2.11-o/src/http.cc ./src/http.cc +--- ../squid-3.2.11-o/src/http.cc 2013-04-30 06:47:06.000000000 +0200 ++++ ./src/http.cc 2014-04-09 15:23:31.000000000 +0200 +@@ -1710,42 +1710,41 @@ + assert (hdr_out->owner == hoRequest); + + /* append our IMS header */ + if (request->lastmod > -1) + hdr_out->putTime(HDR_IF_MODIFIED_SINCE, request->lastmod); + + bool we_do_ranges = decideIfWeDoRanges (request); + + String strConnection (hdr_in->getList(HDR_CONNECTION)); + + while ((e = hdr_in->getEntry(&pos))) + copyOneHeaderFromClientsideRequestToUpstreamRequest(e, strConnection, request, hdr_out, we_do_ranges, flags); + + /* Abstraction break: We should interpret multipart/byterange responses + * into offset-length data, and this works around our inability to do so. + */ + if (!we_do_ranges && request->multipartRangeRequest()) { + /* don't cache the result */ + request->flags.cachable = 0; + /* pretend it's not a range request */ +- delete request->range; +- request->range = NULL; ++ request->ignoreRange("want to request the whole object"); + request->flags.range = 0; + } + + /* append Via */ + if (Config.onoff.via) { + String strVia; + strVia = hdr_in->getList(HDR_VIA); + snprintf(bbuf, BBUF_SZ, "%d.%d %s", + request->http_ver.major, + request->http_ver.minor, ThisCache); + strListAdd(&strVia, bbuf, ','); + hdr_out->putStr(HDR_VIA, strVia.termedBuf()); + strVia.clean(); + } + + if (request->flags.accelerated) { + /* Append Surrogate-Capabilities */ + String strSurrogate(hdr_in->getList(HDR_SURROGATE_CAPABILITY)); + #if USE_SQUID_ESI + snprintf(bbuf, BBUF_SZ, "%s=\"Surrogate/1.0 ESI/1.0\"", Config.Accel.surrogate_id); +diff -rNU 20 ../squid-3.2.11-o/src/HttpRequest.cc ./src/HttpRequest.cc +--- ../squid-3.2.11-o/src/HttpRequest.cc 2013-04-30 06:47:06.000000000 +0200 ++++ ./src/HttpRequest.cc 2014-04-09 15:04:05.000000000 +0200 +@@ -674,31 +674,46 @@ + return rangeOffsetLimit; + + rangeOffsetLimit = 0; // default value for rangeOffsetLimit + + ACLFilledChecklist ch(NULL, this, NULL); + ch.src_addr = client_addr; + ch.my_addr = my_addr; + + for (acl_size_t *l = Config.rangeOffsetLimit; l; l = l -> next) { + /* if there is no ACL list or if the ACLs listed match use this limit value */ + if (!l->aclList || ch.fastCheck(l->aclList) == ACCESS_ALLOWED) { + debugs(58, 4, HERE << "rangeOffsetLimit=" << rangeOffsetLimit); + rangeOffsetLimit = l->size; // may be -1 + break; + } + } + + return rangeOffsetLimit; + } + ++void ++HttpRequest::ignoreRange(const char *reason) ++{ ++ if (range) { ++ debugs(73, 3, static_cast<void*>(range) << " for " << reason); ++ delete range; ++ range = NULL; ++ } ++ // Some callers also reset isRanged but it may not be safe for all callers: ++ // isRanged is used to determine whether a weak ETag comparison is allowed, ++ // and that check should not ignore the Range header if it was present. ++ // TODO: Some callers also delete HDR_RANGE, HDR_REQUEST_RANGE. Should we? ++} ++ ++ + bool + HttpRequest::canHandle1xx() const + { + // old clients do not support 1xx unless they sent Expect: 100-continue + // (we reject all other HDR_EXPECT values so just check for HDR_EXPECT) + if (http_ver <= HttpVersion(1,0) && !header.has(HDR_EXPECT)) + return false; + + // others must support 1xx control messages + return true; + } +diff -rNU 20 ../squid-3.2.11-o/src/HttpRequest.h ./src/HttpRequest.h +--- ../squid-3.2.11-o/src/HttpRequest.h 2013-04-30 06:47:06.000000000 +0200 ++++ ./src/HttpRequest.h 2014-04-09 15:04:42.000000000 +0200 +@@ -223,40 +223,43 @@ + void pack(Packer * p); + + static void httpRequestPack(void *obj, Packer *p); + + static HttpRequest * CreateFromUrlAndMethod(char * url, const HttpRequestMethod& method); + + static HttpRequest * CreateFromUrl(char * url); + + ConnStateData *pinnedConnection() { + if (clientConnectionManager.valid() && clientConnectionManager->pinning.pinned) + return clientConnectionManager.get(); + return NULL; + } + + /** + * The client connection manager, if known; + * Used for any response actions needed directly to the client. + * ie 1xx forwarding or connection pinning state changes + */ + CbcPointer<ConnStateData> clientConnectionManager; ++ /// forgets about the cached Range header (for a reason) ++ void ignoreRange(const char *reason); ++ + + int64_t getRangeOffsetLimit(); /* the result of this function gets cached in rangeOffsetLimit */ + + private: + const char *packableURI(bool full_uri) const; + + mutable int64_t rangeOffsetLimit; /* caches the result of getRangeOffsetLimit */ + + protected: + virtual void packFirstLineInto(Packer * p, bool full_uri) const; + + virtual bool sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, http_status *error); + + virtual void hdrCacheInit(); + + virtual bool inheritProperties(const HttpMsg *aMsg); + }; + + MEMPROXY_CLASS_INLINE(HttpRequest); + + + |