Compare commits

...
Sign in to create a new pull request.

3 commits

Author SHA1 Message Date
Ingvar Hagelund
c686f93def Added patches for VSV00009 aka CVE-2022-38150, bz#2118570
Added patches for VSV00010 aka CVE-2022-45059, bz#2141842
Added patches for VSV00011 aka CVE-2022-45060, bz#2141847
Added a bcond system_allocator, bz#1917697
Removed comments referencing patches no longer in use
2022-11-17 01:05:51 +01:00
Ingvar Hagelund
46809d6fc8 Rebuild with side-tag to co-build varnish-modules 2022-02-07 18:19:57 +01:00
Ingvar Hagelund
423ea19d58 New upstream release. A security release.
Includes fix for CVE-2022-23959 aka VSV00008, rhbz#2045033
2022-01-26 15:06:48 +01:00
10 changed files with 861 additions and 37 deletions

1
.gitignore vendored
View file

@ -46,3 +46,4 @@ varnish-2.1.3.tar.gz
/varnish-6.5.1.tgz
/varnish-6.6.0.tgz
/varnish-6.6.1.tgz
/varnish-6.6.2.tgz

View file

@ -1,2 +1,2 @@
SHA512 (varnish-6.6.1.tgz) = af3ee1743af2ede2d3efbb73e5aa9b42c7bbd5f86163ec338c8afd1989c3e51ff3e1b40bed6b72224b5d339a74f22d6e5f3c3faf2fedee8ab4715307ed5d871b
SHA512 (varnish-6.6.2.tgz) = 8fa163678e2e454fcc959ba24f349de00e6c00357df55f37f12f0d3acbcb2799b2f376385cef2d40c14a4cc44a5eea1b5a3fbf6245961611d4fc3ea30699035d
SHA512 (pkg-varnish-cache-ec7ad9e.tar.gz) = 146aacec76b2ca641bb8bc9dda49e82d28740dbcba034e73a8d39387696f10fa3108ab124a078e900865388217352d112f63f6fe9ef7b23e20bc699441aab4f2

View file

@ -0,0 +1,258 @@
commit f4dffe593b04a33f07423db3f9dc69eb428b2e85
Author: Poul-Henning Kamp <phk@FreeBSD.org>
Date: Thu Apr 29 11:02:21 2021 +0000
Use "perfect hash" to find headers to be filtered out.
The actual agorithm was found with `gperf` but its output is
not directly usable and include/tbl/http_headers.h change so
infrequently that this step is not automated. (Asserts protect
against overlooking this step if new headers are added to
the table.)
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index 09fce7def..db0dad004 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -57,6 +57,131 @@ const char H__Status[] = "\010:status:";
const char H__Proto[] = "\007:proto:";
const char H__Reason[] = "\010:reason:";
+/*--------------------------------------------------------------------
+ * Perfect hash to rapidly recognize headers from tbl/http_headers.h
+ * which have non-zero flags.
+ *
+ * A suitable algorithm can be found with `gperf`:
+ *
+ * tr '" ,' ' ' < include/tbl/http_headers.h |
+ * awk '$1 == "H(" && $4 != "0" {print$2}' |
+ * gperf --ignore-case
+ *
+ */
+
+static const unsigned char http_asso_values[256] = {
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 25, 39, 0, 20, 5, 39, 39, 39, 15, 0, 39,
+ 10, 39, 0, 39, 15, 10, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 25, 39, 0, 20, 5, 39, 39, 39, 15, 0, 39,
+ 10, 39, 0, 39, 15, 10, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
+ 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39
+};
+
+static struct http_hdrflg {
+ char *hdr;
+ unsigned flag;
+} http_hdrflg[38 + 1] = { // MAX_HASH_VALUE
+ { NULL },
+ { NULL },
+ { H_TE },
+ { H_Age },
+ { NULL },
+ { H_Range },
+ { NULL },
+ { H_Upgrade },
+ { H_If_Range },
+ { NULL },
+ { H_Connection },
+ { NULL },
+ { H_Trailer },
+ { H_If_None_Match },
+ { NULL },
+ { NULL },
+ { NULL },
+ { H_Transfer_Encoding },
+ { H_Proxy_Authenticate },
+ { H_Proxy_Authorization },
+ { H_Keep_Alive },
+ { NULL },
+ { NULL },
+ { H_If_Match },
+ { H_HTTP2_Settings },
+ { NULL },
+ { NULL },
+ { NULL },
+ { H_Content_Range },
+ { H_If_Unmodified_Since },
+ { NULL },
+ { NULL },
+ { H_If_Modified_Since },
+ { H_Cache_Control },
+ { NULL },
+ { NULL },
+ { NULL },
+ { NULL },
+ { H_Accept_Ranges }
+};
+
+static struct http_hdrflg *
+http_hdr_flags(const char *b, const char *e)
+{
+ unsigned u;
+ struct http_hdrflg *retval;
+
+ if (e == NULL)
+ return(NULL);
+ assert(e > b);
+ u = (unsigned)(e - b);
+ assert(b + u == e);
+ if (u < 2 || u > 19) // MIN_WORD_LENGTH & MAX_WORD_LENGTH
+ return(NULL);
+ if (u > 3)
+ u += http_asso_values[((const uint8_t*)b)[3]];
+ if (u > 38) // MAX_HASH_VALUE
+ return(NULL);
+ retval = &http_hdrflg[u];
+ if (retval->hdr == NULL)
+ return(NULL);
+ if (strncasecmp(retval->hdr + 1, b, e - b))
+ return(NULL);
+ return(retval);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+http_init_hdr(char *hdr, int flg)
+{
+ struct http_hdrflg *f;
+
+ hdr[0] = strlen(hdr + 1);
+ f = http_hdr_flags(hdr + 1, hdr + hdr[0]);
+ if (flg) {
+ AN(f);
+ assert(f->hdr == hdr);
+ f->flag = flg;
+ }
+}
+
+void
+HTTP_Init(void)
+{
+
+#define HTTPH(a, b, c) http_init_hdr(b, c);
+#include "tbl/http_headers.h"
+}
+
/*--------------------------------------------------------------------
* These two functions are in an incestuous relationship with the
* order of macros in include/tbl/vsl_tags_http.h
@@ -735,6 +860,7 @@ http_DoConnection(struct http *hp, enum sess_close sc_close)
const char *h, *b, *e;
enum sess_close retval;
unsigned u, v;
+ struct http_hdrflg *f;
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
assert(sc_close == SC_REQ_CLOSE || sc_close == SC_RESP_CLOSE);
@@ -756,13 +882,9 @@ http_DoConnection(struct http *hp, enum sess_close sc_close)
retval = SC_NULL;
/* Refuse removal of well-known-headers if they would pass. */
-/*lint -save -e506 [constant value boolean] */
-#define HTTPH(a, x, c) \
- if (!((c) & HTTPH_R_PASS) && \
- strlen(a) == u && !strncasecmp(a, b, u)) \
+ f = http_hdr_flags(b, e);
+ if (f != NULL && !(f->flag & HTTPH_R_PASS))
return (SC_RX_BAD);
-#include "tbl/http_headers.h"
-/*lint -restore */
for (v = HTTP_HDR_FIRST; v < hp->nhd; v++) {
Tcheck(hp->hd[v]);
@@ -898,13 +1020,16 @@ http_PutResponse(struct http *to, const char *proto, uint16_t status,
static inline int
http_isfiltered(const struct http *fm, unsigned u, unsigned how)
{
+ const char *e;
+ const struct http_hdrflg *f;
+
if (fm->hdf[u] & HDF_FILTER)
return (1);
-#define HTTPH(a, b, c) \
- if (((c) & how) && http_IsHdr(&fm->hd[u], (b))) \
- return (1);
-#include "tbl/http_headers.h"
- return (0);
+ e = strchr(fm->hd[u].b, ':');
+ if (e == NULL)
+ return (0);
+ f = http_hdr_flags(fm->hd[u].b, e);
+ return (f != NULL && f->flag & how);
}
int
@@ -1313,13 +1438,3 @@ http_Unset(struct http *hp, const char *hdr)
}
hp->nhd = v;
}
-
-/*--------------------------------------------------------------------*/
-
-void
-HTTP_Init(void)
-{
-
-#define HTTPH(a, b, c) b[0] = (char)strlen(b + 1);
-#include "tbl/http_headers.h"
-}
diff --git a/bin/varnishtest/tests/c00016.vtc b/bin/varnishtest/tests/c00016.vtc
index fa86a59bf..54316a627 100644
--- a/bin/varnishtest/tests/c00016.vtc
+++ b/bin/varnishtest/tests/c00016.vtc
@@ -1,10 +1,15 @@
-varnishtest "Test Connection header handling"
+varnishtest "Test header filtering Table/Connection header"
server s1 {
rxreq
expect req.url == "/foo"
expect req.http.Foo == "bar"
expect req.http.FromVCL == "123"
+ expect req.http.Proxy-Authenticate == "<undef>"
+ expect req.http.pROXY-aUTHENTICATE == "<undef>"
+ expect req.http.Proxy-Authenticat == "3"
+ expect req.http.Proxy-Authenticatd == "4"
+ expect req.http.Proxy-Authenticatef == "5"
txresp -hdr "Bar: foo" -body "foobar"
rxreq
@@ -23,7 +28,13 @@ varnish v1 -vcl+backend {
} -start
client c1 {
- txreq -url "/foo" -hdr "Foo: bar"
+ txreq -url "/foo" -hdr "Foo: bar" \
+ -hdr "Proxy-Authenticate: 1" \
+ -hdr "pROXY-aUTHENTICATE: 2" \
+ -hdr "Proxy-Authenticat: 3" \
+ -hdr "Proxy-Authenticatd: 4" \
+ -hdr "Proxy-Authenticatef: 5"
+
rxresp
expect resp.http.Bar == "foo"
diff --git a/include/tbl/http_headers.h b/include/tbl/http_headers.h
index 416d6a8f6..3fe1aaa00 100644
--- a/include/tbl/http_headers.h
+++ b/include/tbl/http_headers.h
@@ -36,6 +36,9 @@
*
* see [RFC2616 13.5.1 End-to-end and Hop-by-hop Headers]
*
+ * When fields with non-zero flags are added, the "perfect hash" at the
+ * top of cache_http.c will need to be reworked. See the comments there
+ * for instructions.
*/
/*lint -save -e525 -e539 */

View file

@ -0,0 +1,11 @@
--- bin/varnishd/cache/cache_http.c.orig 2022-11-17 00:07:20.275622335 +0100
+++ bin/varnishd/cache/cache_http.c 2022-11-17 00:08:30.429142656 +0100
@@ -1063,6 +1063,8 @@
if (fm->hdf[u] & HDF_FILTER)
return (1);
+ if (u < HTTP_HDR_FIRST)
+ return (0);
e = strchr(fm->hd[u].b, ':');
if (e == NULL)
return (0);

View file

@ -0,0 +1,11 @@
--- bin/varnishd/cache/cache_http.c.orig 2022-11-16 23:56:03.248251530 +0100
+++ bin/varnishd/cache/cache_http.c 2022-11-16 23:56:09.545208475 +0100
@@ -900,8 +900,6 @@
{
if (fm->hdf[u] & HDF_FILTER)
return (1);
- if (u < HTTP_HDR_FIRST)
- return (0);
#define HTTPH(a, b, c) \
if (((c) & how) && http_IsHdr(&fm->hd[u], (b))) \
return (1);

View file

@ -0,0 +1,45 @@
diff -Nur ../varnish-6.6.2.prep/bin/varnishd/cache/cache_http.c ./bin/varnishd/cache/cache_http.c
--- ../varnish-6.6.2.prep/bin/varnishd/cache/cache_http.c 2022-01-12 12:30:00.000000000 +0100
+++ ./bin/varnishd/cache/cache_http.c 2022-11-14 21:07:24.093085010 +0100
@@ -900,6 +900,8 @@
{
if (fm->hdf[u] & HDF_FILTER)
return (1);
+ if (u < HTTP_HDR_FIRST)
+ return (0);
#define HTTPH(a, b, c) \
if (((c) & how) && http_IsHdr(&fm->hd[u], (b))) \
return (1);
diff -Nur ../varnish-6.6.2.prep/bin/varnishtest/tests/r03830.vtc ./bin/varnishtest/tests/r03830.vtc
--- ../varnish-6.6.2.prep/bin/varnishtest/tests/r03830.vtc 1970-01-01 01:00:00.000000000 +0100
+++ ./bin/varnishtest/tests/r03830.vtc 2022-11-14 21:08:47.324725940 +0100
@@ -0,0 +1,29 @@
+varnishtest "3830: Do not call http_hdr_flags() on pseudo-headers"
+
+server s1 {
+ rxreq
+ txresp -reason ":x"
+
+ rxreq
+ txresp
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_recv {
+ return (hash);
+ }
+} -start
+
+client c1 {
+ txreq
+ rxresp
+ expect resp.status == 200
+} -run
+
+client c2 {
+ txreq -url :x -method :x
+ rxresp
+ expect resp.status == 200
+} -run
+
+varnish v1 -vsl_catchup

View file

@ -0,0 +1,235 @@
commit fcf5722af75fdbf58dd425dd68d0beaa49bab4f4
Author: Martin Blix Grydeland <martin@varnish-software.com>
Date: Thu Sep 29 14:38:05 2022 +0200
Add all well-known headers to the perfect hash lookup table
This expands the perfect hash lookup table to be able to match any entry
in the list of well-known headers from tbl/http_headers.h.
Previously only the headers that had a non-zero filter flag section was
kept in the fast match table.
Fixes: VSV00010
diff --git a/bin/varnishd/cache/cache_http.c b/bin/varnishd/cache/cache_http.c
index 194055c3c..827197ded 100644
--- a/bin/varnishd/cache/cache_http.c
+++ b/bin/varnishd/cache/cache_http.c
@@ -65,73 +65,113 @@ const char H__Reason[] = "\010:reason:";
* A suitable algorithm can be found with `gperf`:
*
* tr '" ,' ' ' < include/tbl/http_headers.h |
- * awk '$1 == "H(" && $4 != "0" {print$2}' |
+ * awk '$1 == "H(" {print $2}' |
* gperf --ignore-case
*
*/
+#define GPERF_MIN_WORD_LENGTH 2
+#define GPERF_MAX_WORD_LENGTH 19
+#define GPERF_MAX_HASH_VALUE 79
+
static const unsigned char http_asso_values[256] = {
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 25, 39, 0, 20, 5, 39, 39, 39, 15, 0, 39,
- 10, 39, 0, 39, 15, 10, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 25, 39, 0, 20, 5, 39, 39, 39, 15, 0, 39,
- 10, 39, 0, 39, 15, 10, 39, 39, 0, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 0, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 5, 80, 20, 0, 0,
+ 5, 10, 5, 5, 80, 0, 15, 0, 20, 80,
+ 40, 80, 0, 35, 10, 20, 55, 45, 0, 0,
+ 80, 80, 80, 80, 80, 80, 80, 5, 80, 20,
+ 0, 0, 5, 10, 5, 5, 80, 0, 15, 0,
+ 20, 80, 40, 80, 0, 35, 10, 20, 55, 45,
+ 0, 0, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80, 80, 80, 80, 80,
+ 80, 80, 80, 80, 80, 80
};
static struct http_hdrflg {
char *hdr;
unsigned flag;
-} http_hdrflg[38 + 1] = { // MAX_HASH_VALUE
- { NULL },
- { NULL },
- { H_TE },
- { H_Age },
- { NULL },
+} http_hdrflg[GPERF_MAX_HASH_VALUE + 1] = {
+ { NULL }, { NULL }, { NULL }, { NULL },
+ { H_Date },
{ H_Range },
{ NULL },
- { H_Upgrade },
+ { H_Referer },
+ { H_Age },
+ { H_From },
+ { H_Keep_Alive },
+ { H_Retry_After },
+ { H_TE },
{ H_If_Range },
- { NULL },
- { H_Connection },
- { NULL },
+ { H_ETag },
+ { H_X_Forwarded_For },
+ { H_Expect },
{ H_Trailer },
- { H_If_None_Match },
- { NULL },
- { NULL },
- { NULL },
- { H_Transfer_Encoding },
- { H_Proxy_Authenticate },
- { H_Proxy_Authorization },
- { H_Keep_Alive },
- { NULL },
- { NULL },
{ H_If_Match },
- { H_HTTP2_Settings },
- { NULL },
- { NULL },
- { NULL },
- { H_Content_Range },
+ { H_Host },
+ { H_Accept_Language },
+ { H_Accept },
+ { H_If_Modified_Since },
+ { H_If_None_Match },
{ H_If_Unmodified_Since },
{ NULL },
+ { H_Cookie },
+ { H_Upgrade },
+ { H_Last_Modified },
+ { H_Accept_Charset },
+ { H_Accept_Encoding },
+ { H_Content_MD5 },
+ { H_Content_Type },
+ { H_Content_Range },
+ { NULL }, { NULL },
+ { H_Content_Language },
+ { H_Transfer_Encoding },
+ { H_Authorization },
+ { H_Content_Length },
+ { H_User_Agent },
+ { H_Server },
+ { H_Expires },
+ { H_Location },
{ NULL },
- { H_If_Modified_Since },
+ { H_Set_Cookie },
+ { H_Content_Encoding },
+ { H_Max_Forwards },
{ H_Cache_Control },
{ NULL },
+ { H_Connection },
+ { H_Pragma },
{ NULL },
+ { H_Accept_Ranges },
+ { H_HTTP2_Settings },
+ { H_Allow },
+ { H_Content_Location },
{ NULL },
+ { H_Proxy_Authenticate },
+ { H_Vary },
{ NULL },
- { H_Accept_Ranges }
+ { H_WWW_Authenticate },
+ { H_Warning },
+ { H_Via },
+ { NULL }, { NULL }, { NULL }, { NULL },
+ { NULL }, { NULL }, { NULL }, { NULL },
+ { NULL }, { NULL }, { NULL }, { NULL },
+ { NULL }, { NULL }, { NULL },
+ { H_Proxy_Authorization }
};
static struct http_hdrflg *
@@ -145,12 +185,12 @@ http_hdr_flags(const char *b, const char *e)
assert(b <= e);
u = (unsigned)(e - b);
assert(b + u == e);
- if (u < 2 || u > 19) // MIN_WORD_LENGTH & MAX_WORD_LENGTH
- return(NULL);
- if (u > 3)
- u += http_asso_values[((const uint8_t*)b)[3]];
- if (u > 38) // MAX_HASH_VALUE
- return(NULL);
+ if (u < GPERF_MIN_WORD_LENGTH || u > GPERF_MAX_WORD_LENGTH)
+ return (NULL);
+ u += http_asso_values[((const uint8_t *)b)[u - 1]] +
+ http_asso_values[((const uint8_t *)b)[0]];
+ if (u > GPERF_MAX_HASH_VALUE)
+ return (NULL);
retval = &http_hdrflg[u];
if (retval->hdr == NULL)
return(NULL);
@@ -168,11 +208,9 @@ http_init_hdr(char *hdr, int flg)
hdr[0] = strlen(hdr + 1);
f = http_hdr_flags(hdr + 1, hdr + hdr[0]);
- if (flg) {
- AN(f);
- assert(f->hdr == hdr);
- f->flag = flg;
- }
+ AN(f);
+ assert(f->hdr == hdr);
+ f->flag = flg;
}
void
diff --git a/bin/varnishtest/tests/f00010.vtc b/bin/varnishtest/tests/f00010.vtc
new file mode 100644
index 000000000..b381b5cf3
--- /dev/null
+++ b/bin/varnishtest/tests/f00010.vtc
@@ -0,0 +1,19 @@
+varnishtest "Do not allow critical headers to be marked hop-by-hop"
+
+varnish v1 -vcl {
+ backend default none;
+} -start
+
+client c1 {
+ txreq -hdr "Connection: Content-Length" -body "asdf"
+ rxresp
+ expect resp.status == 400
+ expect_close
+} -run
+
+client c2 {
+ txreq -hdr "Connection: Host"
+ rxresp
+ expect resp.status == 400
+ expect_close
+} -run

View file

@ -0,0 +1,182 @@
diff -Nur ../varnish-6.6.2.pprep/bin/varnishd/http2/cache_http2_hpack.c ./bin/varnishd/http2/cache_http2_hpack.c
--- ../varnish-6.6.2.pprep/bin/varnishd/http2/cache_http2_hpack.c 2022-01-12 12:30:00.000000000 +0100
+++ ./bin/varnishd/http2/cache_http2_hpack.c 2022-11-14 21:37:18.595866979 +0100
@@ -96,13 +96,18 @@
{
/* XXX: This might belong in cache/cache_http.c */
const char *b0;
+ int disallow_empty;
unsigned n;
+ char *p;
+ int i;
CHECK_OBJ_NOTNULL(hp, HTTP_MAGIC);
AN(b);
assert(namelen >= 2); /* 2 chars from the ': ' that we added */
assert(namelen <= len);
+ disallow_empty = 0;
+
if (len > UINT_MAX) { /* XXX: cache_param max header size */
VSLb(hp->vsl, SLT_BogoHeader, "Header too large: %.20s", b);
return (H2SE_ENHANCE_YOUR_CALM);
@@ -117,10 +122,24 @@
b += namelen;
len -= namelen;
n = HTTP_HDR_METHOD;
+ disallow_empty = 1;
+
+ /* First field cannot contain SP or CTL */
+ for (p = b, i = 0; i < len; p++, i++) {
+ if (vct_issp(*p) || vct_isctl(*p))
+ return (H2SE_PROTOCOL_ERROR);
+ }
} else if (!strncmp(b, ":path: ", namelen)) {
b += namelen;
len -= namelen;
n = HTTP_HDR_URL;
+ disallow_empty = 1;
+
+ /* Second field cannot contain LWS or CTL */
+ for (p = b, i = 0; i < len; p++, i++) {
+ if (vct_islws(*p) || vct_isctl(*p))
+ return (H2SE_PROTOCOL_ERROR);
+ }
} else if (!strncmp(b, ":scheme: ", namelen)) {
/* XXX: What to do about this one? (typically
"http" or "https"). For now set it as a normal
@@ -128,6 +147,15 @@
b++;
len-=1;
n = hp->nhd;
+
+ for (p = b + namelen, i = 0; i < len-namelen;
+ p++, i++) {
+ if (vct_issp(*p) || vct_isctl(*p))
+ return (H2SE_PROTOCOL_ERROR);
+ }
+
+ if (!i)
+ return (H2SE_PROTOCOL_ERROR);
} else if (!strncmp(b, ":authority: ", namelen)) {
b+=6;
len-=6;
@@ -164,6 +192,13 @@
hp->hd[n].b = b;
hp->hd[n].e = b + len;
+ if (disallow_empty && !Tlen(hp->hd[n])) {
+ VSLb(hp->vsl, SLT_BogoHeader,
+ "Empty pseudo-header %.*s",
+ (int)namelen, b0);
+ return (H2SE_PROTOCOL_ERROR);
+ }
+
return (0);
}
diff -Nur ../varnish-6.6.2.pprep/bin/varnishtest/tests/t02023.vtc ./bin/varnishtest/tests/t02023.vtc
--- ../varnish-6.6.2.pprep/bin/varnishtest/tests/t02023.vtc 1970-01-01 01:00:00.000000000 +0100
+++ ./bin/varnishtest/tests/t02023.vtc 2022-11-14 21:42:38.634380069 +0100
@@ -0,0 +1,49 @@
+varnishtest "Empty pseudo-headers"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -arg "-p feature=+http2" -vcl+backend {
+} -start
+
+client c1 {
+ txreq -url ""
+ rxresp
+ expect resp.status == 400
+} -run
+
+client c1 {
+ txreq -req ""
+ rxresp
+ expect resp.status == 400
+} -run
+
+client c1 {
+ txreq -proto ""
+ rxresp
+ expect resp.status == 400
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -url ""
+ rxrst
+ } -run
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -scheme ""
+ rxrst
+ } -run
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -req ""
+ rxrst
+ } -run
+} -run
+
diff -Nur ../varnish-6.6.2.pprep/bin/varnishtest/tests/t02024.vtc ./bin/varnishtest/tests/t02024.vtc
--- ../varnish-6.6.2.pprep/bin/varnishtest/tests/t02024.vtc 1970-01-01 01:00:00.000000000 +0100
+++ ./bin/varnishtest/tests/t02024.vtc 2022-11-14 21:43:26.592157248 +0100
@@ -0,0 +1,48 @@
+varnishtest "Garbage pseudo-headers"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -arg "-p feature=+http2" -vcl+backend {
+} -start
+
+client c1 {
+ txreq -url " "
+ rxresp
+ expect resp.status == 400
+} -run
+
+client c1 {
+ txreq -req " "
+ rxresp
+ expect resp.status == 400
+} -run
+
+client c1 {
+ txreq -proto " "
+ rxresp
+ expect resp.status == 400
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -url " "
+ rxrst
+ } -run
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -scheme " "
+ rxrst
+ } -run
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -req " "
+ rxrst
+ } -run
+} -run

View file

@ -0,0 +1,68 @@
commit 31a157cc8470cdc44db0ca299c4c246bd54e2d1c
Author: Asad Sajjad Ahmed <asadsa@varnish-software.com>
Date: Mon Oct 3 16:08:30 2022 +0200
h2: add vtc for VSV00011
Check for correct handling of missing pseudo-headers, and invalid
characters.
Signed-off-by: Asad Sajjad Ahmed <asadsa@varnish-software.com>
diff --git a/bin/varnishtest/tests/f00011.vtc b/bin/varnishtest/tests/f00011.vtc
new file mode 100644
index 000000000..810918028
--- /dev/null
+++ b/bin/varnishtest/tests/f00011.vtc
@@ -0,0 +1,51 @@
+varnishtest "H2: Malformed pseudo-headers"
+
+server s1 {
+ rxreq
+ txresp
+} -start
+
+varnish v1 -arg "-p feature=+http2" -vcl+backend {
+} -start
+
+client c1 {
+ stream 1 {
+ txreq -url ""
+ rxrst
+ } -run
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -url " \t"
+ rxrst
+ } -run
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -scheme ""
+ rxrst
+ } -run
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -scheme " \t"
+ rxrst
+ } -run
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -req ""
+ rxrst
+ } -run
+} -run
+
+client c1 {
+ stream 1 {
+ txreq -req " \t"
+ rxrst
+ } -run
+} -run

View file

@ -12,7 +12,7 @@
%global __provides_exclude_from ^%{_libdir}/varnish/vmods
%global abi e6a8c860944c4f6a7e1af9f40674ea78bbdcdc66
%global abi 17c51b08e037fc8533fb3687a042a867235fc72f
%global vrt 13.0
# Package scripts are now external
@ -20,49 +20,30 @@
%global commit1 ec7ad9e6c6dd7c9b4f4ba60c5b223376908c3ca6
%global shortcommit1 %(c=%{commit1}; echo ${c:0:7})
# Default: Use jemalloc, as adviced by upstream project
# Change to 1 to use system allocator (ie. glibc)
%bcond system_allocator 0
Summary: High-performance HTTP accelerator
Name: varnish
Version: 6.6.1
Version: 6.6.2
Release: 3%{?dist}
License: BSD
URL: https://www.varnish-cache.org/
Source0: http://varnish-cache.org/_downloads/%{name}-%{version}.tgz
Source1: https://github.com/varnishcache/pkg-varnish-cache/archive/%{commit1}.tar.gz#/pkg-varnish-cache-%{shortcommit1}.tar.gz
# Patches:
# Patch 001: Because of Fedora's libtool no-rpath requirement, it is still
# necessary to add LD_LIBRARY_PATH when building the documentation
# (Fixed by using LT_SYS_LIBRARY_PATH)
#Patch1: varnish-6.1.1_fix_ld_library_path_in_doc_build.patch
# Patch 004: varnish selinux support for el6
#Patch4: varnish-4.0.3_fix_varnish4_selinux.el6.patch
# Patch 009: Hard code older python support in configure for older el releases
#Patch9: varnish-5.1.1.fix_python_version.patch
# Patch 012: Fix test for variants of ncurses, based on upstream commit 9bdc5f75, upstream issue #2668
#Patch12: varnish-6.0.1_fix_bug2668.patch
# Patch 013: Just a simple format error
#Patch13: varnish-6.1.0_fix_testu00008.patch
# Patch 014: Another formatting error fixed upstream, issue 2879
#Patch14: varnish-6.1.1_fix_upstrbug_2879.patch
# Patch 015: pcre-jit fixed upstream, issue #2912
#Patch15: varnish-6.1.1_fix_issue_2912.patch
# Patch 016: Fix some warnings that prohibited clean -Werror compilation
# on el6. Will not be fixed upstream. Patch grows more stupid
# for each iteration :-(
#Patch16: varnish-6.5.0_el6_fix_warning_from_old_gcc.patch
# Patch 017: Fix stack size on ppc64 in test c_00057, upstream commit 88948d9
#Patch17: varnish-6.2.0_fix_ppc64_for_test_c00057.patch
# Patch 018: gcc-10.0.1/s390x compilation fix, upstream commit b0af060
#Patch18: varnish-6.3.2_fix_s390x.patch
# Patch19 based on upstream commit 782f42f
Patch19: varnish-6.6.2_vsv00009.patch
# Patch20 Based on upstream commit 515a93d
Patch20: varnish-6.6.2_vsv00011.patch
Patch21: varnish-6.6.2_pre_fix_vsv00010.patch
# Patch22 is upstream commit f4dffe5
Patch22: varnish-6.6.2_perfect_cache_headers.patch
# Patch23 is upstream commit fcf5722a
Patch23: varnish-6.6.2_vsv00010_fcf5722a.patch
Patch24: varnish-6.6.2_post_fix_vsv00010.patch
Patch25: varnish-6.6.2_vsv00011_test.patch
%if 0%{?fedora} > 29
Provides: varnish%{_isa} = %{version}-%{release}
@ -85,7 +66,11 @@ BuildRequires: python34 python34-sphinx python34-docutils
%else
BuildRequires: python3, python3-sphinx, python3-docutils
%endif
%if 0%{with system_allocator}
# use glibc
%else
BuildRequires: jemalloc-devel
%endif
BuildRequires: libedit-devel
BuildRequires: ncurses-devel
BuildRequires: pcre-devel
@ -104,7 +89,11 @@ BuildRequires: haproxy
Requires: logrotate
Requires: ncurses
Requires: pcre
%if 0%{with system_allocator}
# use glibc
%else
Requires: jemalloc
%endif
Requires: redhat-rpm-config
Requires(pre): shadow-utils
Requires(post): /usr/bin/uuidgen
@ -155,6 +144,13 @@ ln -s pkg-varnish-cache-%{commit1}/redhat redhat
ln -s pkg-varnish-cache-%{commit1}/debian debian
cp redhat/find-provides .
sed -i 's,rst2man-3.6,rst2man-3.4,g; s,rst2html-3.6,rst2html-3.4,g; s,phinx-build-3.6,phinx-build-3.4,g' configure
%patch19 -p1
%patch20 -p1
%patch21 -p0
%patch22 -p1
%patch23 -p1 -F1
%patch24 -p0
%patch25 -p1
%build
# https://gcc.gnu.org/wiki/FAQ#PR323
@ -183,6 +179,9 @@ export PYTHON=%{__python}
--disable-static \
--localstatedir=/var/lib \
--docdir=%{?_pkgdocdir}%{!?_pkgdocdir:%{_docdir}/%{name}-%{version}} \
%if 0%{with system_allocator}
--with-jemalloc=no \
%endif
# --disable-pcre-jit \
%make_build
@ -298,6 +297,20 @@ test -f /etc/varnish/secret || (uuidgen > /etc/varnish/secret && chmod 0600 /etc
%changelog
* Mon Nov 14 2022 Ingvar Hagelund <ingvar@redpill-linpro.com> - 6.6.2-3
- Added patches for VSV00009 aka CVE-2022-38150, bz#2118570
- Added patches for VSV00010 aka CVE-2022-45059, bz#2141842
- Added patches for VSV00011 aka CVE-2022-45060, bz#2141847
- Added a bcond system_allocator, bz#1917697
- Removed comments referencing patches no longer in use
* Mon Feb 07 2022 Ingvar Hagelund <ingvar@redpill-linpro.com> - 6.6.2-2
- Rebuild with side-tag to co-build varnish-modules
* Wed Jan 26 2022 Ingvar Hagelund <ingvar@redpill-linpro.com> - 6.6.2-1
- New upstream release. A security release.
- Includes fix for CVE-2022-23959 aka VSV00008, rhbz#2045033
* Fri Jul 23 2021 Fedora Release Engineering <releng@fedoraproject.org> - 6.6.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild