[master] e8d8266 Test for MAX_FRAME_SIZE in h2_frame_complete
Dag Haavi Finstad
daghf at varnish-software.com
Tue Apr 17 11:57:09 UTC 2018
commit e8d8266412b900f87b5602f883c0639e27f9ca84
Author: Dag Haavi Finstad <daghf at varnish-software.com>
Date: Tue Apr 17 13:53:26 2018 +0200
Test for MAX_FRAME_SIZE in h2_frame_complete
Return HTC_S_OVERFLOW if exceeded.
This is a quick-fix for #2624, where we close the connection if a client
exceeds MAX_FRAME_SIZE. More proper handling with draining the rest of
the frame for the specific frames types that allow it (rfc7540 section
4.2) to come later.
Fixes: #2624
diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c
index 39d97e6..6a0c92b 100644
--- a/bin/varnishd/http2/cache_http2_proto.c
+++ b/bin/varnishd/http2/cache_http2_proto.c
@@ -814,14 +814,18 @@ h2_req_fail(struct req *req, enum sess_close reason)
static enum htc_status_e v_matchproto_(htc_complete_f)
h2_frame_complete(struct http_conn *htc)
{
+ struct h2_sess *h2;
int l;
unsigned u;
CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
+ CAST_OBJ_NOTNULL(h2, htc->priv, H2_SESS_MAGIC);
l = htc->rxbuf_e - htc->rxbuf_b;
if (l < 9)
return (HTC_S_MORE);
u = vbe32dec(htc->rxbuf_b) >> 8;
+ if (l > h2->local_settings.max_frame_size + 9)
+ return (HTC_S_OVERFLOW);
if (l < u + 9) // XXX: Only for !DATA frames
return (HTC_S_MORE);
return (HTC_S_COMPLETE);
@@ -1032,6 +1036,7 @@ h2_rxframe(struct worker *wrk, struct h2_sess *h2)
/* FALLTHROUGH */
default:
+ /* XXX: HTC_S_OVERFLOW / FRAME_SIZE_ERROR handling */
Lck_Lock(&h2->sess->mtx);
VSLb(h2->vsl, SLT_Debug, "H2: No frame (hs=%d)", hs);
h2->error = H2CE_NO_ERROR;
diff --git a/bin/varnishd/http2/cache_http2_session.c b/bin/varnishd/http2/cache_http2_session.c
index e34f824..b2ab70f 100644
--- a/bin/varnishd/http2/cache_http2_session.c
+++ b/bin/varnishd/http2/cache_http2_session.c
@@ -349,6 +349,8 @@ h2_new_session(struct worker *wrk, void *arg)
h2 = h2_init_sess(wrk, sp, &h2s,
req->err_code == H2_PU_MARKER ? req : NULL);
h2->req0 = h2_new_req(wrk, h2, 0, NULL);
+ AZ(h2->htc->priv);
+ h2->htc->priv = h2;
if (req->err_code == H2_OU_MARKER && !h2_ou_session(wrk, h2, req)) {
assert(h2->refcnt == 1);
More information about the varnish-commit
mailing list