upgrade 2.2.16 to fix CVE-2021-39240
(cherry picked from commit 9f52a65b134699dc7a2351ee0cc064ab85216ce4)
This commit is contained in:
parent
a6c9427f4c
commit
f45c8a290d
@ -1,25 +0,0 @@
|
|||||||
From 038af20a857ab1f656d5f949c2c5e00d55005c73 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Amaury Denoyelle <adenoyelle@haproxy.com>
|
|
||||||
Date: Fri, 11 Dec 2020 17:53:09 +0100
|
|
||||||
Subject: [PATCH 1/1] MEDIUM:h2: parse Extended CONNECT request to htx
|
|
||||||
|
|
||||||
---
|
|
||||||
src/h2.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/h2.c b/src/h2.c
|
|
||||||
index 656fed4..3f739e7 100644
|
|
||||||
--- a/src/h2.c
|
|
||||||
+++ b/src/h2.c
|
|
||||||
@@ -173,7 +173,7 @@ int h2_parse_cont_len_header(unsigned int *msgf, struct ist *value, unsigned lon
|
|
||||||
*/
|
|
||||||
static struct htx_sl *h2_prepare_htx_reqline(uint32_t fields, struct ist *phdr, struct htx *htx, unsigned int *msgf)
|
|
||||||
{
|
|
||||||
- struct ist uri;
|
|
||||||
+ struct ist uri,meth_sl;
|
|
||||||
unsigned int flags = HTX_SL_F_NONE;
|
|
||||||
struct htx_sl *sl;
|
|
||||||
size_t i;
|
|
||||||
--
|
|
||||||
2.23.0
|
|
||||||
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
From 89265224d314a056d77d974284802c1b8a0dc97f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Willy Tarreau <w@1wt.eu>
|
|
||||||
Date: Wed, 11 Aug 2021 11:12:46 +0200
|
|
||||||
Subject: [PATCH] BUG/MAJOR: h2: enforce stricter syntax checks on the :method
|
|
||||||
pseudo-header
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=utf8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
Before HTX was introduced, all the HTTP request elements passed in
|
|
||||||
pseudo-headers fields were used to build an HTTP/1 request whose syntax
|
|
||||||
was then scrutinized by the HTTP/1 parser, leaving no room to inject
|
|
||||||
invalid characters.
|
|
||||||
|
|
||||||
While NUL, CR and LF are properly blocked, it is possible to inject
|
|
||||||
spaces in the method so that once translated to HTTP/1, fields are
|
|
||||||
shifted by one spcae, and a lenient HTTP/1 server could possibly be
|
|
||||||
fooled into using a part of the method as the URI. For example, the
|
|
||||||
following request:
|
|
||||||
|
|
||||||
H2 request
|
|
||||||
:method: "GET /admin? HTTP/1.1"
|
|
||||||
:path: "/static/images"
|
|
||||||
|
|
||||||
would become:
|
|
||||||
|
|
||||||
GET /admin? HTTP/1.1 /static/images HTTP/1.1
|
|
||||||
|
|
||||||
It's important to note that the resulting request is *not* valid, and
|
|
||||||
that in order for this to be a problem, it requires that this request
|
|
||||||
is delivered to an already vulnerable HTTP/1 server.
|
|
||||||
|
|
||||||
A workaround here is to reject malformed methods by placing this rule
|
|
||||||
in the frontend or backend, at least before leaving haproxy in H1:
|
|
||||||
|
|
||||||
http-request reject if { method -m reg [^A-Z0-9] }
|
|
||||||
|
|
||||||
Alternately H2 may be globally disabled by commenting out the "alpn"
|
|
||||||
directive on "bind" lines, and by rejecting H2 streams creation by
|
|
||||||
adding the following statement to the global section:
|
|
||||||
|
|
||||||
tune.h2.max-concurrent-streams 0
|
|
||||||
|
|
||||||
This patch adds a check for each character of the method to make sure
|
|
||||||
they belong to the ones permitted in a token, as mentioned in RFC7231#4.1.
|
|
||||||
|
|
||||||
This should be backported to versions 2.0 and above. For older versions
|
|
||||||
not having HTX_FL_PARSING_ERROR, a "goto fail" works as well as it
|
|
||||||
results in a protocol error at the stream level. Non-HTX versions are
|
|
||||||
safe because the resulting invalid request will be rejected by the
|
|
||||||
internal HTTP/1 parser.
|
|
||||||
|
|
||||||
Thanks to Tim Düsterhus for reporting that one.
|
|
||||||
---
|
|
||||||
src/h2.c | 8 ++++++++
|
|
||||||
1 file changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/h2.c b/src/h2.c
|
|
||||||
index b31ff93..280bbd7 100644
|
|
||||||
--- a/src/h2.c
|
|
||||||
+++ b/src/h2.c
|
|
||||||
@@ -328,6 +328,14 @@ static struct htx_sl *h2_prepare_htx_reqline(uint32_t fields, struct ist *phdr,
|
|
||||||
flags |= HTX_SL_F_HAS_AUTHORITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /* The method is a non-empty token (RFC7231#4.1) */
|
|
||||||
+ if (!meth_sl.len)
|
|
||||||
+ goto fail;
|
|
||||||
+ for (i = 0; i < meth_sl.len; i++) {
|
|
||||||
+ if (!HTTP_IS_TOKEN(meth_sl.ptr[i]))
|
|
||||||
+ htx->flags |= HTX_FL_PARSING_ERROR;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* make sure the final URI isn't empty. Note that 7540#8.1.2.3 states
|
|
||||||
* that :path must not be empty.
|
|
||||||
*/
|
|
||||||
--
|
|
||||||
1.7.10.4
|
|
||||||
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
From b5d2b9e154d78e4075db163826c5e0f6d31b2ab1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Willy Tarreau <w@1wt.eu>
|
|
||||||
Date: Wed, 11 Aug 2021 15:39:13 +0200
|
|
||||||
Subject: [PATCH] BUG/MEDIUM: h2: give :authority precedence over Host
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=utf8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
The wording regarding Host vs :authority in RFC7540 is ambiguous as it
|
|
||||||
says that an intermediary must produce a host header from :authority if
|
|
||||||
Host is missing, but, contrary to HTTP/1.1, doesn't say anything regarding
|
|
||||||
the possibility that Host and :authority differ, which leaves Host with
|
|
||||||
higher precedence there. In addition it mentions that clients should use
|
|
||||||
:authority *instead* of Host, and that H1->H2 should use :authority only
|
|
||||||
if the original request was in authority form. This leaves some gray
|
|
||||||
area in the middle of the chain for fully valid H2 requests arboring a
|
|
||||||
Host header that are forwarded to the other side where it's possible to
|
|
||||||
drop the Host header and use the authority only after forwarding to a
|
|
||||||
second H2 layer, thus possibly seeing two different values of Host at
|
|
||||||
a different stage. There's no such issue when forwarding from H2 to H1
|
|
||||||
as the authority is dropped only only the Host is kept.
|
|
||||||
|
|
||||||
Note that the following request is sufficient to re-normalize such a
|
|
||||||
request:
|
|
||||||
|
|
||||||
http-request set-header host %[req.hdr(host)]
|
|
||||||
|
|
||||||
The new spec in progress (draft-ietf-httpbis-http2bis-03) addresses
|
|
||||||
this trouble by being a bit is stricter on these rules. It clarifies
|
|
||||||
that :authority must always be used instead of Host and that Host ought
|
|
||||||
to be ignored. This is much saner as it avoids to convey two distinct
|
|
||||||
values along the chain. This becomes the protocol-level equivalent of:
|
|
||||||
|
|
||||||
http-request set-uri %[url]
|
|
||||||
|
|
||||||
So this patch does exactly this, which we were initially a bit reluctant
|
|
||||||
to do initially by lack of visibility about other implementations'
|
|
||||||
expectations. In addition it slightly simplifies the Host header field
|
|
||||||
creation by always placing it first in the list of headers instead of
|
|
||||||
last; this could also speed up the look up a little bit.
|
|
||||||
|
|
||||||
This needs to be backported to 2.0. Non-HTX versions are safe regarding
|
|
||||||
this because they drop the URI during the conversion to HTTP/1.1 so
|
|
||||||
only Host is used and transmitted.
|
|
||||||
|
|
||||||
Thanks to Tim Düsterhus for reporting that one.
|
|
||||||
---
|
|
||||||
src/h2.c | 23 +++++++++++++++++++++--
|
|
||||||
1 file changed, 21 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/h2.c b/src/h2.c
|
|
||||||
index 280bbd7..bbc5853 100644
|
|
||||||
--- a/src/h2.c
|
|
||||||
+++ b/src/h2.c
|
|
||||||
@@ -456,10 +456,27 @@ int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *ms
|
|
||||||
if (!sl)
|
|
||||||
goto fail;
|
|
||||||
fields |= H2_PHDR_FND_NONE;
|
|
||||||
+
|
|
||||||
+ /* http2bis draft recommends to drop Host in favor of :authority when
|
|
||||||
+ * the latter is present. This is required to make sure there is no
|
|
||||||
+ * discrepancy between the authority and the host header, especially
|
|
||||||
+ * since routing rules usually involve Host. Here we already know if
|
|
||||||
+ * :authority was found so we can emit it right now and mark the host
|
|
||||||
+ * as filled so that it's skipped later.
|
|
||||||
+ */
|
|
||||||
+ if (fields & H2_PHDR_FND_AUTH) {
|
|
||||||
+ if (!htx_add_header(htx, ist("host"), phdr_val[H2_PHDR_IDX_AUTH]))
|
|
||||||
+ goto fail;
|
|
||||||
+ fields |= H2_PHDR_FND_HOST;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (isteq(list[idx].n, ist("host")))
|
|
||||||
+ if (isteq(list[idx].n, ist("host"))) {
|
|
||||||
+ if (fields & H2_PHDR_FND_HOST)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
fields |= H2_PHDR_FND_HOST;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
if (isteq(list[idx].n, ist("content-length"))) {
|
|
||||||
ret = h2_parse_cont_len_header(msgf, &list[idx].v, body_len);
|
|
||||||
@@ -531,7 +548,9 @@ int h2_make_htx_request(struct http_hdr *list, struct htx *htx, unsigned int *ms
|
|
||||||
/* update the start line with last detected header info */
|
|
||||||
sl->flags |= sl_flags;
|
|
||||||
|
|
||||||
- /* complete with missing Host if needed */
|
|
||||||
+ /* complete with missing Host if needed (we may validate this test if
|
|
||||||
+ * no regular header was found).
|
|
||||||
+ */
|
|
||||||
if ((fields & (H2_PHDR_FND_HOST|H2_PHDR_FND_AUTH)) == H2_PHDR_FND_AUTH) {
|
|
||||||
/* missing Host field, use :authority instead */
|
|
||||||
if (!htx_add_header(htx, ist("host"), phdr_val[H2_PHDR_IDX_AUTH]))
|
|
||||||
--
|
|
||||||
1.7.10.4
|
|
||||||
|
|
||||||
Binary file not shown.
BIN
haproxy-2.2.16.tar.gz
Normal file
BIN
haproxy-2.2.16.tar.gz
Normal file
Binary file not shown.
12
haproxy.spec
12
haproxy.spec
@ -4,20 +4,17 @@
|
|||||||
%global _hardened_build 1
|
%global _hardened_build 1
|
||||||
|
|
||||||
Name: haproxy
|
Name: haproxy
|
||||||
Version: 2.2.1
|
Version: 2.2.16
|
||||||
Release: 2
|
Release: 1
|
||||||
Summary: The Reliable, High Performance TCP/HTTP Load Balancer
|
Summary: The Reliable, High Performance TCP/HTTP Load Balancer
|
||||||
|
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: https://www.haproxy.org/
|
URL: https://www.haproxy.org/
|
||||||
Source0: https://www.haproxy.org/download/2.0/src/%{name}-%{version}.tar.gz
|
Source0: https://www.haproxy.org/download/2.2/src/%{name}-%{version}.tar.gz
|
||||||
Source1: %{name}.service
|
Source1: %{name}.service
|
||||||
Source2: %{name}.cfg
|
Source2: %{name}.cfg
|
||||||
Source3: %{name}.logrotate
|
Source3: %{name}.logrotate
|
||||||
Source4: %{name}.sysconfig
|
Source4: %{name}.sysconfig
|
||||||
Patch001: CVE-2021-39241-pre.patch
|
|
||||||
Patch002: CVE-2021-39241.patch
|
|
||||||
Patch003: CVE-2021-39242.patch
|
|
||||||
|
|
||||||
BuildRequires: gcc lua-devel pcre-devel zlib-devel openssl-devel systemd-devel systemd-units libatomic
|
BuildRequires: gcc lua-devel pcre-devel zlib-devel openssl-devel systemd-devel systemd-units libatomic
|
||||||
Requires(pre): shadow-utils
|
Requires(pre): shadow-utils
|
||||||
@ -123,6 +120,9 @@ exit 0
|
|||||||
%{_mandir}/man1/*
|
%{_mandir}/man1/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Aug 30 yaoxin <yaoxin30@huawei.com> - 2.2.16-1
|
||||||
|
- Upgrade 2.2.16 to fix CVE-2021-39240
|
||||||
|
|
||||||
* Thu Aug 26 liwu <liwu13@huawei.com> - 2.2.1-2
|
* Thu Aug 26 liwu <liwu13@huawei.com> - 2.2.1-2
|
||||||
- fix CVE-2021-39241,CVE-2021-39242
|
- fix CVE-2021-39241,CVE-2021-39242
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user