From: Amos Jeffries Date: Mon, 7 Feb 2011 12:07:18 +0000 (-0700) Subject: Author: Alexandre SIMON X-Git-Tag: SQUID_3_1_11~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5e259082c61c6a0eb1c2d643d8b8d81609a9b7b;p=thirdparty%2Fsquid.git Author: Alexandre SIMON Bug 3144: redirector program blocks while reading STDIN The string passed to redirect helper program may exceed the available buffer space and be truncated. Thus having no \n terminator for the helper. Test for this failure condition and produce an error page. --- diff --git a/errors/Makefile.am b/errors/Makefile.am index d2f73f57db..b30c16d691 100644 --- a/errors/Makefile.am +++ b/errors/Makefile.am @@ -29,6 +29,7 @@ ERROR_TEMPLATES = \ templates/ERR_FTP_PUT_ERROR \ templates/ERR_FTP_PUT_MODIFIED \ templates/ERR_FTP_UNAVAILABLE \ + templates/ERR_GATEWAY_FAILURE \ templates/ERR_ICAP_FAILURE \ templates/ERR_INVALID_REQ \ templates/ERR_INVALID_RESP \ diff --git a/errors/templates/ERR_GATEWAY_FAILURE b/errors/templates/ERR_GATEWAY_FAILURE new file mode 100644 index 0000000000..0a0cfeb771 --- /dev/null +++ b/errors/templates/ERR_GATEWAY_FAILURE @@ -0,0 +1,39 @@ + + + +ERROR: The requested URL could not be retrieved + + +
+

ERROR

+

The requested URL could not be retrieved

+
+
+ +
+

The following error was encountered while trying to retrieve the URL: %U

+ +
+

Gateway Proxy Failure

+
+ +

A non-recoverable internal failure or configuration problem prevents this request from being completed.

+ +

This may be due to limits established by the Internet Service Provider who operates this cache. Please contact them directly for more information.

+ +

Your cache administrator is %w.

+
+
+ +
+ + diff --git a/src/enums.h b/src/enums.h index 5b089106ba..9c0f2dcde2 100644 --- a/src/enums.h +++ b/src/enums.h @@ -103,6 +103,7 @@ typedef enum { ERR_INVALID_RESP, ERR_ICAP_FAILURE, ERR_UNSUP_HTTPVERSION, /* HTTP version is not supported */ + ERR_GATEWAY_FAILURE, ERR_MAX } err_type; diff --git a/src/redirect.cc b/src/redirect.cc index 04bbe8a08a..ed4157b9ef 100644 --- a/src/redirect.cc +++ b/src/redirect.cc @@ -42,9 +42,13 @@ #include "acl/Checklist.h" #include "HttpRequest.h" #include "client_side.h" +#include "client_side_reply.h" #include "helper.h" #include "rfc1738.h" +/// url maximum lengh + extra informations passed to redirector +#define MAX_REDIRECTOR_REQUEST_STRLEN (MAX_URL + 1024) + typedef struct { void *data; char *orig_url; @@ -114,7 +118,9 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data) ConnStateData * conn = http->getConn(); redirectStateData *r = NULL; const char *fqdn; - char buf[8192]; + char buf[MAX_REDIRECTOR_REQUEST_STRLEN]; + int sz; + http_status status; char claddr[MAX_IPSTRLEN]; char myaddr[MAX_IPSTRLEN]; assert(http); @@ -164,14 +170,41 @@ redirectStart(ClientHttpRequest * http, RH * handler, void *data) if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL) fqdn = dash_str; - snprintf(buf, 8192, "%s %s/%s %s %s myip=%s myport=%d\n", - r->orig_url, - r->client_addr.NtoA(claddr,MAX_IPSTRLEN), - fqdn, - r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str, - r->method_s, - http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN), - http->request->my_addr.GetPort()); + sz = snprintf(buf, MAX_REDIRECTOR_REQUEST_STRLEN, "%s %s/%s %s %s myip=%s myport=%d\n", + r->orig_url, + r->client_addr.NtoA(claddr,MAX_IPSTRLEN), + fqdn, + r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str, + r->method_s, + http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN), + http->request->my_addr.GetPort()); + + if ((sz<=0) || (sz>=MAX_REDIRECTOR_REQUEST_STRLEN)) { + if (sz<=0) { + status = HTTP_INTERNAL_SERVER_ERROR; + debugs(61, DBG_CRITICAL, "ERROR: Gateway Failure. Can not build request to be passed to redirector. Request ABORTED."); + } else { + status = HTTP_REQUEST_URI_TOO_LARGE; + debugs(61, DBG_CRITICAL, "ERROR: Gateway Failure. Request passed to redirector exceeds MAX_REDIRECTOR_REQUEST_STRLEN (" << MAX_REDIRECTOR_REQUEST_STRLEN << "). Request ABORTED."); + } + + clientStreamNode *node = (clientStreamNode *)http->client_stream.tail->prev->data; + clientReplyContext *repContext = dynamic_cast(node->data.getRaw()); + assert (repContext); + IpAddress tmpnoaddr; + tmpnoaddr.SetNoAddr(); + repContext->setReplyToError(ERR_GATEWAY_FAILURE, status, + http->request->method, NULL, + http->getConn() != NULL ? http->getConn()->peer : tmpnoaddr, + http->request, + NULL, + http->getConn() != NULL && http->getConn()->auth_user_request != NULL ? + http->getConn()->auth_user_request : http->request->auth_user_request); + + node = (clientStreamNode *)http->client_stream.tail->data; + clientStreamRead(node, http, node->readBuffer); + return; + } helperSubmit(redirectors, buf, redirectHandleReply, r); }