Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP4:Update
squid.26147
SQUID-2019_12.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File SQUID-2019_12.patch of Package squid.26147
Adapted from commit fdd4123629320aa1ee4c3481bb392437c90d188d Author: Amos Jeffries <yadij@users.noreply.github.com> Date: 2019-05-20 11:23:13 +0000 ESI: convert parse exceptions into 500 status response (#411) Produce a valid HTTP 500 status reply and continue operations when ESI parser throws an exception. This will prevent incomplete ESI responses reaching clients on server errors. Such responses might have been cacheable and thus corrupted, albeit corrupted consistently and at source by the reverse-proxy delivering them. ESI: throw on large stack recursions (#408) This reduces the impact on concurrent clients to only those accessing the malformed resource. Depending on what type of recursion is being performed the resource may appear to the client with missing segments, or not at all. Index: squid-3.5.21/src/esi/Context.h =================================================================== --- squid-3.5.21.orig/src/esi/Context.h +++ squid-3.5.21/src/esi/Context.h @@ -12,6 +12,7 @@ #include "clientStream.h" #include "err_type.h" #include "esi/Element.h" +#include "esi/Esi.h" #include "esi/Parser.h" #include "http/StatusCode.h" #include "HttpReply.h" @@ -112,7 +113,7 @@ public: { public: - ESIElement::Pointer stack[10]; /* a stack of esi elements that are open */ + ESIElement::Pointer stack[ESI_STACK_DEPTH_LIMIT]; /* a stack of esi elements that are open */ int stackdepth; /* self explanatory */ ESIParser::Pointer theParser; ESIElement::Pointer top(); Index: squid-3.5.21/src/esi/Esi.cc =================================================================== --- squid-3.5.21.orig/src/esi/Esi.cc +++ squid-3.5.21/src/esi/Esi.cc @@ -29,6 +29,7 @@ #include "esi/Expression.h" #include "esi/Segment.h" #include "esi/VarState.h" +#include "FadingCounter.h" #include "HttpHdrSc.h" #include "HttpHdrScTarget.h" #include "HttpReply.h" @@ -38,6 +39,7 @@ #include "MemBuf.h" #include "profiler/Profiler.h" #include "SquidConfig.h" +#include "exceptions.h" /* quick reference on behaviour here. * The ESI specification 1.0 requires the ESI processor to be able to @@ -943,13 +945,18 @@ void ESIContext::addStackElement (ESIElement::Pointer element) { /* Put on the stack to allow skipping of 'invalid' markup */ - assert (parserState.stackdepth <11); + + // throw an error if the stack location would be invalid + if (parserState.stackdepth >= ESI_STACK_DEPTH_LIMIT) + throw Esi::Error("ESI Too many nested elements"); + if (parserState.stackdepth < 0) + throw Esi::Error("ESI elements stack error, probable error in ESI template"); + assert (!failed()); debugs(86, 5, "ESIContext::addStackElement: About to add ESI Node " << element.getRaw()); if (!parserState.top()->addElement(element)) { - debugs(86, DBG_IMPORTANT, "ESIContext::addStackElement: failed to add esi node, probable error in ESI template"); - flags.error = 1; + throw Esi::Error("ESIContext::addStackElement failed, probable error in ESI template"); } else { /* added ok, push onto the stack */ parserState.stack[parserState.stackdepth] = element; @@ -1201,13 +1208,10 @@ ESIContext::addLiteral (const char *s, i assert (len); debugs(86, 5, "literal length is " << len); /* give a literal to the current element */ - assert (parserState.stackdepth <11); ESIElement::Pointer element (new esiLiteral (this, s, len)); - if (!parserState.top()->addElement(element)) { - debugs(86, DBG_IMPORTANT, "ESIContext::addLiteral: failed to add esi node, probable error in ESI template"); - flags.error = 1; - } + if (!parserState.top()->addElement(element)) + throw Esi::Error("ESIContext::addLiteral failed, probable error in ESI template"); } void @@ -1269,8 +1273,24 @@ ESIContext::parse() PROF_start(esiParsing); - while (buffered.getRaw() && !flags.error) - parseOneBuffer(); + try { + while (buffered.getRaw() && !flags.error) + parseOneBuffer(); + + } catch (Esi::ErrorDetail &errMsg) { // FIXME: non-const for c_str() + // level-2: these are protocol/syntax errors from upstream + debugs(86, 2, "WARNING: ESI syntax error: " << errMsg); + setError(); + setErrorMessage(errMsg.c_str()); + + } catch (...) { + // DBG_IMPORTANT because these are local issues the admin needs to fix + static FadingCounter logEntries; // TODO: set horizon less than infinity + if (logEntries.count(1) < 100) + debugs(86, DBG_IMPORTANT, "ERROR: ESI parser: " << CurrentException); + setError(); + setErrorMessage("ESI parser error"); + } PROF_stop(esiParsing); Index: squid-3.5.21/src/esi/Esi.h =================================================================== --- squid-3.5.21.orig/src/esi/Esi.h +++ squid-3.5.21/src/esi/Esi.h @@ -10,6 +10,11 @@ #define SQUID_ESI_H #include "clientStream.h" +#include "SBuf.h" + +#if !defined(ESI_STACK_DEPTH_LIMIT) +#define ESI_STACK_DEPTH_LIMIT 20 +#endif /* ESI.c */ extern CSR esiStreamRead; @@ -18,5 +23,14 @@ extern CSD esiStreamDetach; extern CSS esiStreamStatus; int esiEnableProcessing (HttpReply *); +namespace Esi +{ + +typedef SBuf ErrorDetail; +/// prepare an Esi::ErrorDetail for throw on ESI parser internal errors +inline Esi::ErrorDetail Error(const char *msg) { return ErrorDetail(msg); } + +} // namespace Esi + #endif /* SQUID_ESI_H */ Index: squid-3.5.21/src/esi/Expression.cc =================================================================== --- squid-3.5.21.orig/src/esi/Expression.cc +++ squid-3.5.21/src/esi/Expression.cc @@ -10,6 +10,7 @@ #include "squid.h" #include "Debug.h" +#include "esi/Esi.h" #include "esi/Expression.h" #include "profiler/Profiler.h" @@ -97,6 +98,17 @@ stackpop(stackmember * s, int *depth) cleanmember(&s[*depth]); } +static void +stackpush(stackmember *stack, stackmember &item, int *depth) +{ + if (*depth < 0) + throw Esi::Error("ESIExpression stack has negative size"); + if (*depth >= ESI_STACK_DEPTH_LIMIT) + throw Esi::Error("ESIExpression stack is full, cannot push"); + + stack[(*depth)++] = item; +} + static evaluate evalnegate; static evaluate evalliteral; static evaluate evalor; @@ -208,6 +220,11 @@ evalnegate(stackmember * stack, int *dep /* invalid stack */ return 1; + if (whereAmI < 0) + throw Esi::Error("negate expression location too small"); + if (*depth >= ESI_STACK_DEPTH_LIMIT) + throw Esi::Error("negate expression too complex"); + if (stack[whereAmI + 1].valuetype != ESI_EXPR_EXPR) /* invalid operand */ return 1; @@ -280,7 +297,7 @@ evalor(stackmember * stack, int *depth, srv.precedence = 1; - stack[(*depth)++] = srv; + stackpush(stack, srv, depth); /* we're out of way, try adding now */ if (!addmember(stack, depth, candidate)) @@ -327,7 +344,7 @@ evaland(stackmember * stack, int *depth, srv.precedence = 1; - stack[(*depth)++] = srv; + stackpush(stack, srv, depth); /* we're out of way, try adding now */ if (!addmember(stack, depth, candidate)) @@ -373,7 +390,7 @@ evallesseq(stackmember * stack, int *dep srv.precedence = 1; - stack[(*depth)++] = srv; + stackpush(stack, srv, depth); /* we're out of way, try adding now */ if (!addmember(stack, depth, candidate)) @@ -421,7 +438,7 @@ evallessthan(stackmember * stack, int *d srv.precedence = 1; - stack[(*depth)++] = srv; + stackpush(stack, srv, depth); /* we're out of way, try adding now */ if (!addmember(stack, depth, candidate)) @@ -469,7 +486,7 @@ evalmoreeq(stackmember * stack, int *dep srv.precedence = 1; - stack[(*depth)++] = srv; + stackpush(stack, srv, depth); /* we're out of way, try adding now */ if (!addmember(stack, depth, candidate)) @@ -517,7 +534,7 @@ evalmorethan(stackmember * stack, int *d srv.precedence = 1; - stack[(*depth)++] = srv; + stackpush(stack, srv, depth); /* we're out of way, try adding now */ if (!addmember(stack, depth, candidate)) @@ -566,7 +583,7 @@ evalequals(stackmember * stack, int *dep srv.precedence = 1; - stack[(*depth)++] = srv; + stackpush(stack, srv, depth); /* we're out of way, try adding now */ if (!addmember(stack, depth, candidate)) @@ -613,7 +630,7 @@ evalnotequals(stackmember * stack, int * srv.precedence = 1; - stack[(*depth)++] = srv; + stackpush(stack, srv, depth); /* we're out of way, try adding now */ if (!addmember(stack, depth, candidate)) @@ -953,6 +970,9 @@ addmember(stackmember * stack, int *stac /* !(!(a==b))) is why thats safe */ /* strictly less than until we unwind */ + if (*stackdepth >= ESI_STACK_DEPTH_LIMIT) + throw Esi::Error("ESI expression too complex to add member"); + if (candidate->precedence < stack[*stackdepth - 1].precedence || candidate->precedence < stack[*stackdepth - 2].precedence) { /* must be an operator */ @@ -968,10 +988,10 @@ addmember(stackmember * stack, int *stac return 0; } } else { - stack[(*stackdepth)++] = *candidate; + stackpush(stack, *candidate, stackdepth); } } else if (candidate->valuetype != ESI_EXPR_INVALID) - stack[(*stackdepth)++] = *candidate; + stackpush(stack, *candidate, stackdepth); return 1; } @@ -979,7 +999,7 @@ addmember(stackmember * stack, int *stac int ESIExpression::Evaluate(char const *s) { - stackmember stack[20]; + stackmember stack[ESI_STACK_DEPTH_LIMIT]; int stackdepth = 0; char const *end; PROF_start(esiExpressionEval); Index: squid-3.5.21/src/exceptions.h =================================================================== --- /dev/null +++ squid-3.5.21/src/exceptions.h @@ -0,0 +1,4 @@ +#include <iostream> + +extern std::ostream& CurrentException(std::ostream &os); +
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor