[master] 91755a0 Return 500 if we cannot decode the stored object into the resp.* This can happen in a number of obscure corner-cases, which do not warrant a panic.
Poul-Henning Kamp
phk at FreeBSD.org
Mon Nov 9 10:46:22 CET 2015
commit 91755a001a9691b3ce12c20ea1402164685c7ed9
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Mon Nov 9 09:45:13 2015 +0000
Return 500 if we cannot decode the stored object into the resp.*
This can happen in a number of obscure corner-cases, which do not
warrant a panic.
Fixes: #1807
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index 9080641..8e3fe0f 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -863,26 +863,30 @@ HTTP_Decode(struct http *to, const uint8_t *fm)
{
CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
+ AN(to->vsl);
AN(fm);
- if (vbe16dec(fm) > to->shd)
- return(-1);
- to->status = vbe16dec(fm + 2);
- fm += 4;
- for (to->nhd = 0; to->nhd < to->shd; to->nhd++) {
- if (to->nhd == HTTP_HDR_METHOD || to->nhd == HTTP_HDR_URL) {
- to->hd[to->nhd].b = NULL;
- to->hd[to->nhd].e = NULL;
- continue;
- }
- if (*fm == '\0')
- return (0);
- to->hd[to->nhd].b = (const void*)fm;
- fm = (const void*)strchr((const void*)fm, '\0');
- to->hd[to->nhd].e = (const void*)fm;
- fm++;
- if (to->vsl != NULL)
+ if (vbe16dec(fm) <= to->shd) {
+ to->status = vbe16dec(fm + 2);
+ fm += 4;
+ for (to->nhd = 0; to->nhd < to->shd; to->nhd++) {
+ if (to->nhd == HTTP_HDR_METHOD ||
+ to->nhd == HTTP_HDR_URL) {
+ to->hd[to->nhd].b = NULL;
+ to->hd[to->nhd].e = NULL;
+ continue;
+ }
+ if (*fm == '\0')
+ return (0);
+ to->hd[to->nhd].b = (const void*)fm;
+ fm = (const void*)strchr((const void*)fm, '\0');
+ to->hd[to->nhd].e = (const void*)fm;
+ fm++;
http_VSLH(to, to->nhd);
+ }
}
+ VSLb(to->vsl, SLT_Error,
+ "Too many headers to Decode object (%u vs. %u)",
+ vbe16dec(fm), to->shd);
return (-1);
}
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index b7afe84..da59078 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -129,8 +129,12 @@ cnt_deliver(struct worker *wrk, struct req *req)
EXP_Touch(req->objcore, req->t_prev);
HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod);
- AZ(HTTP_Decode(req->resp,
- ObjGetattr(req->wrk, req->objcore, OA_HEADERS, NULL)));
+ if (HTTP_Decode(req->resp,
+ ObjGetattr(req->wrk, req->objcore, OA_HEADERS, NULL))) {
+ req->err_code = 500;
+ req->req_step = R_STP_SYNTH;
+ return (REQ_FSM_MORE);
+ }
http_ForceField(req->resp, HTTP_HDR_PROTO, "HTTP/1.1");
if (req->is_hit)
@@ -493,9 +497,9 @@ cnt_miss(struct worker *wrk, struct req *req)
case VCL_RET_FETCH:
wrk->stats->cache_miss++;
VBF_Fetch(wrk, req, req->objcore, req->stale_oc, VBF_NORMAL);
- req->req_step = R_STP_FETCH;
if (req->stale_oc != NULL)
(void)HSH_DerefObjCore(wrk, &req->stale_oc);
+ req->req_step = R_STP_FETCH;
return (REQ_FSM_MORE);
case VCL_RET_SYNTH:
req->req_step = R_STP_SYNTH;
diff --git a/bin/varnishtest/tests/r01807.vtc b/bin/varnishtest/tests/r01807.vtc
new file mode 100644
index 0000000..4696cd1
--- /dev/null
+++ b/bin/varnishtest/tests/r01807.vtc
@@ -0,0 +1,50 @@
+varnishtest "Decreasing http_max_hdr"
+
+server s1 {
+ rxreq
+ txresp \
+ -hdr "h00: 00" \
+ -hdr "h01: 01" \
+ -hdr "h02: 02" \
+ -hdr "h03: 03" \
+ -hdr "h04: 04" \
+ -hdr "h05: 05" \
+ -hdr "h06: 06" \
+ -hdr "h07: 07" \
+ -hdr "h08: 08" \
+ -hdr "h09: 09" \
+ -hdr "h10: 10" \
+ -hdr "h11: 11" \
+ -hdr "h12: 12" \
+ -hdr "h13: 13" \
+ -hdr "h14: 14" \
+ -hdr "h15: 15" \
+ -hdr "h16: 16" \
+ -hdr "h17: 17" \
+ -hdr "h18: 18" \
+ -hdr "h19: 19" \
+ -hdr "h20: 20" \
+ -hdr "h21: 21" \
+ -hdr "h22: 22" \
+ -hdr "h23: 23" \
+ -hdr "h24: 24"
+} -start
+
+varnish v1 -vcl+backend {
+} -start
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.status == 200
+ expect resp.http.h24 == 24
+} -run
+
+varnish v1 -cliok {param.set http_max_hdr 32}
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.status == 500
+} -run
+
More information about the varnish-commit
mailing list