From 1f77868dfacbdb62670588c0fcc3cd0cceb27f98 Mon Sep 17 00:00:00 2001 From: starlet-dx <15929766099@163.com> Date: Thu, 23 Sep 2021 09:49:26 +0800 Subject: [PATCH] fix CVE-2021-36740 --- CVE-2021-36740-1.patch | 27 +++++++++ CVE-2021-36740-2.patch | 29 +++++++++ CVE-2021-36740-3.patch | 29 +++++++++ CVE-2021-36740-4.patch | 134 +++++++++++++++++++++++++++++++++++++++++ varnish.spec | 9 ++- 5 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 CVE-2021-36740-1.patch create mode 100644 CVE-2021-36740-2.patch create mode 100644 CVE-2021-36740-3.patch create mode 100644 CVE-2021-36740-4.patch diff --git a/CVE-2021-36740-1.patch b/CVE-2021-36740-1.patch new file mode 100644 index 0000000..886c682 --- /dev/null +++ b/CVE-2021-36740-1.patch @@ -0,0 +1,27 @@ +From cda1921004f10d3a56e6e044426473d99c88fa56 Mon Sep 17 00:00:00 2001 +From: Poul-Henning Kamp +Date: Fri, 22 Feb 2019 07:47:49 +0000 +Subject: [PATCH 1/1] We cannot trust the mailcall to be empty just because we + got the mutex, for instance the VFP might have nipped out for more storage. + +Fixes: #2572 +--- + bin/varnishd/http2/cache_http2_proto.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c +index 39d97e6..26bfae8 100644 +--- a/bin/varnishd/http2/cache_http2_proto.c ++++ b/bin/varnishd/http2/cache_http2_proto.c +@@ -701,6 +701,8 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) + if (r2 == NULL) + return (0); + Lck_Lock(&h2->sess->mtx); ++ while (h2->mailcall != NULL && h2->error == 0 && r2->error == 0) ++ AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0)); + AZ(h2->mailcall); + h2->mailcall = r2; + h2->req0->r_window -= h2->rxf_len; +-- +2.27.0 + diff --git a/CVE-2021-36740-2.patch b/CVE-2021-36740-2.patch new file mode 100644 index 0000000..83feda1 --- /dev/null +++ b/CVE-2021-36740-2.patch @@ -0,0 +1,29 @@ +From f3e9ca6abc4a03e48df4e9894323cad25472793f Mon Sep 17 00:00:00 2001 +From: Dag Haavi Finstad +Date: Tue, 24 Sep 2019 16:50:33 +0200 +Subject: [PATCH 1/1] Add missing error handling in h2_rx_data + +A failing write on a different stream will set h2->error, which would +cause us to panic here on the following AZ(h2->mailcall). + +Fixes: #3040 +--- + bin/varnishd/http2/cache_http2_proto.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c +index 527fb8e61..902c1e08c 100644 +--- a/bin/varnishd/http2/cache_http2_proto.c ++++ b/bin/varnishd/http2/cache_http2_proto.c +@@ -703,6 +703,8 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) + Lck_Lock(&h2->sess->mtx); + while (h2->mailcall != NULL && h2->error == 0 && r2->error == 0) + AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0)); ++ if (h2->error || r2->error) ++ return (h2->error ? h2->error : r2->error); + AZ(h2->mailcall); + h2->mailcall = r2; + h2->req0->r_window -= h2->rxf_len; +-- +2.27.0 + diff --git a/CVE-2021-36740-3.patch b/CVE-2021-36740-3.patch new file mode 100644 index 0000000..c11f209 --- /dev/null +++ b/CVE-2021-36740-3.patch @@ -0,0 +1,29 @@ +From 799f68e918fd3fb8a373338c7886042317e1910c Mon Sep 17 00:00:00 2001 +From: Dag Haavi Finstad +Date: Mon, 28 Oct 2019 12:13:43 +0100 +Subject: [PATCH 1/1] h2_rx_data: Remember to drop the lock before returning + +Fixes: #3086 +--- + bin/varnishd/http2/cache_http2_proto.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c +index 902c1e08c..0f2a21230 100644 +--- a/bin/varnishd/http2/cache_http2_proto.c ++++ b/bin/varnishd/http2/cache_http2_proto.c +@@ -703,8 +703,10 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) + Lck_Lock(&h2->sess->mtx); + while (h2->mailcall != NULL && h2->error == 0 && r2->error == 0) + AZ(Lck_CondWait(h2->cond, &h2->sess->mtx, 0)); +- if (h2->error || r2->error) ++ if (h2->error || r2->error) { ++ Lck_Unlock(&h2->sess->mtx); + return (h2->error ? h2->error : r2->error); ++ } + AZ(h2->mailcall); + h2->mailcall = r2; + h2->req0->r_window -= h2->rxf_len; +-- +2.27.0 + diff --git a/CVE-2021-36740-4.patch b/CVE-2021-36740-4.patch new file mode 100644 index 0000000..8bfecc4 --- /dev/null +++ b/CVE-2021-36740-4.patch @@ -0,0 +1,134 @@ +From 9be22198e258d0e7a5c41f4291792214a29405cf Mon Sep 17 00:00:00 2001 +From: Martin Blix Grydeland +Date: Tue, 22 Jun 2021 11:47:55 +0200 +Subject: [PATCH] Take content length into account on H/2 request bodies + +When receiving H/2 data frames, make sure to take the advertised content +length into account, and fail appropriately if the combined sum of the +data frames does not match the content length. +--- + bin/varnishd/http2/cache_http2.h | 2 ++ + bin/varnishd/http2/cache_http2_proto.c | 46 +++++++++++++++++++++----- + 2 files changed, 40 insertions(+), 8 deletions(-) + +diff --git a/bin/varnishd/http2/cache_http2.h b/bin/varnishd/http2/cache_http2.h +index cfe8598..9f4fc0c 100644 +--- a/bin/varnishd/http2/cache_http2.h ++++ b/bin/varnishd/http2/cache_http2.h +@@ -132,6 +132,8 @@ struct h2_req { + /* Where to wake this stream up */ + struct worker *wrk; + ++ ssize_t reqbody_bytes; ++ + VTAILQ_ENTRY(h2_req) tx_list; + h2_error error; + }; +diff --git a/bin/varnishd/http2/cache_http2_proto.c b/bin/varnishd/http2/cache_http2_proto.c +index bb0f5f9..3526b49 100644 +--- a/bin/varnishd/http2/cache_http2_proto.c ++++ b/bin/varnishd/http2/cache_http2_proto.c +@@ -528,7 +528,7 @@ h2_end_headers(struct worker *wrk, struct h2_sess *h2, + struct req *req, struct h2_req *r2) + { + h2_error h2e; +- const char *b; ++ ssize_t cl; + + ASSERT_RXTHR(h2); + assert(r2->state == H2_S_OPEN); +@@ -551,14 +551,24 @@ h2_end_headers(struct worker *wrk, struct h2_sess *h2, + // XXX: Have I mentioned H/2 Is hodge-podge ? + http_CollectHdrSep(req->http, H_Cookie, "; "); // rfc7540,l,3114,3120 + ++ cl = http_GetContentLength(req->http); ++ assert(cl >= -2); ++ if (cl == -2) { ++ VSLb(h2->vsl, SLT_Debug, "Non-parseable Content-Length"); ++ return (H2SE_PROTOCOL_ERROR); ++ } ++ + if (req->req_body_status == REQ_BODY_INIT) { +- if (!http_GetHdr(req->http, H_Content_Length, &b)) ++ if (cl == -1) + req->req_body_status = REQ_BODY_WITHOUT_LEN; + else + req->req_body_status = REQ_BODY_WITH_LEN; ++ req->htc->content_length = cl; + } else { ++ /* A HEADER frame contained END_STREAM */ + assert (req->req_body_status == REQ_BODY_NONE); +- if (http_GetContentLength(req->http) > 0) ++ r2->state = H2_S_CLOS_REM; ++ if (cl > 0) + return (H2CE_PROTOCOL_ERROR); //rfc7540,l,1838,1840 + } + +@@ -695,6 +705,7 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) + int w1 = 0, w2 = 0; + char buf[4]; + unsigned wi; ++ ssize_t cl; + + (void)wrk; + ASSERT_RXTHR(h2); +@@ -707,6 +718,23 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) + Lck_Unlock(&h2->sess->mtx); + return (h2->error ? h2->error : r2->error); + } ++ ++ r2->reqbody_bytes += h2->rxf_len; ++ if (h2->rxf_flags & H2FF_DATA_END_STREAM) ++ r2->state = H2_S_CLOS_REM; ++ cl = r2->req->htc->content_length; ++ if (cl >= 0 && (r2->reqbody_bytes > cl || ++ (r2->state >= H2_S_CLOS_REM && r2->reqbody_bytes != cl))) { ++ VSLb(h2->vsl, SLT_Debug, ++ "H2: stream %u: Received data and Content-Length" ++ " mismatch", h2->rxf_stream); ++ r2->error = H2SE_PROTOCOL_ERROR; // rfc7540,l,3150,3163 ++ if (r2->cond) ++ AZ(pthread_cond_signal(r2->cond)); ++ Lck_Unlock(&h2->sess->mtx); ++ return (H2SE_PROTOCOL_ERROR); ++ } ++ + AZ(h2->mailcall); + h2->mailcall = r2; + h2->req0->r_window -= h2->rxf_len; +@@ -725,6 +753,8 @@ h2_rx_data(struct worker *wrk, struct h2_sess *h2, struct h2_req *r2) + r2->r_window += wi; + w2 = 1; + } ++ ++ + Lck_Unlock(&h2->sess->mtx); + + if (w1 || w2) { +@@ -747,7 +777,7 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) + struct h2_req *r2; + struct h2_sess *h2; + unsigned l; +- enum vfp_status retval = VFP_OK; ++ enum vfp_status retval; + + CHECK_OBJ_NOTNULL(vc, VFP_CTX_MAGIC); + CHECK_OBJ_NOTNULL(vfe, VFP_ENTRY_MAGIC); +@@ -776,10 +806,10 @@ h2_vfp_body(struct vfp_ctx *vc, struct vfp_entry *vfe, void *ptr, ssize_t *lp) + h2->rxf_len -= l; + } + *lp = l; +- if (h2->rxf_len == 0) { +- if (h2->rxf_flags & H2FF_DATA_END_STREAM) +- retval = VFP_END; +- } ++ if (h2->rxf_len == 0 && r2->state >= H2_S_CLOS_REM) ++ retval = VFP_END; ++ else ++ retval = VFP_OK; + h2->mailcall = NULL; + AZ(pthread_cond_signal(h2->cond)); + } +-- +2.27.0 + diff --git a/varnish.spec b/varnish.spec index ccea49f..3433211 100644 --- a/varnish.spec +++ b/varnish.spec @@ -1,7 +1,7 @@ Name: varnish Summary: A web application accelerator Version: 6.0.0 -Release: 5 +Release: 6 License: BSD URL: https://www.varnish-cache.org/ Source0: http://varnish-cache.org/_downloads/varnish-%{version}.tgz @@ -18,6 +18,10 @@ Patch0006: CVE-2019-15892-5.patch Patch0007: CVE-2019-15892-6.patch Patch0008: CVE-2019-15892-7.patch Patch0009: CVE-2019-15892-8.patch +Patch0010: CVE-2021-36740-1.patch +Patch0011: CVE-2021-36740-2.patch +Patch0012: CVE-2021-36740-3.patch +Patch0013: CVE-2021-36740-4.patch BuildRequires: python3-sphinx python3-docutils pkgconfig make graphviz nghttp2 systemd-units BuildRequires: ncurses-devel pcre-devel libedit-devel @@ -165,6 +169,9 @@ test -f /etc/varnish/secret || (uuidgen > /etc/varnish/secret && chmod 0600 /etc %{_mandir}/man7/*.7* %changelog +* Thu Sep 23 2021 yaoxin - 6.0.0-6 +- Fix CVE-2021-36740 + * Tue Jan 19 2021 wangyue - 6.0.0-5 - Fix CVE-2019-15892 -- Gitee