Update to 2.1.4 (CVE-2010-11100, #1820200)

This commit is contained in:
Ryan O'Hara 2020-04-02 12:53:50 -05:00
parent 805118c9c8
commit 278672f8e9
3 changed files with 6 additions and 124 deletions

View File

@ -1,118 +0,0 @@
From 3285ced5cbec5d8a0c3464f1762d34439280f8eb Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 11 Mar 2020 11:54:04 +0100
Subject: [PATCH] BUG/MAJOR: list: fix invalid element address calculation
Ryan O'Hara reported that haproxy breaks on fedora-32 using gcc-10
(pre-release). It turns out that constructs such as:
while (item != head) {
item = LIST_ELEM(item.n);
}
loop forever, never matching <item> to <head> despite a printf there
showing them equal. In practice the problem is that the LIST_ELEM()
macro is wrong, it assigns the subtract of two pointers (an integer)
to another pointer through a cast to its pointer type. And GCC 10 now
considers that this cannot match a pointer and silently optimizes the
comparison away. A tested workaround for this is to build with
-fno-tree-pta. Note that older gcc versions even with -ftree-pta do
not exhibit this rather surprizing behavior.
This patch changes the test to instead cast the null-based address to
an int to get the offset and subtract it from the pointer, and this
time it works. There were just a few places to adjust. Ideally
offsetof() should be used but the LIST_ELEM() API doesn't make this
trivial as it's commonly called with a typeof(ptr) and not typeof(ptr*)
thus it would require to completely change the whole API, which is not
something workable in the short term, especially for a backport.
With this change, the emitted code is subtly different even on older
versions. A code size reduction of ~600 bytes and a total executable
size reduction of ~1kB are expected to be observed and should not be
taken as an anomaly. Typically this loop in dequeue_proxy_listeners() :
while ((listener = MT_LIST_POP(...)))
used to produce this code where the comparison is performed on RAX
while the new offset is assigned to RDI even though both are always
identical:
53ded8: 48 8d 78 c0 lea -0x40(%rax),%rdi
53dedc: 48 83 f8 40 cmp $0x40,%rax
53dee0: 74 39 je 53df1b <dequeue_proxy_listeners+0xab>
and now produces this one which is slightly more efficient as the
same register is used for both purposes:
53dd08: 48 83 ef 40 sub $0x40,%rdi
53dd0c: 74 2d je 53dd3b <dequeue_proxy_listeners+0x9b>
Similarly, retrieving the channel from a stream_interface using si_ic()
and si_oc() used to cause this (stream-int in rdi):
1cb7: c7 47 1c 00 02 00 00 movl $0x200,0x1c(%rdi)
1cbe: f6 47 04 10 testb $0x10,0x4(%rdi)
1cc2: 74 1c je 1ce0 <si_report_error+0x30>
1cc4: 48 81 ef 00 03 00 00 sub $0x300,%rdi
1ccb: 81 4f 10 00 08 00 00 orl $0x800,0x10(%rdi)
and now causes this:
1cb7: c7 47 1c 00 02 00 00 movl $0x200,0x1c(%rdi)
1cbe: f6 47 04 10 testb $0x10,0x4(%rdi)
1cc2: 74 1c je 1ce0 <si_report_error+0x30>
1cc4: 81 8f 10 fd ff ff 00 orl $0x800,-0x2f0(%rdi)
There is extremely little chance that this fix wakes up a dormant bug as
the emitted code effectively does what the source code intends.
This must be backported to all supported branches (dropping MT_LIST_ELEM
and the spoa_example parts as needed), since the bug is subtle and may
not always be visible even when compiling with gcc-10.
(cherry picked from commit 855796bdc8b1bc2ebcc697ca99fb304bc6e2abe9)
Signed-off-by: Willy Tarreau <w@1wt.eu>
---
contrib/spoa_example/include/mini-clist.h | 2 +-
include/common/mini-clist.h | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/contrib/spoa_example/include/mini-clist.h b/contrib/spoa_example/include/mini-clist.h
index a89255c46..d009704cc 100644
--- a/contrib/spoa_example/include/mini-clist.h
+++ b/contrib/spoa_example/include/mini-clist.h
@@ -44,7 +44,7 @@ struct list {
* since it's used only once.
* Example: LIST_ELEM(cur_node->args.next, struct node *, args)
*/
-#define LIST_ELEM(lh, pt, el) ((pt)(((void *)(lh)) - ((void *)&((pt)NULL)->el)))
+#define LIST_ELEM(lh, pt, el) ((pt)(((const char *)(lh)) - ((size_t)&((pt)NULL)->el)))
/* checks if the list head <lh> is empty or not */
#define LIST_ISEMPTY(lh) ((lh)->n == (lh))
diff --git a/include/common/mini-clist.h b/include/common/mini-clist.h
index e29451148..01bd0b695 100644
--- a/include/common/mini-clist.h
+++ b/include/common/mini-clist.h
@@ -137,7 +137,7 @@ struct cond_wordlist {
* since it's used only once.
* Example: LIST_ELEM(cur_node->args.next, struct node *, args)
*/
-#define LIST_ELEM(lh, pt, el) ((pt)(((void *)(lh)) - ((void *)&((pt)NULL)->el)))
+#define LIST_ELEM(lh, pt, el) ((pt)(((const char *)(lh)) - ((size_t)&((pt)NULL)->el)))
/* checks if the list head <lh> is empty or not */
#define LIST_ISEMPTY(lh) ((lh)->n == (lh))
@@ -463,7 +463,7 @@ struct cond_wordlist {
* since it's used only once.
* Example: MT_LIST_ELEM(cur_node->args.next, struct node *, args)
*/
-#define MT_LIST_ELEM(lh, pt, el) ((pt)(((void *)(lh)) - ((void *)&((pt)NULL)->el)))
+#define MT_LIST_ELEM(lh, pt, el) ((pt)(((const char *)(lh)) - ((size_t)&((pt)NULL)->el)))
/* checks if the list head <lh> is empty or not */
#define MT_LIST_ISEMPTY(lh) ((lh)->next == (lh))
--
2.24.1

View File

@ -7,8 +7,8 @@
%global _hardened_build 1 %global _hardened_build 1
Name: haproxy Name: haproxy
Version: 2.1.3 Version: 2.1.4
Release: 2%{?dist} Release: 1%{?dist}
Summary: HAProxy reverse proxy for high availability environments Summary: HAProxy reverse proxy for high availability environments
License: GPLv2+ License: GPLv2+
@ -21,8 +21,6 @@ Source3: %{name}.logrotate
Source4: %{name}.sysconfig Source4: %{name}.sysconfig
Source5: halog.1 Source5: halog.1
Patch1: fix-invalid-addr-calc.patch
BuildRequires: gcc BuildRequires: gcc
BuildRequires: lua-devel BuildRequires: lua-devel
BuildRequires: pcre2-devel BuildRequires: pcre2-devel
@ -50,7 +48,6 @@ availability environments. Indeed, it can:
%prep %prep
%setup -q %setup -q
%patch1 -p1
%build %build
regparm_opts= regparm_opts=
@ -135,6 +132,9 @@ exit 0
%{_mandir}/man1/* %{_mandir}/man1/*
%changelog %changelog
* Thu Apr 02 2020 Ryan O'Hara <rohara@redhat.com> - 2.1.4-1
- Update to 2.1.4 (CVE-2010-11100, #1820200)
* Mon Mar 16 2020 Ryan O'Hara <rohara@redhat.com> - 2.1.3-2 * Mon Mar 16 2020 Ryan O'Hara <rohara@redhat.com> - 2.1.3-2
- Fix invalid element address calculation (#1801109) - Fix invalid element address calculation (#1801109)

View File

@ -1 +1 @@
SHA512 (haproxy-2.1.3.tar.gz) = 4728c1177b2bba69465cbc56b1ed73a1b2d36891ba2d94d29bb49714ad98ccfac4b52947735aded211f0cd8070002f5406ddd77cabd2f8230b00438189dd7a60 SHA512 (haproxy-2.1.4.tar.gz) = fd029ac1ec877fa89a9410944439b66795b1392b6c8416aaa7978943170530c3826ba50ea706366f3f7785b7cffed58497cb362fc2480dd6920a99af4f920d98