Commit 2dc7d093 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp Committed by Lasse Karstensen

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
parent 5a67684d
...@@ -863,26 +863,30 @@ HTTP_Decode(struct http *to, const uint8_t *fm) ...@@ -863,26 +863,30 @@ HTTP_Decode(struct http *to, const uint8_t *fm)
{ {
CHECK_OBJ_NOTNULL(to, HTTP_MAGIC); CHECK_OBJ_NOTNULL(to, HTTP_MAGIC);
AN(to->vsl);
AN(fm); AN(fm);
if (vbe16dec(fm) > to->shd) if (vbe16dec(fm) <= to->shd) {
return(-1); to->status = vbe16dec(fm + 2);
to->status = vbe16dec(fm + 2); fm += 4;
fm += 4; for (to->nhd = 0; to->nhd < to->shd; to->nhd++) {
for (to->nhd = 0; to->nhd < to->shd; to->nhd++) { if (to->nhd == HTTP_HDR_METHOD ||
if (to->nhd == HTTP_HDR_METHOD || to->nhd == HTTP_HDR_URL) { to->nhd == HTTP_HDR_URL) {
to->hd[to->nhd].b = NULL; to->hd[to->nhd].b = NULL;
to->hd[to->nhd].e = NULL; to->hd[to->nhd].e = NULL;
continue; continue;
} }
if (*fm == '\0') if (*fm == '\0')
return (0); return (0);
to->hd[to->nhd].b = (const void*)fm; to->hd[to->nhd].b = (const void*)fm;
fm = (const void*)strchr((const void*)fm, '\0'); fm = (const void*)strchr((const void*)fm, '\0');
to->hd[to->nhd].e = (const void*)fm; to->hd[to->nhd].e = (const void*)fm;
fm++; fm++;
if (to->vsl != NULL)
http_VSLH(to, to->nhd); 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); return (-1);
} }
......
...@@ -129,8 +129,12 @@ cnt_deliver(struct worker *wrk, struct req *req) ...@@ -129,8 +129,12 @@ cnt_deliver(struct worker *wrk, struct req *req)
EXP_Touch(req->objcore, req->t_prev); EXP_Touch(req->objcore, req->t_prev);
HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod); HTTP_Setup(req->resp, req->ws, req->vsl, SLT_RespMethod);
AZ(HTTP_Decode(req->resp, if (HTTP_Decode(req->resp,
ObjGetattr(req->wrk, req->objcore, OA_HEADERS, NULL))); 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"); http_ForceField(req->resp, HTTP_HDR_PROTO, "HTTP/1.1");
if (req->is_hit) if (req->is_hit)
...@@ -493,9 +497,9 @@ cnt_miss(struct worker *wrk, struct req *req) ...@@ -493,9 +497,9 @@ cnt_miss(struct worker *wrk, struct req *req)
case VCL_RET_FETCH: case VCL_RET_FETCH:
wrk->stats->cache_miss++; wrk->stats->cache_miss++;
VBF_Fetch(wrk, req, req->objcore, req->stale_oc, VBF_NORMAL); VBF_Fetch(wrk, req, req->objcore, req->stale_oc, VBF_NORMAL);
req->req_step = R_STP_FETCH;
if (req->stale_oc != NULL) if (req->stale_oc != NULL)
(void)HSH_DerefObjCore(wrk, &req->stale_oc); (void)HSH_DerefObjCore(wrk, &req->stale_oc);
req->req_step = R_STP_FETCH;
return (REQ_FSM_MORE); return (REQ_FSM_MORE);
case VCL_RET_SYNTH: case VCL_RET_SYNTH:
req->req_step = R_STP_SYNTH; req->req_step = R_STP_SYNTH;
......
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment