diff --git a/.gitignore b/.gitignore index 20d67f9..f4864a7 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/sources b/sources index 86e6875..5cfae4b 100644 --- a/sources +++ b/sources @@ -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 diff --git a/varnish-6.6.2_perfect_cache_headers.patch b/varnish-6.6.2_perfect_cache_headers.patch new file mode 100644 index 0000000..8a5661a --- /dev/null +++ b/varnish-6.6.2_perfect_cache_headers.patch @@ -0,0 +1,258 @@ +commit f4dffe593b04a33f07423db3f9dc69eb428b2e85 +Author: Poul-Henning Kamp +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 == "" ++ expect req.http.pROXY-aUTHENTICATE == "" ++ 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 */ diff --git a/varnish-6.6.2_post_fix_vsv00010.patch b/varnish-6.6.2_post_fix_vsv00010.patch new file mode 100644 index 0000000..19c33ab --- /dev/null +++ b/varnish-6.6.2_post_fix_vsv00010.patch @@ -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); diff --git a/varnish-6.6.2_pre_fix_vsv00010.patch b/varnish-6.6.2_pre_fix_vsv00010.patch new file mode 100644 index 0000000..9127165 --- /dev/null +++ b/varnish-6.6.2_pre_fix_vsv00010.patch @@ -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); diff --git a/varnish-6.6.2_vsv00009.patch b/varnish-6.6.2_vsv00009.patch new file mode 100644 index 0000000..e7fbd15 --- /dev/null +++ b/varnish-6.6.2_vsv00009.patch @@ -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 diff --git a/varnish-6.6.2_vsv00010_fcf5722a.patch b/varnish-6.6.2_vsv00010_fcf5722a.patch new file mode 100644 index 0000000..c76c43f --- /dev/null +++ b/varnish-6.6.2_vsv00010_fcf5722a.patch @@ -0,0 +1,235 @@ +commit fcf5722af75fdbf58dd425dd68d0beaa49bab4f4 +Author: Martin Blix Grydeland +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 diff --git a/varnish-6.6.2_vsv00011.patch b/varnish-6.6.2_vsv00011.patch new file mode 100644 index 0000000..5176f5e --- /dev/null +++ b/varnish-6.6.2_vsv00011.patch @@ -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 diff --git a/varnish-6.6.2_vsv00011_test.patch b/varnish-6.6.2_vsv00011_test.patch new file mode 100644 index 0000000..399812c --- /dev/null +++ b/varnish-6.6.2_vsv00011_test.patch @@ -0,0 +1,68 @@ +commit 31a157cc8470cdc44db0ca299c4c246bd54e2d1c +Author: Asad Sajjad Ahmed +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 + +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 diff --git a/varnish.spec b/varnish.spec index 9fa221a..c19b6ce 100644 --- a/varnish.spec +++ b/varnish.spec @@ -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 - 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 - 6.6.2-2 +- Rebuild with side-tag to co-build varnish-modules + +* Wed Jan 26 2022 Ingvar Hagelund - 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 - 6.6.1-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild