Compare commits
10 Commits
c7e04f024e
...
704118a2e1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
704118a2e1 | ||
|
|
ad0ec7f79f | ||
|
|
ce43ece7f8 | ||
|
|
f04ffea0e0 | ||
|
|
5dd1b2224b | ||
|
|
fbb679fff7 | ||
|
|
4d58e747ec | ||
|
|
49d44f471d | ||
|
|
71c6d0617c | ||
|
|
456f8d96e9 |
41
CVE-2023-0836.patch
Normal file
41
CVE-2023-0836.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 2e6bf0a2722866ae0128a4392fa2375bd1f03ff8 Mon Sep 17 00:00:00 2001
|
||||
From: Youfu Zhang <zhangyoufu@gmail.com>
|
||||
Date: Fri, 9 Dec 2022 19:15:48 +0800
|
||||
Subject: [PATCH] BUG/MAJOR: fcgi: Fix uninitialized reserved bytes
|
||||
|
||||
The output buffer is not zero-initialized. If we don't clear reserved
|
||||
bytes, fcgi requests sent to backend will leak sensitive data.
|
||||
|
||||
This patch must be backported as far as 2.2.
|
||||
---
|
||||
src/fcgi.c | 8 ++++++--
|
||||
1 file changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/fcgi.c b/src/fcgi.c
|
||||
index dcf2db2..1d1a82b 100644
|
||||
--- a/src/fcgi.c
|
||||
+++ b/src/fcgi.c
|
||||
@@ -47,7 +47,7 @@ int fcgi_encode_record_hdr(struct buffer *out, const struct fcgi_header *h)
|
||||
out->area[len++] = ((h->len >> 8) & 0xff);
|
||||
out->area[len++] = (h->len & 0xff);
|
||||
out->area[len++] = h->padding;
|
||||
- len++; /* rsv */
|
||||
+ out->area[len++] = 0; /* rsv */
|
||||
|
||||
out->data = len;
|
||||
return 1;
|
||||
@@ -94,7 +94,11 @@ int fcgi_encode_begin_request(struct buffer *out, const struct fcgi_begin_reques
|
||||
out->area[len++] = ((r->role >> 8) & 0xff);
|
||||
out->area[len++] = (r->role & 0xff);
|
||||
out->area[len++] = r->flags;
|
||||
- len += 5; /* rsv */
|
||||
+ out->area[len++] = 0; /* rsv */
|
||||
+ out->area[len++] = 0;
|
||||
+ out->area[len++] = 0;
|
||||
+ out->area[len++] = 0;
|
||||
+ out->area[len++] = 0;
|
||||
|
||||
out->data = len;
|
||||
return 1;
|
||||
--
|
||||
1.7.10.4
|
||||
107
CVE-2023-45539.patch
Normal file
107
CVE-2023-45539.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From 2eab6d354322932cfec2ed54de261e4347eca9a6 Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Tue, 8 Aug 2023 16:17:22 +0200
|
||||
Subject: [PATCH] BUG/MINOR: h1: do not accept '#' as part of the URI component
|
||||
|
||||
Seth Manesse and Paul Plasil reported that the "path" sample fetch
|
||||
function incorrectly accepts '#' as part of the path component. This
|
||||
can in some cases lead to misrouted requests for rules that would apply
|
||||
on the suffix:
|
||||
|
||||
use_backend static if { path_end .png .jpg .gif .css .js }
|
||||
|
||||
Note that this behavior can be selectively configured using
|
||||
"normalize-uri fragment-encode" and "normalize-uri fragment-strip".
|
||||
|
||||
The problem is that while the RFC says that this '#' must never be
|
||||
emitted, as often it doesn't suggest how servers should handle it. A
|
||||
diminishing number of servers still do accept it and trim it silently,
|
||||
while others are rejecting it, as indicated in the conversation below
|
||||
with other implementers:
|
||||
|
||||
https://lists.w3.org/Archives/Public/ietf-http-wg/2023JulSep/0070.html
|
||||
|
||||
Looking at logs from publicly exposed servers, such requests appear at
|
||||
a rate of roughly 1 per million and only come from attacks or poorly
|
||||
written web crawlers incorrectly following links found on various pages.
|
||||
|
||||
Thus it looks like the best solution to this problem is to simply reject
|
||||
such ambiguous requests by default, and include this in the list of
|
||||
controls that can be disabled using "option accept-invalid-http-request".
|
||||
|
||||
We're already rejecting URIs containing any control char anyway, so we
|
||||
should also reject '#'.
|
||||
|
||||
In the H1 parser for the H1_MSG_RQURI state, there is an accelerated
|
||||
parser for bytes 0x21..0x7e that has been tightened to 0x24..0x7e (it
|
||||
should not impact perf since 0x21..0x23 are not supposed to appear in
|
||||
a URI anyway). This way '#' falls through the fine-grained filter and
|
||||
we can add the special case for it also conditionned by a check on the
|
||||
proxy's option "accept-invalid-http-request", with no overhead for the
|
||||
vast majority of valid URIs. Here this information is available through
|
||||
h1m->err_pos that's set to -2 when the option is here (so we don't need
|
||||
to change the API to expose the proxy). Example with a trivial GET
|
||||
through netcat:
|
||||
|
||||
[08/Aug/2023:16:16:52.651] frontend layer1 (#2): invalid request
|
||||
backend <NONE> (#-1), server <NONE> (#-1), event #0, src 127.0.0.1:50812
|
||||
buffer starts at 0 (including 0 out), 16361 free,
|
||||
len 23, wraps at 16336, error at position 7
|
||||
H1 connection flags 0x00000000, H1 stream flags 0x00000810
|
||||
H1 msg state MSG_RQURI(4), H1 msg flags 0x00001400
|
||||
H1 chunk len 0 bytes, H1 body len 0 bytes :
|
||||
|
||||
00000 GET /aa#bb HTTP/1.0\r\n
|
||||
00021 \r\n
|
||||
|
||||
This should be progressively backported to all stable versions along with
|
||||
the following patch:
|
||||
|
||||
REGTESTS: http-rules: add accept-invalid-http-request for normalize-uri tests
|
||||
|
||||
Similar fixes for h2 and h3 will come in followup patches.
|
||||
|
||||
Thanks to Seth Manesse and Paul Plasil for reporting this problem with
|
||||
detailed explanations.
|
||||
---
|
||||
src/h1.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/h1.c b/src/h1.c
|
||||
index 88a54c4a593d..4e224f895422 100644
|
||||
--- a/src/h1.c
|
||||
+++ b/src/h1.c
|
||||
@@ -551,13 +551,13 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
|
||||
case H1_MSG_RQURI:
|
||||
http_msg_rquri:
|
||||
#ifdef HA_UNALIGNED_LE
|
||||
- /* speedup: skip bytes not between 0x21 and 0x7e inclusive */
|
||||
+ /* speedup: skip bytes not between 0x24 and 0x7e inclusive */
|
||||
while (ptr <= end - sizeof(int)) {
|
||||
- int x = *(int *)ptr - 0x21212121;
|
||||
+ int x = *(int *)ptr - 0x24242424;
|
||||
if (x & 0x80808080)
|
||||
break;
|
||||
|
||||
- x -= 0x5e5e5e5e;
|
||||
+ x -= 0x5b5b5b5b;
|
||||
if (!(x & 0x80808080))
|
||||
break;
|
||||
|
||||
@@ -569,8 +569,15 @@ int h1_headers_to_hdr_list(char *start, const char *stop,
|
||||
goto http_msg_ood;
|
||||
}
|
||||
http_msg_rquri2:
|
||||
- if (likely((unsigned char)(*ptr - 33) <= 93)) /* 33 to 126 included */
|
||||
+ if (likely((unsigned char)(*ptr - 33) <= 93)) { /* 33 to 126 included */
|
||||
+ if (*ptr == '#') {
|
||||
+ if (h1m->err_pos < -1) /* PR_O2_REQBUG_OK not set */
|
||||
+ goto invalid_char;
|
||||
+ if (h1m->err_pos == -1) /* PR_O2_REQBUG_OK set: just log */
|
||||
+ h1m->err_pos = ptr - start + skip;
|
||||
+ }
|
||||
EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_rquri2, http_msg_ood, state, H1_MSG_RQURI);
|
||||
+ }
|
||||
|
||||
if (likely(HTTP_IS_SPHT(*ptr))) {
|
||||
sl.rq.u.len = ptr - sl.rq.u.ptr;
|
||||
@ -0,0 +1,134 @@
|
||||
From d7be206d3570138cfadca87bb768293804629bc7 Mon Sep 17 00:00:00 2001
|
||||
From: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Tue, 28 Feb 2023 15:39:38 +0100
|
||||
Subject: [PATCH] BUG/MEDIUM: connection: Clear flags when a conn is removed
|
||||
from an idle list
|
||||
|
||||
When a connection is removed from the safe list or the idle list,
|
||||
CO_FL_SAFE_LIST and CO_FL_IDLE_LIST flags must be cleared. It is performed
|
||||
when the connection is reused. But not when it is moved into the
|
||||
toremove_conns list. It may be an issue because the multiplexer owning the
|
||||
connection may be woken up before the connection is really removed. If the
|
||||
connection flags are not sanitized, it may think the connection is idle and
|
||||
reinsert it in the corresponding list. From this point, we can imagine
|
||||
several bugs. An UAF or a connection reused with an invalid state for
|
||||
instance.
|
||||
|
||||
To avoid any issue, the connection flags are sanitized when an idle
|
||||
connection is moved into the toremove_conns list. The same is performed at
|
||||
right places in the multiplexers. Especially because the connection release
|
||||
may be delayed (for h2 and fcgi connections).
|
||||
|
||||
This patch shoudld fix the issue #2057. It must carefully be backported as
|
||||
far as 2.2. Especially on the 2.2 where the code is really different. But
|
||||
some conflicts should be expected on the 2.4 too.
|
||||
|
||||
(cherry picked from commit 5e1b0e7bf86a300def07388df0ea7f4b3f9e68b9)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 7902ebadb1ffbe0237ce974b950ca595894f3774)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=d7be206d3570138cfadca87bb768293804629bc7
|
||||
---
|
||||
src/mux_fcgi.c | 4 +++-
|
||||
src/mux_h1.c | 4 +++-
|
||||
src/mux_h2.c | 7 ++++++-
|
||||
src/server.c | 2 ++
|
||||
4 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c
|
||||
index c93ddd4..5a040bf 100644
|
||||
--- a/src/mux_fcgi.c
|
||||
+++ b/src/mux_fcgi.c
|
||||
@@ -3221,8 +3221,10 @@ struct task *fcgi_timeout_task(struct task *t, void *context, unsigned int state
|
||||
/* We're about to destroy the connection, so make sure nobody attempts
|
||||
* to steal it from us.
|
||||
*/
|
||||
- if (fconn->conn->flags & CO_FL_LIST_MASK)
|
||||
+ if (fconn->conn->flags & CO_FL_LIST_MASK) {
|
||||
conn_delete_from_tree(&fconn->conn->hash_node->node);
|
||||
+ fconn->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
+ }
|
||||
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
diff --git a/src/mux_h1.c b/src/mux_h1.c
|
||||
index 67d4234..a26e99c 100644
|
||||
--- a/src/mux_h1.c
|
||||
+++ b/src/mux_h1.c
|
||||
@@ -3281,8 +3281,10 @@ struct task *h1_timeout_task(struct task *t, void *context, unsigned int state)
|
||||
/* We're about to destroy the connection, so make sure nobody attempts
|
||||
* to steal it from us.
|
||||
*/
|
||||
- if (h1c->conn->flags & CO_FL_LIST_MASK)
|
||||
+ if (h1c->conn->flags & CO_FL_LIST_MASK) {
|
||||
conn_delete_from_tree(&h1c->conn->hash_node->node);
|
||||
+ h1c->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
+ }
|
||||
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
diff --git a/src/mux_h2.c b/src/mux_h2.c
|
||||
index 2215c8b..9b319c6 100644
|
||||
--- a/src/mux_h2.c
|
||||
+++ b/src/mux_h2.c
|
||||
@@ -4147,6 +4147,7 @@ static int h2_process(struct h2c *h2c)
|
||||
if (conn->flags & CO_FL_LIST_MASK) {
|
||||
HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
conn_delete_from_tree(&conn->hash_node->node);
|
||||
+ conn->flags &= ~CO_FL_LIST_MASK;
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
}
|
||||
@@ -4155,6 +4156,7 @@ static int h2_process(struct h2c *h2c)
|
||||
if (conn->flags & CO_FL_LIST_MASK) {
|
||||
HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
conn_delete_from_tree(&conn->hash_node->node);
|
||||
+ conn->flags &= ~CO_FL_LIST_MASK;
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
}
|
||||
@@ -4235,8 +4237,10 @@ struct task *h2_timeout_task(struct task *t, void *context, unsigned int state)
|
||||
/* We're about to destroy the connection, so make sure nobody attempts
|
||||
* to steal it from us.
|
||||
*/
|
||||
- if (h2c->conn->flags & CO_FL_LIST_MASK)
|
||||
+ if (h2c->conn->flags & CO_FL_LIST_MASK) {
|
||||
conn_delete_from_tree(&h2c->conn->hash_node->node);
|
||||
+ h2c->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
+ }
|
||||
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
@@ -4289,6 +4293,7 @@ struct task *h2_timeout_task(struct task *t, void *context, unsigned int state)
|
||||
if (h2c->conn->flags & CO_FL_LIST_MASK) {
|
||||
HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
conn_delete_from_tree(&h2c->conn->hash_node->node);
|
||||
+ h2c->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
|
||||
diff --git a/src/server.c b/src/server.c
|
||||
index f35190d..b8e1f0a 100644
|
||||
--- a/src/server.c
|
||||
+++ b/src/server.c
|
||||
@@ -5714,6 +5714,7 @@ static int srv_migrate_conns_to_remove(struct eb_root *idle_tree, struct mt_list
|
||||
|
||||
hash_node = ebmb_entry(node, struct conn_hash_node, node);
|
||||
eb_delete(node);
|
||||
+ hash_node->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
MT_LIST_APPEND(toremove_list, &hash_node->conn->toremove_list);
|
||||
i++;
|
||||
|
||||
@@ -5771,6 +5772,7 @@ void srv_release_conn(struct server *srv, struct connection *conn)
|
||||
/* Remove the connection from any tree (safe, idle or available) */
|
||||
HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
conn_delete_from_tree(&conn->hash_node->node);
|
||||
+ conn->flags &= ~CO_FL_LIST_MASK;
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,212 @@
|
||||
From a53fdaf7203e45f67c44d7e250cec36875ea8e01 Mon Sep 17 00:00:00 2001
|
||||
From: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Thu, 16 Mar 2023 11:43:05 +0100
|
||||
Subject: [PATCH] BUG/MEDIUM: connection: Preserve flags when a conn is removed
|
||||
from an idle list
|
||||
|
||||
The commit 5e1b0e7bf ("BUG/MEDIUM: connection: Clear flags when a conn is
|
||||
removed from an idle list") introduced a regression. CO_FL_SAFE_LIST and
|
||||
CO_FL_IDLE_LIST flags are used when the connection is released to properly
|
||||
decrement used/idle connection counters. if a connection is idle, these
|
||||
flags must be preserved till the connection is really released. It may be
|
||||
removed from the list but not immediately released. If these flags are lost
|
||||
when it is finally released, the current number of used connections is
|
||||
erroneously decremented. If means this counter may become negative and the
|
||||
counters tracking the number of idle connecitons is not decremented,
|
||||
suggesting a leak.
|
||||
|
||||
So, the above commit is reverted and instead we improve a bit the way to
|
||||
detect an idle connection. The function conn_get_idle_flag() must now be
|
||||
used to know if a connection is in an idle list. It returns the connection
|
||||
flag corresponding to the idle list if the connection is idle
|
||||
(CO_FL_SAFE_LIST or CO_FL_IDLE_LIST) or 0 otherwise. But if the connection
|
||||
is scheduled to be removed, 0 is also returned, regardless the connection
|
||||
flags.
|
||||
|
||||
This new function is used when the connection is temporarily removed from
|
||||
the list to be used, mainly in muxes.
|
||||
|
||||
This patch should fix #2078 and #2057. It must be backported as far as 2.2.
|
||||
|
||||
(cherry picked from commit 3a7b539b124bccaa57478e0a5a6d66338594615a)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit a81a1e2aea0793aa624565a14cb7579b907f116a)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=a53fdaf7203e45f67c44d7e250cec36875ea8e01
|
||||
---
|
||||
include/haproxy/connection.h | 10 ++++++++++
|
||||
src/connection.c | 2 +-
|
||||
src/mux_fcgi.c | 6 ++----
|
||||
src/mux_h1.c | 6 ++----
|
||||
src/mux_h2.c | 10 ++--------
|
||||
src/server.c | 1 -
|
||||
src/ssl_sock.c | 2 +-
|
||||
7 files changed, 18 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h
|
||||
index 4d289e7b3..8cf22ef4f 100644
|
||||
--- a/include/haproxy/connection.h
|
||||
+++ b/include/haproxy/connection.h
|
||||
@@ -316,6 +316,16 @@ static inline void conn_set_private(struct connection *conn)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Used to know if a connection is in an idle list. It returns connection flag
|
||||
+ * corresponding to the idle list if the connection is idle (CO_FL_SAFE_LIST or
|
||||
+ * CO_FL_IDLE_LIST) or 0 otherwise. Note that if the connection is scheduled to
|
||||
+ * be removed, 0 is returned, regardless the connection flags.
|
||||
+ */
|
||||
+static inline unsigned int conn_get_idle_flag(const struct connection *conn)
|
||||
+{
|
||||
+ return (!MT_LIST_INLIST(&conn->toremove_list) ? conn->flags & CO_FL_LIST_MASK : 0);
|
||||
+}
|
||||
+
|
||||
static inline void conn_force_unsubscribe(struct connection *conn)
|
||||
{
|
||||
if (!conn->subs)
|
||||
diff --git a/src/connection.c b/src/connection.c
|
||||
index 4a73dbcc8..5a459fd98 100644
|
||||
--- a/src/connection.c
|
||||
+++ b/src/connection.c
|
||||
@@ -146,7 +146,7 @@ int conn_notify_mux(struct connection *conn, int old_flags, int forced_wake)
|
||||
((conn->flags ^ old_flags) & CO_FL_NOTIFY_DONE) ||
|
||||
((old_flags & CO_FL_WAIT_XPRT) && !(conn->flags & CO_FL_WAIT_XPRT))) &&
|
||||
conn->mux && conn->mux->wake) {
|
||||
- uint conn_in_list = conn->flags & CO_FL_LIST_MASK;
|
||||
+ uint conn_in_list = conn_get_idle_flag(conn);
|
||||
struct server *srv = objt_server(conn->target);
|
||||
|
||||
if (conn_in_list) {
|
||||
diff --git a/src/mux_fcgi.c b/src/mux_fcgi.c
|
||||
index 4981f6bab..2c417dd1f 100644
|
||||
--- a/src/mux_fcgi.c
|
||||
+++ b/src/mux_fcgi.c
|
||||
@@ -3043,7 +3043,7 @@ struct task *fcgi_io_cb(struct task *t, void *ctx, unsigned int state)
|
||||
conn = fconn->conn;
|
||||
TRACE_POINT(FCGI_EV_FCONN_WAKE, conn);
|
||||
|
||||
- conn_in_list = conn->flags & CO_FL_LIST_MASK;
|
||||
+ conn_in_list = conn_get_idle_flag(conn);
|
||||
if (conn_in_list)
|
||||
conn_delete_from_tree(&conn->hash_node->node);
|
||||
|
||||
@@ -3227,10 +3227,8 @@ struct task *fcgi_timeout_task(struct task *t, void *context, unsigned int state
|
||||
/* We're about to destroy the connection, so make sure nobody attempts
|
||||
* to steal it from us.
|
||||
*/
|
||||
- if (fconn->conn->flags & CO_FL_LIST_MASK) {
|
||||
+ if (fconn->conn->flags & CO_FL_LIST_MASK)
|
||||
conn_delete_from_tree(&fconn->conn->hash_node->node);
|
||||
- fconn->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
- }
|
||||
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
diff --git a/src/mux_h1.c b/src/mux_h1.c
|
||||
index 56b08a77e..6f59b3112 100644
|
||||
--- a/src/mux_h1.c
|
||||
+++ b/src/mux_h1.c
|
||||
@@ -3158,7 +3158,7 @@ struct task *h1_io_cb(struct task *t, void *ctx, unsigned int state)
|
||||
/* Remove the connection from the list, to be sure nobody attempts
|
||||
* to use it while we handle the I/O events
|
||||
*/
|
||||
- conn_in_list = conn->flags & CO_FL_LIST_MASK;
|
||||
+ conn_in_list = conn_get_idle_flag(conn);
|
||||
if (conn_in_list)
|
||||
conn_delete_from_tree(&conn->hash_node->node);
|
||||
|
||||
@@ -3282,10 +3282,8 @@ struct task *h1_timeout_task(struct task *t, void *context, unsigned int state)
|
||||
/* We're about to destroy the connection, so make sure nobody attempts
|
||||
* to steal it from us.
|
||||
*/
|
||||
- if (h1c->conn->flags & CO_FL_LIST_MASK) {
|
||||
+ if (h1c->conn->flags & CO_FL_LIST_MASK)
|
||||
conn_delete_from_tree(&h1c->conn->hash_node->node);
|
||||
- h1c->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
- }
|
||||
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
diff --git a/src/mux_h2.c b/src/mux_h2.c
|
||||
index f4cb5b188..b62a8f60e 100644
|
||||
--- a/src/mux_h2.c
|
||||
+++ b/src/mux_h2.c
|
||||
@@ -4027,11 +4027,10 @@ struct task *h2_io_cb(struct task *t, void *ctx, unsigned int state)
|
||||
conn = h2c->conn;
|
||||
TRACE_ENTER(H2_EV_H2C_WAKE, conn);
|
||||
|
||||
- conn_in_list = conn->flags & CO_FL_LIST_MASK;
|
||||
-
|
||||
/* Remove the connection from the list, to be sure nobody attempts
|
||||
* to use it while we handle the I/O events
|
||||
*/
|
||||
+ conn_in_list = conn_get_idle_flag(conn);
|
||||
if (conn_in_list)
|
||||
conn_delete_from_tree(&conn->hash_node->node);
|
||||
|
||||
@@ -4163,7 +4162,6 @@ static int h2_process(struct h2c *h2c)
|
||||
if (conn->flags & CO_FL_LIST_MASK) {
|
||||
HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
conn_delete_from_tree(&conn->hash_node->node);
|
||||
- conn->flags &= ~CO_FL_LIST_MASK;
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
}
|
||||
@@ -4172,7 +4170,6 @@ static int h2_process(struct h2c *h2c)
|
||||
if (conn->flags & CO_FL_LIST_MASK) {
|
||||
HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
conn_delete_from_tree(&conn->hash_node->node);
|
||||
- conn->flags &= ~CO_FL_LIST_MASK;
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
}
|
||||
@@ -4253,10 +4250,8 @@ struct task *h2_timeout_task(struct task *t, void *context, unsigned int state)
|
||||
/* We're about to destroy the connection, so make sure nobody attempts
|
||||
* to steal it from us.
|
||||
*/
|
||||
- if (h2c->conn->flags & CO_FL_LIST_MASK) {
|
||||
+ if (h2c->conn->flags & CO_FL_LIST_MASK)
|
||||
conn_delete_from_tree(&h2c->conn->hash_node->node);
|
||||
- h2c->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
- }
|
||||
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
@@ -4309,7 +4304,6 @@ struct task *h2_timeout_task(struct task *t, void *context, unsigned int state)
|
||||
if (h2c->conn->flags & CO_FL_LIST_MASK) {
|
||||
HA_SPIN_LOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
conn_delete_from_tree(&h2c->conn->hash_node->node);
|
||||
- h2c->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
}
|
||||
|
||||
diff --git a/src/server.c b/src/server.c
|
||||
index 8a282bcf9..d701eaeab 100644
|
||||
--- a/src/server.c
|
||||
+++ b/src/server.c
|
||||
@@ -5717,7 +5717,6 @@ static int srv_migrate_conns_to_remove(struct eb_root *idle_tree, struct mt_list
|
||||
|
||||
hash_node = ebmb_entry(node, struct conn_hash_node, node);
|
||||
eb_delete(node);
|
||||
- hash_node->conn->flags &= ~CO_FL_LIST_MASK;
|
||||
MT_LIST_APPEND(toremove_list, &hash_node->conn->toremove_list);
|
||||
i++;
|
||||
|
||||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
|
||||
index 919a08a88..b2f937487 100644
|
||||
--- a/src/ssl_sock.c
|
||||
+++ b/src/ssl_sock.c
|
||||
@@ -6481,7 +6481,7 @@ struct task *ssl_sock_io_cb(struct task *t, void *context, unsigned int state)
|
||||
return NULL;
|
||||
}
|
||||
conn = ctx->conn;
|
||||
- conn_in_list = conn->flags & CO_FL_LIST_MASK;
|
||||
+ conn_in_list = conn_get_idle_flag(conn);
|
||||
if (conn_in_list)
|
||||
conn_delete_from_tree(&conn->hash_node->node);
|
||||
HA_SPIN_UNLOCK(IDLE_CONNS_LOCK, &idle_conns[tid].idle_conns_lock);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From 3311c72eabc15fc3824cf09537785ccbb1c3b88f Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Mon, 20 Mar 2023 19:11:08 +0100
|
||||
Subject: [PATCH] BUG/MEDIUM: stream: do not try to free a failed stream-conn
|
||||
|
||||
In stream_free() if we fail to allocate s->scb() we go to the path where
|
||||
we try to free it, and it doesn't like being called with a null at all.
|
||||
It's easily reproducible with -dMfail,no-cache and "tune.fail-alloc 10"
|
||||
in the global section.
|
||||
|
||||
This must be backported to 2.6.
|
||||
|
||||
(cherry picked from commit a45e7e81ec54fd0562d8ab4776b4c05584d6d180)
|
||||
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
|
||||
(cherry picked from commit 8daac8191313b625efeaf2799a4c05b585a44474)
|
||||
Signed-off-by: Amaury Denoyelle <adenoyelle@haproxy.com>
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=3311c72eabc15fc3824cf09537785ccbb1c3b88f
|
||||
---
|
||||
src/stream.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/stream.c b/src/stream.c
|
||||
index 7eaf03995..224b9b8a2 100644
|
||||
--- a/src/stream.c
|
||||
+++ b/src/stream.c
|
||||
@@ -575,8 +575,8 @@ struct stream *stream_new(struct session *sess, struct stconn *sc, struct buffer
|
||||
out_fail_accept:
|
||||
flt_stream_release(s, 0);
|
||||
LIST_DELETE(&s->list);
|
||||
- out_fail_alloc_scb:
|
||||
sc_free(s->scb);
|
||||
+ out_fail_alloc_scb:
|
||||
out_fail_attach_scf:
|
||||
task_destroy(t);
|
||||
out_fail_alloc:
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
From 61882cc68c8336016f158f74c0944e1b047c6f5f Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien DARRAGON <adarragon@haproxy.com>
|
||||
Date: Fri, 18 Nov 2022 09:17:29 +0100
|
||||
Subject: [PATCH] BUG/MINOR: http_ana/txn: don't re-initialize txn and req var
|
||||
lists
|
||||
|
||||
In http_create_txn(): vars_init_head() was performed on both s->vars_txn
|
||||
and s->var_reqres lists.
|
||||
|
||||
But this is wrong, these two lists are already initialized upon stream
|
||||
creation in stream_new().
|
||||
Moreover, between stream_new() and http_create_txn(), some variable may
|
||||
be defined (e.g.: by the frontend), resulting in lists not being empty.
|
||||
|
||||
Because of this "extra" list initialization, already defined variables
|
||||
can be lost.
|
||||
This causes txn dependant code not being able to access previously defined
|
||||
variables as well as memory leak because http_destroy_txn() relies on these
|
||||
lists to perform the purge.
|
||||
|
||||
This proved to be the case when a frontend sets variables and lua sample
|
||||
fetch is used in backend section as described in GH #1935.
|
||||
Many thanks to Darragh O'Toole for his detailed report.
|
||||
|
||||
Removing extra var_init_head (x2) in http_create_txn() to fix the issue.
|
||||
Adding somme comments in the code in an attempt to prevent future misuses
|
||||
of s->var_reqres, and s->var_txn lists.
|
||||
|
||||
It should be backported in every stable version.
|
||||
(This is an old bug that seems to exist since 1.6-dev6)
|
||||
|
||||
[cf: On 2.0 and 1.8, for the legacy HTTP code, vars_init() are used during
|
||||
the TXN cleanup, when the stream is reused. So, these calls must be
|
||||
moved from http_init_txn() to http_reset_txn() and not removed.]
|
||||
|
||||
(cherry picked from commit 5ad2b642625b89cdf4f5fd26a598fc480abdc806)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=61882cc68c8336016f158f74c0944e1b047c6f5f
|
||||
---
|
||||
src/http_ana.c | 6 ++++--
|
||||
src/stream.c | 11 ++++++++++-
|
||||
2 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/http_ana.c b/src/http_ana.c
|
||||
index 2b2cfdc56..379b480a8 100644
|
||||
--- a/src/http_ana.c
|
||||
+++ b/src/http_ana.c
|
||||
@@ -5224,8 +5224,10 @@ struct http_txn *http_create_txn(struct stream *s)
|
||||
|
||||
txn->auth.method = HTTP_AUTH_UNKNOWN;
|
||||
|
||||
- vars_init_head(&s->vars_txn, SCOPE_TXN);
|
||||
- vars_init_head(&s->vars_reqres, SCOPE_REQ);
|
||||
+ /* here we don't want to re-initialize s->vars_txn and s->vars_reqres
|
||||
+ * variable lists, because they were already initialized upon stream
|
||||
+ * creation in stream_new(), and thus may already contain some variables
|
||||
+ */
|
||||
|
||||
return txn;
|
||||
}
|
||||
diff --git a/src/stream.c b/src/stream.c
|
||||
index c04dd565c..7eaf03995 100644
|
||||
--- a/src/stream.c
|
||||
+++ b/src/stream.c
|
||||
@@ -435,8 +435,17 @@ struct stream *stream_new(struct session *sess, struct stconn *sc, struct buffer
|
||||
s->req_cap = NULL;
|
||||
s->res_cap = NULL;
|
||||
|
||||
- /* Initialise all the variables contexts even if not used.
|
||||
+ /* Initialize all the variables contexts even if not used.
|
||||
* This permits to prune these contexts without errors.
|
||||
+ *
|
||||
+ * We need to make sure that those lists are not re-initialized
|
||||
+ * by stream-dependant underlying code because we could lose
|
||||
+ * track of already defined variables, leading to data inconsistency
|
||||
+ * and memory leaks...
|
||||
+ *
|
||||
+ * For reference: we had a very old bug caused by vars_txn and
|
||||
+ * vars_reqres being accidentally re-initialized in http_create_txn()
|
||||
+ * (https://github.com/haproxy/haproxy/issues/1935)
|
||||
*/
|
||||
vars_init_head(&s->vars_txn, SCOPE_TXN);
|
||||
vars_init_head(&s->vars_reqres, SCOPE_REQ);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,111 @@
|
||||
From cb9a8fdbaef4a642eeb84ac9feaf636720d18360 Mon Sep 17 00:00:00 2001
|
||||
From: William Lallemand <wlallemand@haproxy.org>
|
||||
Date: Fri, 17 Feb 2023 16:23:52 +0100
|
||||
Subject: [PATCH] BUG/MINOR: mworker: prevent incorrect values in uptime
|
||||
|
||||
Since the recent changes on the clocks, now.tv_sec is not to be used
|
||||
between processes because it's a clock which is local to the process and
|
||||
does not contain a real unix timestamp. This patch fixes the issue by
|
||||
using "data.tv_sec" which is the wall clock instead of "now.tv_sec'.
|
||||
It prevents having incoherent timestamps.
|
||||
|
||||
It also introduces some checks on negatives values in order to never
|
||||
displays a netative value if it was computed from a wrong value set by a
|
||||
previous haproxy version.
|
||||
|
||||
It must be backported as far as 2.0.
|
||||
|
||||
(cherry picked from commit 5a7f83af84d2a08f69ce1629c7609c98f43411ab)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 7b8337e0cbaeebec26eab0062f0706f9388e3e2c)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=cb9a8fdbaef4a642eeb84ac9feaf636720d18360
|
||||
---
|
||||
src/haproxy.c | 2 +-
|
||||
src/mworker.c | 21 ++++++++++++++++-----
|
||||
2 files changed, 17 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/haproxy.c b/src/haproxy.c
|
||||
index 5a3f6c755..0cb0662d2 100644
|
||||
--- a/src/haproxy.c
|
||||
+++ b/src/haproxy.c
|
||||
@@ -3432,7 +3432,7 @@ int main(int argc, char **argv)
|
||||
if (child->reloads == 0 &&
|
||||
child->options & PROC_O_TYPE_WORKER &&
|
||||
child->pid == -1) {
|
||||
- child->timestamp = now.tv_sec;
|
||||
+ child->timestamp = date.tv_sec;
|
||||
child->pid = ret;
|
||||
child->version = strdup(haproxy_version);
|
||||
break;
|
||||
diff --git a/src/mworker.c b/src/mworker.c
|
||||
index 686fc755d..26b16cca4 100644
|
||||
--- a/src/mworker.c
|
||||
+++ b/src/mworker.c
|
||||
@@ -559,13 +559,16 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
|
||||
struct stconn *sc = appctx_sc(appctx);
|
||||
struct mworker_proc *child;
|
||||
int old = 0;
|
||||
- int up = now.tv_sec - proc_self->timestamp;
|
||||
+ int up = date.tv_sec - proc_self->timestamp;
|
||||
char *uptime = NULL;
|
||||
char *reloadtxt = NULL;
|
||||
|
||||
if (unlikely(sc_ic(sc)->flags & (CF_WRITE_ERROR|CF_SHUTW)))
|
||||
return 1;
|
||||
|
||||
+ if (up < 0) /* must never be negative because of clock drift */
|
||||
+ up = 0;
|
||||
+
|
||||
chunk_reset(&trash);
|
||||
|
||||
memprintf(&reloadtxt, "%d [failed: %d]", proc_self->reloads, proc_self->failedreloads);
|
||||
@@ -579,7 +582,9 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
|
||||
|
||||
chunk_appendf(&trash, "# workers\n");
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
- up = now.tv_sec - child->timestamp;
|
||||
+ up = date.tv_sec - child->timestamp;
|
||||
+ if (up < 0) /* must never be negative because of clock drift */
|
||||
+ up = 0;
|
||||
|
||||
if (!(child->options & PROC_O_TYPE_WORKER))
|
||||
continue;
|
||||
@@ -600,7 +605,9 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
|
||||
|
||||
chunk_appendf(&trash, "# old workers\n");
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
- up = now.tv_sec - child->timestamp;
|
||||
+ up = date.tv_sec - child->timestamp;
|
||||
+ if (up <= 0) /* must never be negative because of clock drift */
|
||||
+ up = 0;
|
||||
|
||||
if (!(child->options & PROC_O_TYPE_WORKER))
|
||||
continue;
|
||||
@@ -618,7 +625,9 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
|
||||
chunk_appendf(&trash, "# programs\n");
|
||||
old = 0;
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
- up = now.tv_sec - child->timestamp;
|
||||
+ up = date.tv_sec - child->timestamp;
|
||||
+ if (up < 0) /* must never be negative because of clock drift */
|
||||
+ up = 0;
|
||||
|
||||
if (!(child->options & PROC_O_TYPE_PROG))
|
||||
continue;
|
||||
@@ -635,7 +644,9 @@ static int cli_io_handler_show_proc(struct appctx *appctx)
|
||||
if (old) {
|
||||
chunk_appendf(&trash, "# old programs\n");
|
||||
list_for_each_entry(child, &proc_list, list) {
|
||||
- up = now.tv_sec - child->timestamp;
|
||||
+ up = date.tv_sec - child->timestamp;
|
||||
+ if (up < 0) /* must never be negative because of clock drift */
|
||||
+ up = 0;
|
||||
|
||||
if (!(child->options & PROC_O_TYPE_PROG))
|
||||
continue;
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
From 44eef1b3b566ec73a6d242ca347e6b6111dfabaa Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien DARRAGON <adarragon@haproxy.com>
|
||||
Date: Tue, 7 Feb 2023 15:51:58 +0100
|
||||
Subject: [PATCH] BUG/MINOR: protocol: fix minor memory leak in
|
||||
protocol_bind_all()
|
||||
|
||||
In protocol_bind_all() (involved in startup sequence):
|
||||
We only free errmsg (set by fam->bind() attempt) when we make use of it.
|
||||
But this could lead to some memory leaks because there are some cases
|
||||
where we ignore the error message (e.g: verbose=0 with ERR_WARN messages).
|
||||
|
||||
As long as errmsg is set, we should always free it.
|
||||
|
||||
As mentioned earlier, this really is a minor leak because it can only occur on
|
||||
specific conditions (error paths) during the startup phase.
|
||||
|
||||
This may be backported up to 2.4.
|
||||
|
||||
--
|
||||
Backport notes:
|
||||
|
||||
-> 2.4 only:
|
||||
|
||||
Replace this:
|
||||
|
||||
| ha_warning("Binding [%s:%d] for %s %s: %s\n",
|
||||
| listener->bind_conf->file, listener->bind_conf->line,
|
||||
| proxy_type_str(px), px->id, errmsg);
|
||||
|
||||
By this:
|
||||
|
||||
| else if (lerr & ERR_WARN)
|
||||
| ha_warning("Starting %s %s: %s\n",
|
||||
| proxy_type_str(px), px->id, errmsg);
|
||||
|
||||
(cherry picked from commit 8429627e3c2eb472dc94ec8d3d7275ef68a79128)
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
(cherry picked from commit da9a15ff0326d59ba38f5a1b258820d91c7df649)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=44eef1b3b566ec73a6d242ca347e6b6111dfabaa
|
||||
---
|
||||
src/protocol.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/protocol.c b/src/protocol.c
|
||||
index 03f708591..146733a3f 100644
|
||||
--- a/src/protocol.c
|
||||
+++ b/src/protocol.c
|
||||
@@ -92,8 +92,10 @@ int protocol_bind_all(int verbose)
|
||||
ha_warning("Binding [%s:%d] for %s %s: %s\n",
|
||||
listener->bind_conf->file, listener->bind_conf->line,
|
||||
proxy_type_str(px), px->id, errmsg);
|
||||
- ha_free(&errmsg);
|
||||
}
|
||||
+ if (lerr != ERR_NONE)
|
||||
+ ha_free(&errmsg);
|
||||
+
|
||||
if (lerr & ERR_ABORT)
|
||||
break;
|
||||
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
From 6647a2439ba0e88aac2b1bfd313143e68c3b463a Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien DARRAGON <adarragon@haproxy.com>
|
||||
Date: Fri, 15 Sep 2023 00:42:55 +0200
|
||||
Subject: [PATCH] BUG/MINOR: server: add missing free for server->rdr_pfx
|
||||
|
||||
rdr_pfx was not being free during server cleanup, leading to small memory
|
||||
leak when "redir" argument was used on a server line (HTTP only).
|
||||
|
||||
This should be backported to every stable versions.
|
||||
|
||||
[For 2.6 and 2.7: the free should be performed in srv_drop() directly.
|
||||
For older versions: free in deinit() function near the free for the
|
||||
cookie string]
|
||||
|
||||
(cherry picked from commit 2c9bd3ae808872e52c07d7ec1d62f734dcbb6776)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit d2d7fbd1ef16beb525b7b869d48b1519dbe7f4cc)
|
||||
[cf: free performed in srv_drop() as expected]
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 16fe0670060c4aaa26a0961e5fafa4d71fab87cc)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=6647a2439ba0e88aac2b1bfd313143e68c3b463a
|
||||
---
|
||||
src/server.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/server.c b/src/server.c
|
||||
index 7935668..70d4bc8 100644
|
||||
--- a/src/server.c
|
||||
+++ b/src/server.c
|
||||
@@ -2377,6 +2377,7 @@ struct server *srv_drop(struct server *srv)
|
||||
|
||||
free(srv->id);
|
||||
free(srv->cookie);
|
||||
+ free(srv->rdr_pfx);
|
||||
free(srv->hostname);
|
||||
free(srv->hostname_dn);
|
||||
free((char*)srv->conf.file);
|
||||
--
|
||||
1.7.10.4
|
||||
@ -0,0 +1,61 @@
|
||||
From 50bf172a2c4d448145a2061dfbaa5ee2a413874e Mon Sep 17 00:00:00 2001
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Thu, 23 Nov 2023 14:28:14 +0100
|
||||
Subject: [PATCH] BUG/MINOR: server: do not leak default-server in defaults
|
||||
sections
|
||||
|
||||
When a default-server directive is used in a defaults section, it's never
|
||||
freed and the "defaults" proxy gets reset without freeing the fields from
|
||||
that default-server. Normally there are no allocation there, except for
|
||||
the config file location stored in srv->conf.file form an strdup() since
|
||||
commit 9394a9444 ("REORG: server: move alert traces in parse_server")
|
||||
that appeared in 2.4. In addition, if a "default-server" directive
|
||||
appears multiple times in a defaults section, one more entry will be
|
||||
leaked per call.
|
||||
|
||||
This commit addresses this by checking that we don't overwrite the file
|
||||
upon multiple calls, and by clearing it when resetting the default proxy.
|
||||
This should be backported to 2.4.
|
||||
|
||||
(cherry picked from commit 53da8bfcb6d3f4918a45fe77347317ad885ba25e)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 8bb771af10bf68ffb46edba4bb601bd2a79ff5bd)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
(cherry picked from commit 0810c8082b5db901f823b554602702ae52881fc1)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=50bf172a2c4d448145a2061dfbaa5ee2a413874e
|
||||
---
|
||||
src/proxy.c | 1 +
|
||||
src/server.c | 3 ++-
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/proxy.c b/src/proxy.c
|
||||
index dea6004ec..8bfe1175c 100644
|
||||
--- a/src/proxy.c
|
||||
+++ b/src/proxy.c
|
||||
@@ -1442,6 +1442,7 @@ void proxy_free_defaults(struct proxy *defproxy)
|
||||
|
||||
ha_free(&defproxy->id);
|
||||
ha_free(&defproxy->conf.file);
|
||||
+ ha_free((char **)&defproxy->defsrv.conf.file);
|
||||
ha_free(&defproxy->check_command);
|
||||
ha_free(&defproxy->check_path);
|
||||
ha_free(&defproxy->cookie_name);
|
||||
diff --git a/src/server.c b/src/server.c
|
||||
index a927811a9..eb78cc02e 100644
|
||||
--- a/src/server.c
|
||||
+++ b/src/server.c
|
||||
@@ -2927,7 +2927,8 @@ int parse_server(const char *file, int linenum, char **args,
|
||||
if (err_code & ERR_CODE)
|
||||
goto out;
|
||||
|
||||
- newsrv->conf.file = strdup(file);
|
||||
+ if (!newsrv->conf.file) // note: do it only once for default-server
|
||||
+ newsrv->conf.file = strdup(file);
|
||||
newsrv->conf.line = linenum;
|
||||
|
||||
while (*args[cur_arg]) {
|
||||
--
|
||||
2.33.0
|
||||
@ -0,0 +1,48 @@
|
||||
From f233b187f5f101a724c6fdde5b0a9e4fb6d6d50e Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien DARRAGON <adarragon@haproxy.com>
|
||||
Date: Wed, 14 Jun 2023 09:53:32 +0200
|
||||
Subject: [PATCH] BUG/MINOR: server: inherit from netns in srv_settings_cpy()
|
||||
|
||||
When support for 'namespace' keyword was added for the 'default-server'
|
||||
directive in 22f41a2 ("MINOR: server: Make 'default-server' support
|
||||
'namespace' keyword."), we forgot to copy the attribute from the parent
|
||||
to the newly created server.
|
||||
|
||||
This resulted in the 'namespace' keyword being parsed without errors when
|
||||
used from a 'default-server' directive, but in practise the option was
|
||||
simply ignored.
|
||||
|
||||
There's no need to duplicate the netns struct because it is stored in
|
||||
a shared list, so copying the pointer does the job.
|
||||
|
||||
This patch partially fixes GH #2038 and should be backported to all
|
||||
stable versions.
|
||||
|
||||
(cherry picked from commit 19b5a7c7a5b4b01970e06d20928ed1d87ca6efcd)
|
||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
|
||||
(cherry picked from commit 60d185d9320ae1293c466e004b059b0310dcb13c)
|
||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
|
||||
(cherry picked from commit 20e6fa6abf259c20ad471f44d646d0f0ee28f3ec)
|
||||
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=f233b187f5f101a724c6fdde5b0a9e4fb6d6d50e
|
||||
---
|
||||
src/server.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/server.c b/src/server.c
|
||||
index e9e09dd6d..7935668b1 100644
|
||||
--- a/src/server.c
|
||||
+++ b/src/server.c
|
||||
@@ -2280,6 +2280,7 @@ void srv_settings_cpy(struct server *srv, const struct server *src, int srv_tmpl
|
||||
if (srv_tmpl)
|
||||
srv->srvrq = src->srvrq;
|
||||
|
||||
+ srv->netns = src->netns;
|
||||
srv->check.via_socks4 = src->check.via_socks4;
|
||||
srv->socks4_addr = src->socks4_addr;
|
||||
}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From b3dc43ddadfd98b745823deaed6e7743b59442eb Mon Sep 17 00:00:00 2001
|
||||
From: Christopher Faulet <cfaulet@haproxy.com>
|
||||
Date: Tue, 27 Sep 2022 09:14:47 +0200
|
||||
Subject: [PATCH] BUG/MINOR: stream: Perform errors handling in right order in
|
||||
stream_new()
|
||||
|
||||
The frontend SC is attached before the backend one is allocated. Thus an
|
||||
allocation error on backend SC must be handled before an error on the
|
||||
frontend SC.
|
||||
|
||||
This patch must be backported to 2.6.
|
||||
|
||||
(cherry picked from commit 4cfc038cb19996f5d2fe60284fdb556503a5f9ef)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
|
||||
Conflict: NA
|
||||
Reference: https://git.haproxy.org/?p=haproxy-2.6.git;a=commit;h=b3dc43ddadfd98b745823deaed6e7743b59442eb
|
||||
---
|
||||
src/stream.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/stream.c b/src/stream.c
|
||||
index 0cbbb70b7..fc8b82af0 100644
|
||||
--- a/src/stream.c
|
||||
+++ b/src/stream.c
|
||||
@@ -566,9 +566,9 @@ struct stream *stream_new(struct session *sess, struct stconn *sc, struct buffer
|
||||
out_fail_accept:
|
||||
flt_stream_release(s, 0);
|
||||
LIST_DELETE(&s->list);
|
||||
- out_fail_attach_scf:
|
||||
- sc_free(s->scb);
|
||||
out_fail_alloc_scb:
|
||||
+ sc_free(s->scb);
|
||||
+ out_fail_attach_scf:
|
||||
task_destroy(t);
|
||||
out_fail_alloc:
|
||||
pool_free(pool_head_stream, s);
|
||||
--
|
||||
2.33.0
|
||||
|
||||
39
backport-errors-handle-malloc-failure-in-usermsgs_put.patch
Normal file
39
backport-errors-handle-malloc-failure-in-usermsgs_put.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From d4dba38ab101eee4cbd0c8d8aa21181825ef6472 Mon Sep 17 00:00:00 2001
|
||||
From: Aurelien DARRAGON <adarragon@haproxy.com>
|
||||
Date: Thu, 11 May 2023 18:49:14 +0200
|
||||
Subject: [PATCH] BUG/MINOR: errors: handle malloc failure in usermsgs_put()
|
||||
|
||||
usermsgs_buf.size is set without first checking if previous malloc
|
||||
attempt succeeded.
|
||||
|
||||
This could fool the buffer API into assuming that the buffer is
|
||||
initialized, resulting in unsafe read/writes.
|
||||
|
||||
Guarding usermsgs_buf.size assignment with the malloc attempt result
|
||||
to make the buffer initialization safe against malloc failures.
|
||||
|
||||
This partially fixes GH #2130.
|
||||
|
||||
It should be backported up to 2.6.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/haproxy/haproxy/commit/d4dba38ab101eee4cbd0c8d8aa21181825ef6472
|
||||
|
||||
---
|
||||
src/errors.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/errors.c b/src/errors.c
|
||||
index 2e9d6afb7e04..5913cb1d509d 100644
|
||||
--- a/src/errors.c
|
||||
+++ b/src/errors.c
|
||||
@@ -229,7 +229,8 @@ static void usermsgs_put(const struct ist *msg)
|
||||
/* Allocate the buffer if not already done. */
|
||||
if (unlikely(b_is_null(&usermsgs_buf))) {
|
||||
usermsgs_buf.area = malloc(USER_MESSAGES_BUFSIZE * sizeof(char));
|
||||
- usermsgs_buf.size = USER_MESSAGES_BUFSIZE;
|
||||
+ if (usermsgs_buf.area)
|
||||
+ usermsgs_buf.size = USER_MESSAGES_BUFSIZE;
|
||||
}
|
||||
|
||||
if (likely(!b_is_null(&usermsgs_buf))) {
|
||||
43
backport-ssl_sock-add-check-for-ha_meth.patch
Normal file
43
backport-ssl_sock-add-check-for-ha_meth.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 15c3d20e315f1f06c9649ae598de86d61d41085b Mon Sep 17 00:00:00 2001
|
||||
From: eaglegai <eaglegai@163.com>
|
||||
Date: Fri, 26 May 2023 16:42:47 +0800
|
||||
Subject: [PATCH] BUG/MINOR: ssl_sock: add check for ha_meth
|
||||
|
||||
in __ssl_sock_init, BIO_meth_new may failed and return NULL if
|
||||
OPENSSL_zalloc failed. in this case, ha_meth will be NULL, and then
|
||||
crash happens in BIO_meth_set_write. So, we add a check for ha_meth.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/haproxy/haproxy/commit/15c3d20e315f1f06c9649ae598de86d61d41085b
|
||||
|
||||
---
|
||||
src/ssl_sock.c | 16 +++++++++-------
|
||||
1 file changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
|
||||
index e637b0423a9a..ff0db9d1a1c2 100644
|
||||
--- a/src/ssl_sock.c
|
||||
+++ b/src/ssl_sock.c
|
||||
@@ -7561,13 +7561,15 @@ static void __ssl_sock_init(void)
|
||||
ERR_load_SSL_strings();
|
||||
#endif
|
||||
ha_meth = BIO_meth_new(0x666, "ha methods");
|
||||
- BIO_meth_set_write(ha_meth, ha_ssl_write);
|
||||
- BIO_meth_set_read(ha_meth, ha_ssl_read);
|
||||
- BIO_meth_set_ctrl(ha_meth, ha_ssl_ctrl);
|
||||
- BIO_meth_set_create(ha_meth, ha_ssl_new);
|
||||
- BIO_meth_set_destroy(ha_meth, ha_ssl_free);
|
||||
- BIO_meth_set_puts(ha_meth, ha_ssl_puts);
|
||||
- BIO_meth_set_gets(ha_meth, ha_ssl_gets);
|
||||
+ if (ha_meth != NULL) {
|
||||
+ BIO_meth_set_write(ha_meth, ha_ssl_write);
|
||||
+ BIO_meth_set_read(ha_meth, ha_ssl_read);
|
||||
+ BIO_meth_set_ctrl(ha_meth, ha_ssl_ctrl);
|
||||
+ BIO_meth_set_create(ha_meth, ha_ssl_new);
|
||||
+ BIO_meth_set_destroy(ha_meth, ha_ssl_free);
|
||||
+ BIO_meth_set_puts(ha_meth, ha_ssl_puts);
|
||||
+ BIO_meth_set_gets(ha_meth, ha_ssl_gets);
|
||||
+ }
|
||||
|
||||
HA_SPIN_INIT(&ckch_lock);
|
||||
|
||||
31
backport-thread-add-a-check-for-pthread_create.patch
Normal file
31
backport-thread-add-a-check-for-pthread_create.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From ef667b1ad89bb159b1991de0ec07d17e4320df23 Mon Sep 17 00:00:00 2001
|
||||
From: eaglegai <eaglegai@163.com>
|
||||
Date: Fri, 26 May 2023 16:44:34 +0800
|
||||
Subject: [PATCH] BUG/MINOR: thread: add a check for pthread_create
|
||||
|
||||
preload_libgcc_s() use pthread_create to create a thread and then call
|
||||
pthread_join to use it, but it doesn't check if the option is successful.
|
||||
So add a check to aviod potential crash.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/haproxy/haproxy/commit/ef667b1ad89bb159b1991de0ec07d17e4320df23
|
||||
|
||||
---
|
||||
src/thread.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/thread.c b/src/thread.c
|
||||
index d7128252ed0e..b41b6628a4cb 100644
|
||||
--- a/src/thread.c
|
||||
+++ b/src/thread.c
|
||||
@@ -1066,8 +1066,8 @@ static void *dummy_thread_function(void *data)
|
||||
static inline void preload_libgcc_s(void)
|
||||
{
|
||||
pthread_t dummy_thread;
|
||||
- pthread_create(&dummy_thread, NULL, dummy_thread_function, NULL);
|
||||
- pthread_join(dummy_thread, NULL);
|
||||
+ if (pthread_create(&dummy_thread, NULL, dummy_thread_function, NULL) == 0)
|
||||
+ pthread_join(dummy_thread, NULL);
|
||||
}
|
||||
|
||||
static void __thread_init(void)
|
||||
52
haproxy.spec
52
haproxy.spec
@ -5,7 +5,7 @@
|
||||
|
||||
Name: haproxy
|
||||
Version: 2.6.6
|
||||
Release: 5
|
||||
Release: 10
|
||||
Summary: The Reliable, High Performance TCP/HTTP Load Balancer
|
||||
|
||||
License: GPLv2+
|
||||
@ -20,6 +20,22 @@ Patch0: CVE-2023-25725.patch
|
||||
Patch1: CVE-2023-0056.patch
|
||||
Patch2: CVE-2023-25950.patch
|
||||
Patch3: CVE-2023-40225.patch
|
||||
Patch4: backport-BUG-MINOR-stream-Perform-errors-handling-in-right-or.patch
|
||||
Patch5: backport-BUG-MINOR-http_ana-txn-don-t-re-initialize-txn-and-r.patch
|
||||
Patch6: backport-BUG-MEDIUM-connection-Clear-flags-when-a-conn-is-rem.patch
|
||||
Patch7: backport-BUG-MINOR-mworker-prevent-incorrect-values-in-uptime.patch
|
||||
Patch8: backport-BUG-MEDIUM-connection-Preserve-flags-when-a-conn-is-.patch
|
||||
Patch9: backport-BUG-MINOR-protocol-fix-minor-memory-leak-in-protocol.patch
|
||||
Patch10: backport-BUG-MEDIUM-stream-do-not-try-to-free-a-failed-stream.patch
|
||||
Patch11: backport-BUG-MINOR-server-inherit-from-netns-in-srv_settings_.patch
|
||||
Patch12: CVE-2023-0836.patch
|
||||
# https://github.com/haproxy/haproxy/commit/2eab6d354322932cfec2ed54de261e4347eca9a6
|
||||
Patch13: CVE-2023-45539.patch
|
||||
Patch14: backport-errors-handle-malloc-failure-in-usermsgs_put.patch
|
||||
Patch15: backport-ssl_sock-add-check-for-ha_meth.patch
|
||||
Patch16: backport-thread-add-a-check-for-pthread_create.patch
|
||||
Patch17: backport-BUG-MINOR-server-add-missing-free-for-server-rdr_pfx.patch
|
||||
Patch18: backport-BUG-MINOR-server-do-not-leak-default-server-in-defau.patch
|
||||
|
||||
BuildRequires: gcc lua-devel pcre2-devel openssl-devel systemd-devel systemd libatomic
|
||||
%ifarch sw_64
|
||||
@ -124,6 +140,40 @@ exit 0
|
||||
%{_mandir}/man1/*
|
||||
|
||||
%changelog
|
||||
* Mon Mar 11 2024 xinghe <xinghe2@h-partners.com> - 2.6.6-10
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
- SUG:restart
|
||||
- DESC:server: add missing free for server->rdr_pfx
|
||||
server: do not leak default-server in defaults
|
||||
|
||||
* Fri Jan 19 2024 xinghe <xinghe2@h-partners.com> - 2.6.6-9
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
- SUG:restart
|
||||
- DESC:backport to fix potential coredump:
|
||||
errors: handle malloc failure in usermsgs_put
|
||||
ssl_sock: add check for ha_meth
|
||||
thread: add a check for pthread_creat
|
||||
|
||||
* Wed Dec 06 2023 yaoxin <yao_xin001@hoperun.com> - 2.6.6-8
|
||||
- Fix CVE-2023-45539
|
||||
|
||||
* Fri Dec 1 2023 liningjie <liningjie@xfusion.com> - 2.6.6-7
|
||||
- Fix CVE-2023-0836
|
||||
|
||||
* Wed Sep 27 2023 xinghe <xinghe2@h-partners.com> - 2.6.6-6
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
- SUG:restart
|
||||
- DESC:connection: Clear flags when a conn is removed
|
||||
connection: Preserve flags when a conn is removed
|
||||
stream: do not try to free a failed stream-conn
|
||||
http_ana/txn: don't re-initialize txn and req var
|
||||
mworker: prevent incorrect values in uptime
|
||||
protocol: fix minor memory leak in protocol_bind_all()
|
||||
stream: Perform errors handling in right order in stream_new()
|
||||
|
||||
* Fri Aug 25 2023 panchenbo <panchenbo@kylinsec.com.cn> - 2.6.6-5
|
||||
- fix sw_64 build error
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user