!21 [sync] PR-20: fix CVE-2021-36740

From: @openeuler-sync-bot
Reviewed-by: @ruebb
Signed-off-by: @ruebb
This commit is contained in:
openeuler-ci-bot 2021-09-23 06:14:50 +00:00 committed by Gitee
commit f6f36b106e
5 changed files with 227 additions and 1 deletions

27
CVE-2021-36740-1.patch Normal file
View File

@ -0,0 +1,27 @@
From cda1921004f10d3a56e6e044426473d99c88fa56 Mon Sep 17 00:00:00 2001
From: Poul-Henning Kamp <phk@FreeBSD.org>
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

29
CVE-2021-36740-2.patch Normal file
View File

@ -0,0 +1,29 @@
From f3e9ca6abc4a03e48df4e9894323cad25472793f Mon Sep 17 00:00:00 2001
From: Dag Haavi Finstad <daghf@varnish-software.com>
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

29
CVE-2021-36740-3.patch Normal file
View File

@ -0,0 +1,29 @@
From 799f68e918fd3fb8a373338c7886042317e1910c Mon Sep 17 00:00:00 2001
From: Dag Haavi Finstad <daghf@varnish-software.com>
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

134
CVE-2021-36740-4.patch Normal file
View File

@ -0,0 +1,134 @@
From 9be22198e258d0e7a5c41f4291792214a29405cf Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
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

View File

@ -1,7 +1,7 @@
Name: varnish Name: varnish
Summary: A web application accelerator Summary: A web application accelerator
Version: 6.0.0 Version: 6.0.0
Release: 7 Release: 8
License: BSD License: BSD
URL: https://www.varnish-cache.org/ URL: https://www.varnish-cache.org/
Source0: http://varnish-cache.org/_downloads/varnish-%{version}.tgz Source0: http://varnish-cache.org/_downloads/varnish-%{version}.tgz
@ -19,6 +19,10 @@ Patch0007: CVE-2019-15892-5.patch
Patch0008: CVE-2019-15892-6.patch Patch0008: CVE-2019-15892-6.patch
Patch0009: CVE-2019-15892-7.patch Patch0009: CVE-2019-15892-7.patch
Patch0010: CVE-2019-15892-8.patch Patch0010: CVE-2019-15892-8.patch
Patch0011: CVE-2021-36740-1.patch
Patch0012: CVE-2021-36740-2.patch
Patch0013: CVE-2021-36740-3.patch
Patch0014: CVE-2021-36740-4.patch
BuildRequires: python3-sphinx python3-docutils pkgconfig make graphviz nghttp2 systemd-units BuildRequires: python3-sphinx python3-docutils pkgconfig make graphviz nghttp2 systemd-units
BuildRequires: ncurses-devel pcre-devel libedit-devel gcc BuildRequires: ncurses-devel pcre-devel libedit-devel gcc
@ -166,6 +170,9 @@ test -f /etc/varnish/secret || (uuidgen > /etc/varnish/secret && chmod 0600 /etc
%{_mandir}/man7/*.7* %{_mandir}/man7/*.7*
%changelog %changelog
* Wed Sep 22 2021 yaoxin <yaoxin30@huawei.com> - 6.0.0-8
- Fix CVE-2021-36740
* Mon May 31 2021 huanghaitao <huanghaitao8@huawei.com> - 6.0.0-7 * Mon May 31 2021 huanghaitao <huanghaitao8@huawei.com> - 6.0.0-7
- Completing build dependencies to fix gcc compiler missing error - Completing build dependencies to fix gcc compiler missing error