Upgrade varnish to 7.0.1

This commit is contained in:
starlet-dx 2021-12-29 15:13:19 +08:00
parent f6f36b106e
commit 6dbcc2d869
17 changed files with 12 additions and 847 deletions

View File

@ -1,221 +0,0 @@
From 177e17c8f129c58daeeb98055761ee65ab5c3dfc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alf-Andr=C3=A9=20Walla?= <fwsgonzo@hotmail.com>
Date: Tue, 13 Aug 2019 12:52:39 +0200
Subject: [PATCH] Add bounds-checking to vct_iscrlf and vct_skipcrlf
The macros vct_iscrlf() and vct_skipcrlf() may look at one or two bytes
after its pointer value, causing OOB reads. This would allow
http1_dissect_hdrs to wrongly see a CRLF when one wasn't there (the last
LF left over in the bufer from the previous request).
Change the macros to inline functions, and harden them by always sending
the end pointer so that they can't overflow.
vct_iscrlf() will return an int value of 0 for no [CR]LF, 1 for LF and 2
for CRLF.
vct_skipcrlf() will return the pointer having been skipped 0, 1 or 2
bytes.
---
bin/varnishd/http1/cache_http1_proto.c | 16 +++++++++-------
bin/varnishtest/vtc_http.c | 26 ++++++++++++++------------
include/vct.h | 19 +++++++++++++++++--
bin/varnishtest/vtc_subr.c | 3 ++-
4 files changed, 42 insertions(+), 22 deletions(-)
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index dd81863d32..5d99da47a8 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -121,31 +121,31 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc,
/* Find end of next header */
q = r = p;
- if (vct_iscrlf(p))
+ if (vct_iscrlf(p, htc->rxbuf_e))
break;
while (r < htc->rxbuf_e) {
if (!vct_isctl(*r) || vct_issp(*r)) {
r++;
continue;
}
- if (!vct_iscrlf(r)) {
+ if (!vct_iscrlf(r, htc->rxbuf_e)) {
VSLb(hp->vsl, SLT_BogoHeader,
"Header has ctrl char 0x%02x", *r);
return (400);
}
q = r;
assert(r < htc->rxbuf_e);
- r += vct_skipcrlf(r);
+ r = vct_skipcrlf(r, htc->rxbuf_e);
if (r >= htc->rxbuf_e)
break;
- if (vct_iscrlf(r))
+ if (vct_iscrlf(r, htc->rxbuf_e))
break;
/* If line does not continue: got it. */
if (!vct_issp(*r))
break;
/* Clear line continuation LWS to spaces */
- while (vct_islws(*q))
+ while (q < htc->rxbuf_e && vct_islws(*q))
*q++ = ' ';
}
@@ -275,7 +275,7 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
hp->hd[hf[2]].b = p;
/* Third field is optional and cannot contain CTL except TAB */
- for (; !vct_iscrlf(p); p++) {
+ for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) {
if (vct_isctl(*p) && !vct_issp(*p)) {
hp->hd[hf[2]].b = NULL;
return (400);
@@ -284,7 +284,9 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
hp->hd[hf[2]].e = p;
/* Skip CRLF */
- i = vct_skipcrlf(p);
+ i = vct_iscrlf(p, htc->rxbuf_e);
+ if (!i)
+ return (400);
*p = '\0';
p += i;
diff --git a/bin/varnishtest/vtc_http.c b/bin/varnishtest/vtc_http.c
index 616cb459e1..e17643f8eb 100644
--- a/bin/varnishtest/vtc_http.c
+++ b/bin/varnishtest/vtc_http.c
@@ -409,6 +409,7 @@ http_splitheader(struct http *hp, int req)
char *p, *q, **hh;
int n;
char buf[20];
+ const char* rxbuf_e = &hp->rxbuf[hp->prxbuf];
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
if (req) {
@@ -428,20 +429,20 @@ http_splitheader(struct http *hp, int req)
hh[n++] = p;
while (!vct_islws(*p))
p++;
- AZ(vct_iscrlf(p));
+ AZ(vct_iscrlf(p, rxbuf_e));
*p++ = '\0';
/* URL/STATUS */
while (vct_issp(*p)) /* XXX: H space only */
p++;
- AZ(vct_iscrlf(p));
+ AZ(vct_iscrlf(p, rxbuf_e));
hh[n++] = p;
while (!vct_islws(*p))
p++;
- if (vct_iscrlf(p)) {
+ if (vct_iscrlf(p, rxbuf_e)) {
hh[n++] = NULL;
q = p;
- p += vct_skipcrlf(p);
+ p = vct_skipcrlf(p, rxbuf_e);
*q = '\0';
} else {
*p++ = '\0';
@@ -449,26 +450,26 @@ http_splitheader(struct http *hp, int req)
while (vct_issp(*p)) /* XXX: H space only */
p++;
hh[n++] = p;
- while (!vct_iscrlf(p))
+ while (!vct_iscrlf(p, rxbuf_e))
p++;
q = p;
- p += vct_skipcrlf(p);
+ p = vct_skipcrlf(p, rxbuf_e);
*q = '\0';
}
assert(n == 3);
while (*p != '\0') {
assert(n < MAX_HDR);
- if (vct_iscrlf(p))
+ if (vct_iscrlf(p, rxbuf_e))
break;
hh[n++] = p++;
- while (*p != '\0' && !vct_iscrlf(p))
+ while (*p != '\0' && !vct_iscrlf(p, rxbuf_e))
p++;
q = p;
- p += vct_skipcrlf(p);
+ p = vct_skipcrlf(p, rxbuf_e);
*q = '\0';
}
- p += vct_skipcrlf(p);
+ p = vct_skipcrlf(p, rxbuf_e);
assert(*p == '\0');
for (n = 0; n < 3 || hh[n] != NULL; n++) {
@@ -564,15 +565,16 @@ http_rxchunk(struct http *hp)
vtc_dump(hp->vl, 4, "chunk", hp->rxbuf + l, i);
}
l = hp->prxbuf;
+
if (http_rxchar(hp, 2, 0) < 0)
return (-1);
- if (!vct_iscrlf(hp->rxbuf + l)) {
+ if (!vct_iscrlf(&hp->rxbuf[l], &hp->rxbuf[hp->prxbuf])) {
vtc_log(hp->vl, hp->fatal,
"Wrong chunk tail[0] = %02x",
hp->rxbuf[l] & 0xff);
return (-1);
}
- if (!vct_iscrlf(hp->rxbuf + l + 1)) {
+ if (!vct_iscrlf(&hp->rxbuf[l + 1], &hp->rxbuf[hp->prxbuf])) {
vtc_log(hp->vl, hp->fatal,
"Wrong chunk tail[1] = %02x",
hp->rxbuf[l + 1] & 0xff);
diff --git a/include/vct.h b/include/vct.h
index 24143a3322..1b7ffbd4f5 100644
--- a/include/vct.h
+++ b/include/vct.h
@@ -76,7 +76,22 @@ vct_is(int x, uint16_t y)
#define vct_isxmlname(x) vct_is(x, VCT_XMLNAMESTART | VCT_XMLNAME)
#define vct_istchar(x) vct_is(x, VCT_ALPHA | VCT_DIGIT | VCT_TCHAR)
-#define vct_iscrlf(p) (((p)[0] == 0x0d && (p)[1] == 0x0a) || (p)[0] == 0x0a)
+static inline int
+vct_iscrlf(const char* p, const char* end)
+{
+ assert(p <= end);
+ if (p == end)
+ return (0);
+ if ((p[0] == 0x0d && (p+1 < end) && p[1] == 0x0a)) // CR LF
+ return (2);
+ if (p[0] == 0x0a) // LF
+ return (1);
+ return (0);
+}
/* NB: VCT always operate in ASCII, don't replace 0x0d with \r etc. */
-#define vct_skipcrlf(p) ((p)[0] == 0x0d && (p)[1] == 0x0a ? 2 : 1)
+static inline char*
+vct_skipcrlf(char* p, const char* end)
+{
+ return (p + vct_iscrlf(p, end));
+}
diff --git a/bin/varnishtest/vtc_subr.c b/bin/varnishtest/vtc_subr.c
index 2c1439a..f200981 100644
--- a/bin/varnishtest/vtc_subr.c
+++ b/bin/varnishtest/vtc_subr.c
@@ -33,10 +33,11 @@
#include <string.h>
#include <stdint.h>
+#include "vtc.h"
+
#include "vct.h"
#include "vnum.h"
#include "vre.h"
-#include "vtc.h"
struct vsb *
vtc_hex_to_bin(struct vtclog *vl, const char *arg)

View File

@ -1,25 +0,0 @@
From f98c250300bd7303bb7b706384ec153101a3eab0 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 15 Aug 2019 10:44:00 +0200
Subject: [PATCH] Allow a NULL value in http_Proto
The proto field is optional in HTTP, so it may not be set. Set the proto
to 0 also for a NULL value instead of segfaulting if it were NULL.
---
bin/varnishd/cache/cache_http.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index 23eaa0b183..070ead2e6b 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -212,7 +212,8 @@ http_Proto(struct http *to)
fm = to->hd[HTTP_HDR_PROTO].b;
- if ((fm[0] == 'H' || fm[0] == 'h') &&
+ if (fm != NULL &&
+ (fm[0] == 'H' || fm[0] == 'h') &&
(fm[1] == 'T' || fm[1] == 't') &&
(fm[2] == 'T' || fm[2] == 't') &&
(fm[3] == 'P' || fm[3] == 'p') &&

View File

@ -1,48 +0,0 @@
From 3dc8c15adc23456f494fd23455b2251efe275eda Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 15 Aug 2019 10:56:58 +0200
Subject: [PATCH] Fix http1_splitline parsing of 2 field HTTP proto lines using
NLNL
When parsing a request like this, "GET /\n\n", the first NL would be
overwritten by nul guard inserted after the 2nd field, and the second NL
would be overwritten by the nul guard after the missing 3rd field. This
would cause http1_dissect_hdrs to attempt to decode the body as headers.
---
bin/varnishd/http1/cache_http1_proto.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index 5d99da47a8..af9ca3898c 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -224,7 +224,7 @@ static uint16_t
http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
unsigned maxhdr)
{
- char *p;
+ char *p, *q;
int i;
assert(hf == HTTP1_Req || hf == HTTP1_Resp);
@@ -265,14 +265,19 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
hp->hd[hf[1]].e = p;
if (!Tlen(hp->hd[hf[1]]))
return (400);
- *p++ = '\0';
/* Skip SP */
+ q = p;
for (; vct_issp(*p); p++) {
if (vct_isctl(*p))
return (400);
}
hp->hd[hf[2]].b = p;
+ if (q < p)
+ *q = '\0'; /* Nul guard for the 2nd field. If q == p
+ * (the third optional field is not
+ * present), the last nul guard will
+ * cover this field. */
/* Third field is optional and cannot contain CTL except TAB */
for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) {

View File

@ -1,46 +0,0 @@
From 73befed1a6950f5312e3a422dde82a7bb5a8bbe3 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 15 Aug 2019 11:16:22 +0200
Subject: [PATCH] Do not set the proto txt.b value when third field is missing
In http1_splitline, if the third field is missing, we would still set the
txt.b value to where the field would have been, with a NULL txt.e
entry. This would cause http_Proto to attempt to parse the values
there. Fix this by only setting the .b and .e if the third field was
present.
---
bin/varnishd/http1/cache_http1_proto.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index af9ca3898c..e55555bf19 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -272,7 +272,6 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
if (vct_isctl(*p))
return (400);
}
- hp->hd[hf[2]].b = p;
if (q < p)
*q = '\0'; /* Nul guard for the 2nd field. If q == p
* (the third optional field is not
@@ -280,13 +279,15 @@ http1_splitline(struct http *hp, struct http_conn *htc, const int *hf,
* cover this field. */
/* Third field is optional and cannot contain CTL except TAB */
+ q = p;
for (; p < htc->rxbuf_e && !vct_iscrlf(p, htc->rxbuf_e); p++) {
- if (vct_isctl(*p) && !vct_issp(*p)) {
- hp->hd[hf[2]].b = NULL;
+ if (vct_isctl(*p) && !vct_issp(*p))
return (400);
- }
}
- hp->hd[hf[2]].e = p;
+ if (p > q) {
+ hp->hd[hf[2]].b = q;
+ hp->hd[hf[2]].e = p;
+ }
/* Skip CRLF */
i = vct_iscrlf(p, htc->rxbuf_e);

View File

@ -1,41 +0,0 @@
From 3eb7a04587d235bec5a312d3eae652abd8a63a14 Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 15 Aug 2019 11:19:41 +0200
Subject: [PATCH] Be stricter on final [CR]LF parsing in http1_dissect_hdrs
The end of http1_dissect_hdrs ends with skipping over the final [CR]LF
that marks then end of the headers. Currently that skip is optional, that
is, it is skipped if it was present.
This patch adds an assert if the final [CR]LF is not found when finishing
the parsing. HTTP1_Complete guarantees that it is there, if not we would
not have started parsing the request or response in the first place, and
if it is missing, there must be an error in the parsing leading up to it.
---
bin/varnishd/http1/cache_http1_proto.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index e55555bf19..e5203a94ec 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -117,6 +117,7 @@ http1_dissect_hdrs(struct http *hp, char
unsigned maxhdr)
{
char *q, *r;
+ int i;
assert(p > htc->rxbuf_b);
assert(p <= htc->rxbuf_e);
@@ -213,8 +214,9 @@ http1_dissect_hdrs(struct http *hp, char
break;
}
}
- if (p < htc->rxbuf_e)
- p += vct_skipcrlf(p);
+ i = vct_iscrlf(p, htc->rxbuf_e);
+ assert(i > 0); /* HTTP1_Complete guarantees this */
+ p += i;
HTC_RxPipeline(htc, p);
htc->rxbuf_e = p;
return (0);

View File

@ -1,60 +0,0 @@
From bf18bb21ef9c269edadac549b7b7d43fdb87051c Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 15 Aug 2019 12:54:50 +0200
Subject: [PATCH] Fix HTTP header line continuation in http1_dissect_hdrs
When clearing the [CR]LF in a line continuation, we would continue
replacing any [CR|LF|HT|SP] characters up until the end of the buffer,
possibly overwriting later [CR]LFs. Fix this by only unconditionally
overwrite one [CR]LF, and then only replace [HT|SP] with SP to keep with
previous behaviour.
Update r00494.vtc to include multiple line continuations to make sure they
are parsed.
---
bin/varnishd/http1/cache_http1_proto.c | 4 +++-
bin/varnishtest/tests/r00494.vtc | 11 +++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index e5203a94ec..e373d7d5d5 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -146,7 +146,9 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc,
break;
/* Clear line continuation LWS to spaces */
- while (q < htc->rxbuf_e && vct_islws(*q))
+ while (q < r)
+ *q++ = ' ';
+ while (q < htc->rxbuf_e && vct_issp(*q))
*q++ = ' ';
}
diff --git a/bin/varnishtest/tests/r00494.vtc b/bin/varnishtest/tests/r00494.vtc
index cb0bbe8d7b..e0db8a4bf8 100644
--- a/bin/varnishtest/tests/r00494.vtc
+++ b/bin/varnishtest/tests/r00494.vtc
@@ -6,6 +6,11 @@ server s1 {
rxreq
txresp -hdr {Foo: bar,
barf: fail} -body "xxx"
+
+ rxreq
+ txresp -hdr {Foo: bar,
+
+ barf: fail} -body "xxx"
} -start
varnish v1 -vcl+backend {
@@ -21,4 +26,10 @@ client c1 {
expect resp.http.bar == "bar, barf: fail"
expect resp.http.barf == <undef>
expect resp.http.foo == <undef>
+
+ txreq -url /2
+ rxresp
+ expect resp.http.bar == "bar, barf: fail"
+ expect resp.http.barf == <undef>
+ expect resp.http.foo == <undef>
} -run

View File

@ -1,45 +0,0 @@
From ea1d09b3b8ee8ad667b9d680013ed9448e0727dc Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu, 15 Aug 2019 14:06:00 +0200
Subject: [PATCH] Add a test case covering some HTTP/1 parsing corner cases
---
bin/varnishtest/tests/b00067.vtc | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
create mode 100644 bin/varnishtest/tests/b00067.vtc
diff --git a/bin/varnishtest/tests/b00067.vtc b/bin/varnishtest/tests/b00067.vtc
new file mode 100644
index 0000000000..2167c9483f
--- /dev/null
+++ b/bin/varnishtest/tests/b00067.vtc
@@ -0,0 +1,29 @@
+varnishtest "HTTP/1 parsing checks"
+
+# Some tricky requests that have been known to cause parsing errors in the past.
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+} -start
+
+# This test checks a bug that was dependent on the contents of the buffer left behind
+# by the previous request
+client c1 {
+ send "GET / HTTP/1.1\r\nHost: asdf.com\r\nFoo: baar\r\n\r\n\r\n\r\n\r\n"
+ rxresp
+ send "GET / HTTP/1.1\r\nHost: asdf.com\r\nAsdf: b\n \r\n\r\nSj\r"
+ rxresp
+ expect resp.status == 200
+} -run
+
+# This tests that the line continuation handling doesn't clear out the end of headers
+# [CR]LF
+client c1 {
+ send "GET / HTTP/1.1\r\nHost: asdf.com\r\nAsdf: b\n \r\n\r\nSj"
+ rxresp
+ expect resp.status == 200
+} -run

View File

@ -1,36 +0,0 @@
From 6da64a47beff44ecdb45c82b033811f2d19819af Mon Sep 17 00:00:00 2001
From: Martin Blix Grydeland <martin@varnish-software.com>
Date: Fri, 23 Aug 2019 13:53:42 +0200
Subject: [PATCH] Avoid some code duplication
Apply some adjustments to recent patches based off of review by Nils
Goroll at UPLEX (@nigoroll)
---
bin/varnishd/http1/cache_http1_proto.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/bin/varnishd/http1/cache_http1_proto.c b/bin/varnishd/http1/cache_http1_proto.c
index 61563b8ead..31c75ed88d 100644
--- a/bin/varnishd/http1/cache_http1_proto.c
+++ b/bin/varnishd/http1/cache_http1_proto.c
@@ -128,15 +128,16 @@ http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc,
r++;
continue;
}
- if (!vct_iscrlf(r, htc->rxbuf_e)) {
+ i = vct_iscrlf(r, htc->rxbuf_e);
+ if (i == 0) {
VSLb(hp->vsl, SLT_BogoHeader,
"Header has ctrl char 0x%02x", *r);
return (400);
}
q = r;
- assert(r < htc->rxbuf_e);
- r = vct_skipcrlf(r, htc->rxbuf_e);
- if (r >= htc->rxbuf_e)
+ r += i;
+ assert(r <= htc->rxbuf_e);
+ if (r == htc->rxbuf_e)
break;
if (vct_iscrlf(r, htc->rxbuf_e))
break;

View File

@ -1,27 +0,0 @@
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

View File

@ -1,29 +0,0 @@
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

View File

@ -1,29 +0,0 @@
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

View File

@ -1,134 +0,0 @@
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,43 +0,0 @@
From 6fa1497436693b2a2d8577dcae86a2bebca5b3f3 Mon Sep 17 00:00:00 2001
From: chengzihan2 <chengzihan1111@163.com>
Date: Tue, 2 Jun 2020 10:57:02 +0800
Subject: [PATCH] gcc-9 stricter on NULL arguments for printf
---
lib/libvarnish/vnum.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/lib/libvarnish/vnum.c b/lib/libvarnish/vnum.c
index 6caf931..2611768 100644
--- a/lib/libvarnish/vnum.c
+++ b/lib/libvarnish/vnum.c
@@ -348,15 +348,17 @@ main(int argc, char *argv[])
for (tc = test_cases; tc->str; ++tc) {
e = VNUM_2bytes(tc->str, &val, tc->rel);
- if (e != tc->err) {
- printf("%s: VNUM_2bytes(\"%s\", %ju) (%s) != (%s)\n",
- *argv, tc->str, tc->rel, tc->err, e);
- ++ec;
- } else if (e == NULL && val != tc->val) {
- printf("%s: VNUM_2bytes(\"%s\", %ju) %ju != %ju (%s)\n",
- *argv, tc->str, tc->rel, val, tc->val, e);
- ++ec;
- }
+ if (e != NULL)
+ val = 0;
+ if (e == tc->err && val == tc->val)
+ continue;
+ ++ec;
+ printf("%s: VNUM_2bytes(\"%s\", %ju)\n",
+ *argv, tc->str, tc->rel);
+ printf("\tExpected:\tstatus %s - value %ju\n",
+ tc->err ? tc->err : "Success", tc->val);
+ printf("\tGot:\t\tstatus %s - value %ju\n",
+ e ? e : "Success", val);
}
if (!isnan(VNUM_duration(NULL))) {
printf("%s: VNUM_Duration(NULL) fail\n", *argv);
--
2.23.0

View File

@ -1,41 +0,0 @@
--- a/doc/sphinx/Makefile.in 2017-03-16 16:01:18.440999286 +0100
+++ b/doc/sphinx/Makefile.in 2017-03-16 16:02:38.557728852 +0100
@@ -626,28 +626,38 @@
# XXX add varnishstat here when it's been _opt2rst'ed
include/varnishncsa_options.rst: $(top_builddir)/bin/varnishncsa/varnishncsa
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishncsa/varnishncsa --options > $@
include/varnishncsa_synopsis.rst: $(top_builddir)/bin/varnishncsa/varnishncsa
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishncsa/varnishncsa --synopsis > $@
include/varnishlog_options.rst: $(top_builddir)/bin/varnishlog/varnishlog
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishlog/varnishlog --options > $@
include/varnishlog_synopsis.rst: $(top_builddir)/bin/varnishlog/varnishlog
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishlog/varnishlog --synopsis > $@
include/varnishtop_options.rst: $(top_builddir)/bin/varnishtop/varnishtop
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishtop/varnishtop --options > $@
include/varnishtop_synopsis.rst: $(top_builddir)/bin/varnishtop/varnishtop
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishtop/varnishtop --synopsis > $@
include/varnishhist_options.rst: $(top_builddir)/bin/varnishhist/varnishhist
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishhist/varnishhist --options > $@
include/varnishhist_synopsis.rst: $(top_builddir)/bin/varnishhist/varnishhist
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishhist/varnishhist --synopsis > $@
include/varnishstat_options.rst: $(top_builddir)/bin/varnishstat/varnishstat
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishstat/varnishstat --options > $@
include/varnishstat_synopsis.rst: $(top_builddir)/bin/varnishstat/varnishstat
+ LD_LIBRARY_PATH=$(top_builddir)/lib/libvarnishapi/.libs \
$(top_builddir)/bin/varnishstat/varnishstat --synopsis > $@
include/vsl-tags.rst: $(top_builddir)/lib/libvarnishapi/vsl2rst

Binary file not shown.

BIN
varnish-7.0.1.tgz Normal file

Binary file not shown.

View File

@ -1,7 +1,9 @@
%global debug_package %{nil}
Name: varnish Name: varnish
Summary: A web application accelerator Summary: A web application accelerator
Version: 6.0.0 Version: 7.0.1
Release: 8 Release: 1
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
@ -9,24 +11,9 @@ Source0: http://varnish-cache.org/_downloads/varnish-%{version}.tgz
# https://github.com/varnishcache/pkg-varnish-cache # https://github.com/varnishcache/pkg-varnish-cache
Source1: https://github.com/varnishcache/pkg-varnish-cache/archive/0ad2f22629c4a368959c423a19e352c9c6c79682/pkg-varnish-cache-0ad2f22.tar.gz Source1: https://github.com/varnishcache/pkg-varnish-cache/archive/0ad2f22629c4a368959c423a19e352c9c6c79682/pkg-varnish-cache-0ad2f22.tar.gz
Patch0001: varnish-5.1.1.fix_ld_library_path_in_doc_build.patch
Patch0002: gcc-9-stricter-on-NULL-arguments-for-printf.patch
Patch0003: CVE-2019-15892-1.patch
Patch0004: CVE-2019-15892-2.patch
Patch0005: CVE-2019-15892-3.patch
Patch0006: CVE-2019-15892-4.patch
Patch0007: CVE-2019-15892-5.patch
Patch0008: CVE-2019-15892-6.patch
Patch0009: CVE-2019-15892-7.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 pcre2-devel libedit-devel gcc
Requires: logrotate ncurses pcre jemalloc openEuler-rpm-config gcc Requires: logrotate ncurses pcre2 jemalloc openEuler-rpm-config gcc
Requires(pre): shadow-utils Requires(pre): shadow-utils
Requires(post): /usr/bin/uuidgen systemd-units systemd-sysv Requires(post): /usr/bin/uuidgen systemd-units systemd-sysv
Requires(preun): systemd-units Requires(preun): systemd-units
@ -76,9 +63,6 @@ export RST2MAN=/bin/true
--localstatedir=/var/lib \ --localstatedir=/var/lib \
--docdir="%{_docdir}/varnish" --docdir="%{_docdir}/varnish"
sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g;
s|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
mkdir lib/libvarnishapi/.libs mkdir lib/libvarnishapi/.libs
pushd lib/libvarnishapi/.libs pushd lib/libvarnishapi/.libs
ln -s libvarnishapi.so libvarnishapi.so.1 ln -s libvarnishapi.so libvarnishapi.so.1
@ -112,8 +96,11 @@ install -D -m 0755 redhat/varnishreload %{buildroot}%{_sbindir}/varnishrel
echo %{_libdir}/varnish > %{buildroot}%{_sysconfdir}/ld.so.conf.d/varnish-%{_arch}.conf echo %{_libdir}/varnish > %{buildroot}%{_sysconfdir}/ld.so.conf.d/varnish-%{_arch}.conf
# No idea why these ends up with mode 600 in the debug package
%if 0%{debug_package}
chmod 644 lib/libvmod_*/*.c chmod 644 lib/libvmod_*/*.c
chmod 644 lib/libvmod_*/*.h chmod 644 lib/libvmod_*/*.h
%endif
%check %check
%ifarch aarch64 %ifarch aarch64
@ -170,6 +157,9 @@ test -f /etc/varnish/secret || (uuidgen > /etc/varnish/secret && chmod 0600 /etc
%{_mandir}/man7/*.7* %{_mandir}/man7/*.7*
%changelog %changelog
* Wed Dec 29 2021 yaoxin <yaoxin30@huawei.com> - 7.0.1-1
- Upgrade varnish to 7.0.1
* Wed Sep 22 2021 yaoxin <yaoxin30@huawei.com> - 6.0.0-8 * Wed Sep 22 2021 yaoxin <yaoxin30@huawei.com> - 6.0.0-8
- Fix CVE-2021-36740 - Fix CVE-2021-36740