[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