diff --git a/CVE-2022-45060.patch b/CVE-2022-45060.patch new file mode 100644 index 0000000000000000000000000000000000000000..701c787872ba7feeb7dd7aa215af3191e1c84bea --- /dev/null +++ b/CVE-2022-45060.patch @@ -0,0 +1,207 @@ +From 515a93df894430767073ccd8265497b6b25b54b5 Mon Sep 17 00:00:00 2001 +From: Asad Sajjad Ahmed +Date: Fri, 30 Sep 2022 14:42:53 +0200 +Subject: [PATCH] hpack: fix pseudo-headers handling + +We should apply the same restrictions on the list of allowed characters inside +H/2 pseudo-headers as we do for H/1. This error is translated into the +headers we send to a backend over H/1. + +Failure to do so could permit various exploits against a backend not handling +malformed H/1 requests. + +Signed-off-by: Asad Sajjad Ahmed +--- + bin/varnishd/http2/cache_http2_hpack.c | 35 +++++++++++++++++++ + bin/varnishtest/tests/t02023.vtc | 48 ++++++++++++++++++++++++++ + bin/varnishtest/tests/t02024.vtc | 48 ++++++++++++++++++++++++++ + 3 files changed, 131 insertions(+) + create mode 100644 bin/varnishtest/tests/t02023.vtc + create mode 100644 bin/varnishtest/tests/t02024.vtc + +diff --git a/bin/varnishd/http2/cache_http2_hpack.c b/bin/varnishd/http2/cache_http2_hpack.c +index 6e67b55c50..f58788b126 100644 +--- a/bin/varnishd/http2/cache_http2_hpack.c ++++ b/bin/varnishd/http2/cache_http2_hpack.c +@@ -96,13 +96,18 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len) + { + /* 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 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len) + 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 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len) + 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 @@ h2h_addhdr(struct http *hp, char *b, size_t namelen, size_t len) + 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 --git a/bin/varnishtest/tests/t02023.vtc b/bin/varnishtest/tests/t02023.vtc +new file mode 100644 +index 0000000000..cfd843da3e +--- /dev/null ++++ b/bin/varnishtest/tests/t02023.vtc +@@ -0,0 +1,48 @@ ++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 --git a/bin/varnishtest/tests/t02024.vtc b/bin/varnishtest/tests/t02024.vtc +new file mode 100644 +index 0000000000..0d0a1abc5d +--- /dev/null ++++ b/bin/varnishtest/tests/t02024.vtc +@@ -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.spec b/varnish.spec index b49eefb8c90965c2997368d53777a25148f17b49..685bbdf9cc6f90a3aaf125cffa707a24d3fe5d7f 100644 --- a/varnish.spec +++ b/varnish.spec @@ -1,7 +1,7 @@ Name: varnish Summary: A web application accelerator Version: 7.0.1 -Release: 4 +Release: 5 License: BSD-2-Clause URL: https://www.varnish-cache.org/ Source0: http://varnish-cache.org/_downloads/varnish-%{version}.tgz @@ -13,6 +13,7 @@ Patch0002: fix-varnish.service-reload-failed.patch ##https://github.com/varnishcache/varnish-cache/commit/fceaefd4d59a3b5d5a4903a3f420e35eb430d0d4 Patch0003: CVE-2022-23959.patch Patch0004: CVE-2022-38150.patch +Patch0005: CVE-2022-45060.patch BuildRequires: python3-sphinx python3-docutils pkgconfig make graphviz nghttp2 systemd-units BuildRequires: ncurses-devel pcre2-devel libedit-devel gcc @@ -161,6 +162,9 @@ test -f /etc/varnish/secret || (uuidgen > /etc/varnish/secret && chmod 0600 /etc %{_mandir}/man7/*.7* %changelog +* Tue Nov 22 2022 jiangpeng - 7.0.1-5 +- Fix CVE-2022-45060 + * Tue Aug 23 2022 jiangpeng - 7.0.1-4 - Fix CVE-2022-38150