backport update stream

This commit is contained in:
leeffo 2023-09-22 11:17:59 +08:00
parent 4938bcdf0d
commit b2a4c0153d
9 changed files with 689 additions and 3 deletions

View File

@ -0,0 +1,111 @@
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>
---
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 31bc3ad..4981f6b 100644
--- a/src/mux_fcgi.c
+++ b/src/mux_fcgi.c
@@ -3227,8 +3227,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 754b572..56b08a7 100644
--- a/src/mux_h1.c
+++ b/src/mux_h1.c
@@ -3282,8 +3282,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 94017e9..f4cb5b1 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -4163,6 +4163,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);
}
}
@@ -4305,6 +4309,7 @@ do_leave:
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 cccf2f5..8a282bc 100644
--- a/src/server.c
+++ b/src/server.c
@@ -5717,6 +5717,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++;
@@ -5774,6 +5775,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);
}
--
1.7.10.4

View File

@ -0,0 +1,189 @@
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>
---
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 4d289e7..8cf22ef 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 4a73dbc..5a459fd 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 4981f6b..2c417dd 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 56b08a7..6f59b31 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 f4cb5b1..b62a8f6 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);
}
}
@@ -4309,7 +4304,6 @@ do_leave:
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 8a282bc..d701eae 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 919a08a..b2f9374 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);
--
1.7.10.4

View File

@ -0,0 +1,37 @@
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>
---
src/stream.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/stream.c b/src/stream.c
index 7eaf039..224b9b8 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:
--
1.7.10.4

View File

@ -0,0 +1,85 @@
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>
---
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 2b2cfdc..379b480 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 c04dd56..7eaf039 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);
--
1.7.10.4

View File

@ -0,0 +1,108 @@
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>
---
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 5a3f6c7..0cb0662 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 686fc75..26b16cc 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;
--
1.7.10.4

View File

@ -0,0 +1,62 @@
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>
---
src/protocol.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/protocol.c b/src/protocol.c
index 03f7085..146733a 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;
--
1.7.10.4

View File

@ -0,0 +1,45 @@
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>
---
src/server.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/server.c b/src/server.c
index e9e09dd..7935668 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;
}
--
1.7.10.4

View File

@ -0,0 +1,36 @@
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>
---
src/stream.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/stream.c b/src/stream.c
index 0cbbb70..fc8b82a 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);
--
1.7.10.4

View File

@ -5,7 +5,7 @@
Name: haproxy
Version: 2.6.6
Release: 4
Release: 5
Summary: The Reliable, High Performance TCP/HTTP Load Balancer
License: GPLv2+
@ -21,6 +21,16 @@ Patch1: CVE-2023-0056.patch
Patch2: CVE-2023-25950.patch
Patch3: CVE-2023-40225.patch
Patch1001: backport-BUG-MINOR-stream-Perform-errors-handling-in-right-order-in-stream_new.patch
Patch1002: backport-BUG-MINOR-http_ana-txn-don-t-re-initialize-txn-and-req-var-lists.patch
Patch1003: backport-BUG-MEDIUM-connection-Clear-flags-when-a-conn-is-removed-from-an-idle-list.patch
Patch1004: backport-BUG-MINOR-mworker-prevent-incorrect-values-in-uptime.patch
Patch1005: backport-BUG-MEDIUM-connection-Preserve-flags-when-a-conn-is-removed-from-an-idle-list.patch
Patch1006: backport-BUG-MINOR-protocol-fix-minor-memory-leak-in-protocol_bind_all.patch
Patch1007: backport-BUG-MEDIUM-stream-do-not-try-to-free-a-failed-stream-conn.patch
Patch1008: backport-BUG-MINOR-server-inherit-from-netns-in-srv_settings_cpy.patch
BuildRequires: gcc lua-devel pcre2-devel openssl-devel systemd-devel systemd libatomic
Requires(pre): shadow-utils
%{?systemd_requires}
@ -121,6 +131,9 @@ exit 0
%{_mandir}/man1/*
%changelog
* Fri Sep 22 2023 leeffo <liweiganga@uniontech.com> - 2.6.6-5
- backport update stream
* Mon Aug 21 2023 wangkai <wang_kai001@hoperun.com> - 2.6.6-4
- Fix CVE-2023-40225
@ -148,10 +161,10 @@ exit 0
* Mon Aug 30 2021 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 2021 liwu <liwu13@huawei.com> - 2.2.1-2
- fix CVE-2021-39241,CVE-2021-39242
* Thu July 1 huanghaitao <huanghaitao8@huawei.com> - 2.2.1-1
* Thu Jul 1 2021 huanghaitao <huanghaitao8@huawei.com> - 2.2.1-1
- update to 2.2.1
* Tue Sep 15 2020 Ge Wang <wangge20@huawei.com> - 2.0.17-1