upgrade 2.2.16 to fix CVE-2021-39240

(cherry picked from commit 9f52a65b134699dc7a2351ee0cc064ab85216ce4)
This commit is contained in:
starlet_dx 2021-08-30 20:59:40 +08:00 committed by openeuler-sync-bot
parent a6c9427f4c
commit f45c8a290d
6 changed files with 6 additions and 207 deletions

View File

@ -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

View File

@ -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

View File

@ -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

Binary file not shown.

View File

@ -4,20 +4,17 @@
%global _hardened_build 1
Name: haproxy
Version: 2.2.1
Release: 2
Version: 2.2.16
Release: 1
Summary: The Reliable, High Performance TCP/HTTP Load Balancer
License: GPLv2+
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
Source2: %{name}.cfg
Source3: %{name}.logrotate
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
Requires(pre): shadow-utils
@ -123,6 +120,9 @@ exit 0
%{_mandir}/man1/*
%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
- fix CVE-2021-39241,CVE-2021-39242