update to 2.0.14
This commit is contained in:
parent
4564787683
commit
9584be3eaa
@ -1,36 +0,0 @@
|
||||
From efbbdf72992cd20458259962346044cafd9331c0 Mon Sep 17 00:00:00 2001
|
||||
From: Remi Gacogne <remi.gacogne@powerdns.com>
|
||||
Date: Wed, 5 Dec 2018 17:56:29 +0100
|
||||
Subject: [PATCH] BUG: dns: Prevent out-of-bounds read in
|
||||
dns_validate_dns_response()
|
||||
|
||||
We need to make sure that the record length is not making us read
|
||||
past the end of the data we received.
|
||||
Before this patch we could for example read the 16 bytes
|
||||
corresponding to an AAAA record from the non-initialized part of
|
||||
the buffer, possibly accessing anything that was left on the stack,
|
||||
or even past the end of the 8193-byte buffer, depending on the
|
||||
value of accepted_payload_size.
|
||||
|
||||
To be backported to 1.8, probably also 1.7.
|
||||
---
|
||||
src/dns.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
Index: haproxy-1.8.13/src/dns.c
|
||||
===================================================================
|
||||
--- haproxy-1.8.13.orig/src/dns.c
|
||||
+++ haproxy-1.8.13/src/dns.c
|
||||
@@ -798,6 +798,11 @@ static int dns_validate_dns_response(uns
|
||||
/* Move forward 2 bytes for data len */
|
||||
reader += 2;
|
||||
|
||||
+ if (reader + dns_answer_record->data_len >= bufend) {
|
||||
+ pool_free(dns_answer_item_pool, dns_answer_record);
|
||||
+ return DNS_RESP_INVALID;
|
||||
+ }
|
||||
+
|
||||
/* Analyzing record content */
|
||||
switch (dns_answer_record->type) {
|
||||
case DNS_RTYPE_A:
|
||||
|
||||
@ -1,85 +0,0 @@
|
||||
From 58df5aea0a0c926b2238f65908f5e9f83d1cca25 Mon Sep 17 00:00:00 2001
|
||||
From: Remi Gacogne <remi.gacogne@powerdns.com>
|
||||
Date: Wed, 5 Dec 2018 17:52:54 +0100
|
||||
Subject: [PATCH] BUG: dns: Prevent stack-exhaustion via recursion loop in
|
||||
dns_read_name
|
||||
|
||||
When a compressed pointer is encountered, dns_read_name() will call
|
||||
itself with the pointed-to offset in the packet.
|
||||
With a specially crafted packet, it was possible to trigger an
|
||||
infinite-loop recursion by making the pointer points to itself.
|
||||
While it would be possible to handle that particular case differently
|
||||
by making sure that the target is different from the current offset,
|
||||
it would still be possible to craft a packet with a very long chain
|
||||
of valid pointers, always pointing backwards. To prevent a stack
|
||||
exhaustion in that case, this patch restricts the number of recursive
|
||||
calls to 100, which should be more than enough.
|
||||
|
||||
To be backported to 1.8, probably also 1.7.
|
||||
---
|
||||
src/dns.c | 15 +++++++++------
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
Index: haproxy-1.8.13/src/dns.c
|
||||
===================================================================
|
||||
--- haproxy-1.8.13.orig/src/dns.c
|
||||
+++ haproxy-1.8.13/src/dns.c
|
||||
@@ -391,7 +391,7 @@ static inline unsigned short dns_respons
|
||||
*/
|
||||
int dns_read_name(unsigned char *buffer, unsigned char *bufend,
|
||||
unsigned char *name, char *destination, int dest_len,
|
||||
- int *offset)
|
||||
+ int *offset, unsigned int depth)
|
||||
{
|
||||
int nb_bytes = 0, n = 0;
|
||||
int label_len;
|
||||
@@ -405,8 +405,11 @@ int dns_read_name(unsigned char *buffer,
|
||||
if ((buffer + reader[1]) > reader)
|
||||
goto err;
|
||||
|
||||
+ if (depth++ > 100)
|
||||
+ goto err;
|
||||
+
|
||||
n = dns_read_name(buffer, bufend, buffer + reader[1],
|
||||
- dest, dest_len - nb_bytes, offset);
|
||||
+ dest, dest_len - nb_bytes, offset, depth);
|
||||
if (n == 0)
|
||||
goto err;
|
||||
|
||||
@@ -692,7 +695,7 @@ static int dns_validate_dns_response(uns
|
||||
* one query per response and the first one can't be compressed
|
||||
* (using the 0x0c format) */
|
||||
offset = 0;
|
||||
- len = dns_read_name(resp, bufend, reader, dns_query->name, DNS_MAX_NAME_SIZE, &offset);
|
||||
+ len = dns_read_name(resp, bufend, reader, dns_query->name, DNS_MAX_NAME_SIZE, &offset, 0);
|
||||
|
||||
if (len == 0)
|
||||
return DNS_RESP_INVALID;
|
||||
@@ -729,7 +732,7 @@ static int dns_validate_dns_response(uns
|
||||
return (DNS_RESP_INVALID);
|
||||
|
||||
offset = 0;
|
||||
- len = dns_read_name(resp, bufend, reader, tmpname, DNS_MAX_NAME_SIZE, &offset);
|
||||
+ len = dns_read_name(resp, bufend, reader, tmpname, DNS_MAX_NAME_SIZE, &offset, 0);
|
||||
|
||||
if (len == 0) {
|
||||
pool_free(dns_answer_item_pool, dns_answer_record);
|
||||
@@ -831,7 +834,7 @@ static int dns_validate_dns_response(uns
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
- len = dns_read_name(resp, bufend, reader, tmpname, DNS_MAX_NAME_SIZE, &offset);
|
||||
+ len = dns_read_name(resp, bufend, reader, tmpname, DNS_MAX_NAME_SIZE, &offset, 0);
|
||||
if (len == 0) {
|
||||
pool_free(dns_answer_item_pool, dns_answer_record);
|
||||
return DNS_RESP_INVALID;
|
||||
@@ -861,7 +864,7 @@ static int dns_validate_dns_response(uns
|
||||
dns_answer_record->port = read_n16(reader);
|
||||
reader += sizeof(uint16_t);
|
||||
offset = 0;
|
||||
- len = dns_read_name(resp, bufend, reader, tmpname, DNS_MAX_NAME_SIZE, &offset);
|
||||
+ len = dns_read_name(resp, bufend, reader, tmpname, DNS_MAX_NAME_SIZE, &offset, 0);
|
||||
if (len == 0) {
|
||||
pool_free(dns_answer_item_pool, dns_answer_record);
|
||||
return DNS_RESP_INVALID;
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
From a01f45e3ced23c799f6e78b5efdbd32198a75354 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Mon, 31 Dec 2018 07:41:24 +0100
|
||||
Subject: [PATCH] BUG/CRITICAL: mux-h2: re-check the frame length when PRIORITY
|
||||
is used
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Tim Düsterhus reported a possible crash in the H2 HEADERS frame decoder
|
||||
when the PRIORITY flag is present. A check is missing to ensure the 5
|
||||
extra bytes needed with this flag are actually part of the frame. As per
|
||||
RFC7540#4.2, let's return a connection error with code FRAME_SIZE_ERROR.
|
||||
|
||||
Many thanks to Tim for responsibly reporting this issue with a working
|
||||
config and reproducer. This issue was assigned CVE-2018-20615.
|
||||
|
||||
This fix must be backported to 1.9 and 1.8.
|
||||
|
||||
Signed-off-by: gaoyi <gaoyi15@huawei.com>
|
||||
---
|
||||
src/mux_h2.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/mux_h2.c b/src/mux_h2.c
|
||||
index dc67bc67..20ff9882 100644
|
||||
--- a/src/mux_h2.c
|
||||
+++ b/src/mux_h2.c
|
||||
@@ -3316,6 +3316,11 @@ next_frame:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (flen < 5) {
|
||||
+ h2c_error(h2c, H2_ERR_FRAME_SIZE_ERROR);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
hdrs += 5; // stream dep = 4, weight = 1
|
||||
flen -= 5;
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
From 5dfc5d5cd0d2128d77253ead3acf03a421ab5b88 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Sun, 29 Mar 2020 08:53:31 +0200
|
||||
Subject: [PATCH 1/1] BUG/CRITICAL: hpack: never index a header into the
|
||||
headroom after wrapping
|
||||
|
||||
The HPACK header table is implemented as a wrapping list inside a contigous
|
||||
area. Headers names and values are stored from right to left while indexes
|
||||
are stored from left to right. When there's no more room to store a new one,
|
||||
we wrap to the right again, or possibly defragment it if needed. The condition
|
||||
do use the right part (called tailroom) or the left part (called headroom)
|
||||
depends on the location of the last inserted header. After wrapping happens,
|
||||
the code forces to stick to tailroom by pretending there's no more headroom,
|
||||
so that the size fit test always fails. The problem is that nothing prevents
|
||||
from storing a header with an empty name and empty value, resulting in a
|
||||
total size of zero bytes, which satisfies the condition to use the headroom.
|
||||
Doing this in a wrapped buffer results in changing the "front" header index
|
||||
and causing miscalculations on the available size and the addresses of the
|
||||
next headers. This may even allow to overwrite some parts of the index,
|
||||
opening the possibility to perform arbitrary writes into a 32-bit relative
|
||||
address space.
|
||||
|
||||
This patch fixes the issue by making sure the headroom is considered only
|
||||
when the buffer does not wrap, instead of relying on the zero size. This
|
||||
must be backported to all versions supporting H2, which is as far as 1.8.
|
||||
|
||||
Many thanks to Felix Wilhelm of Google Project Zero for responsibly
|
||||
reporting this problem with a reproducer and a detailed analysis.
|
||||
CVE-2020-11100 was assigned to this issue.
|
||||
---
|
||||
src/hpack-tbl.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/hpack-tbl.c b/src/hpack-tbl.c
|
||||
index 70d7f35..727ff7a 100644
|
||||
--- a/src/hpack-tbl.c
|
||||
+++ b/src/hpack-tbl.c
|
||||
@@ -346,9 +346,9 @@ int hpack_dht_insert(struct hpack_dht *dht, struct ist name, struct ist value)
|
||||
* room left in the tail to suit the protocol, but tests show that in
|
||||
* practice it almost never happens in other situations so the extra
|
||||
* test is useless and we simply fill the headroom as long as it's
|
||||
- * available.
|
||||
+ * available and we don't wrap.
|
||||
*/
|
||||
- if (headroom >= name.len + value.len) {
|
||||
+ if (prev == dht->front && headroom >= name.len + value.len) {
|
||||
/* install upfront and update ->front */
|
||||
dht->dte[head].addr = dht->dte[dht->front].addr - (name.len + value.len);
|
||||
dht->front = head;
|
||||
--
|
||||
1.7.10.4
|
||||
|
||||
Binary file not shown.
BIN
haproxy-2.0.14.tar.gz
Normal file
BIN
haproxy-2.0.14.tar.gz
Normal file
Binary file not shown.
15
haproxy.spec
15
haproxy.spec
@ -4,8 +4,8 @@
|
||||
%global _hardened_build 1
|
||||
|
||||
Name: haproxy
|
||||
Version: 1.8.14
|
||||
Release: 5
|
||||
Version: 2.0.14
|
||||
Release: 1
|
||||
Summary: The Reliable, High Performance TCP/HTTP Load Balancer
|
||||
|
||||
License: GPLv2+
|
||||
@ -16,12 +16,8 @@ Source2: %{name}.cfg
|
||||
Source3: %{name}.logrotate
|
||||
Source4: %{name}.sysconfig
|
||||
|
||||
Patch6000: CVE-2018-20615-BUG-CRITICAL-mux-h2-re-check-the-frame-length-when-P.patch
|
||||
Patch6001: CVE-2018-20103.patch
|
||||
Patch6002: CVE-2018-20102.patch
|
||||
Patch6003: CVE-2020-11100.patch
|
||||
|
||||
BuildRequires: gcc lua-devel pcre-devel zlib-devel openssl-devel systemd-devel systemd-units
|
||||
BuildRequires: gcc lua-devel pcre-devel zlib-devel openssl-devel systemd-devel systemd-units libatomic
|
||||
Requires(pre): shadow-utils
|
||||
Requires(post): systemd
|
||||
Requires(preun): systemd
|
||||
@ -42,7 +38,7 @@ use_regparm_opt=
|
||||
use_regparm_opt="USE_REGPARM=1"
|
||||
%endif
|
||||
|
||||
%make_build CPU="generic" TARGET="linux2628" USE_OPENSSL=1 USE_PCRE=1 USE_ZLIB=1 \
|
||||
%make_build CPU="generic" TARGET="linux-glibc" USE_OPENSSL=1 USE_PCRE=1 USE_ZLIB=1 \
|
||||
USE_LUA=1 USE_CRYPT_H=1 USE_SYSTEMD=1 USE_LINUX_TPROXY=1 USE_GETADDRINFO=1 ${use_regparm_opt} \
|
||||
ADDINC="%{optflags}" ADDLIB="%{__global_ldflags}"
|
||||
|
||||
@ -126,6 +122,9 @@ exit 0
|
||||
%{_mandir}/man1/*
|
||||
|
||||
%changelog
|
||||
* Wed Jul 22 2020 hanzhijun <hanzhijun1@huawei.com> - 2.0.14-1
|
||||
- update to 2.0.14
|
||||
|
||||
* Thu May 7 2020 cuibaobao <cuibaobao1@huawei.com> - 1.8.14-5
|
||||
- Type:cves
|
||||
- ID: CVE-2020-11100
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user