Control: tags -1 - moreinfo ❦ 5 décembre 2014 13:49 +0100, Ivo De Decker <iv...@debian.org> :
> You didn't include the diff for this, which would be relevant for the unblock. > However, if you upload this before Monday Dec 8th, I will review it and, if > appropriate, unblock it. I have just uploaded 1.5.8-2. No change in packaging, only patches BUG/MEDIUM and BUG/MAJOR from upstream. I am attaching the debdiff. Thanks!
diff -Nru haproxy-1.5.8/debian/changelog haproxy-1.5.8/debian/changelog --- haproxy-1.5.8/debian/changelog 2014-10-31 13:54:12.000000000 +0100 +++ haproxy-1.5.8/debian/changelog 2014-12-07 11:24:54.000000000 +0100 @@ -1,3 +1,25 @@ +haproxy (1.5.8-2) unstable; urgency=medium + + * Cherry-pick the following patches from 1.5.9 release: + - 8a0b93bde77e BUG/MAJOR: sessions: unlink session from list on out + of memory + - bae03eaad40a BUG/MEDIUM: pattern: don't load more than once a pattern + list. + - 93637b6e8503 BUG/MEDIUM: connection: sanitize PPv2 header length before + parsing address information + - 8ba50128832b BUG/MAJOR: frontend: initialize capture pointers earlier + - 1f96a87c4e14 BUG/MEDIUM: checks: fix conflicts between agent checks and + ssl healthchecks + - 9bcc01ae2598 BUG/MEDIUM: ssl: force a full GC in case of memory shortage + - 909514970089 BUG/MEDIUM: ssl: fix bad ssl context init can cause + segfault in case of OOM. + * Cherry-pick the following patches from future 1.5.10 release: + - 1e89acb6be9b BUG/MEDIUM: payload: ensure that a request channel is + available + - bad3c6f1b6d7 BUG/MEDIUM: patterns: previous fix was incomplete + + -- Vincent Bernat <ber...@debian.org> Sun, 07 Dec 2014 11:11:21 +0100 + haproxy (1.5.8-1) unstable; urgency=medium * New upstream stable release including the following fixes: diff -Nru haproxy-1.5.8/debian/patches/from-upstream/0001-BUG-MEDIUM-ssl-fix-bad-ssl-context-init-can-cause-se.patch haproxy-1.5.8/debian/patches/from-upstream/0001-BUG-MEDIUM-ssl-fix-bad-ssl-context-init-can-cause-se.patch --- haproxy-1.5.8/debian/patches/from-upstream/0001-BUG-MEDIUM-ssl-fix-bad-ssl-context-init-can-cause-se.patch 1970-01-01 01:00:00.000000000 +0100 +++ haproxy-1.5.8/debian/patches/from-upstream/0001-BUG-MEDIUM-ssl-fix-bad-ssl-context-init-can-cause-se.patch 2014-12-07 11:24:54.000000000 +0100 @@ -0,0 +1,87 @@ +From 8de4ecd5f55ee0d45b9cde587af13be980c7a891 Mon Sep 17 00:00:00 2001 +From: Emeric Brun <eb...@haproxy.comw> +Date: Wed, 12 Nov 2014 17:35:37 +0100 +Subject: [PATCH 1/9] BUG/MEDIUM: ssl: fix bad ssl context init can cause + segfault in case of OOM. + +Some SSL context's init functions errors were not handled and +can cause a segfault due to an incomplete SSL context +initialization. + +This fix must be backported to 1.5. +(cherry picked from commit 5547615cdac377797ae351a2e024376dbf6d6963) +--- + src/ssl_sock.c | 44 ++++++++++++++++++++++++++++++++++---------- + 1 file changed, 34 insertions(+), 10 deletions(-) + +diff --git a/src/ssl_sock.c b/src/ssl_sock.c +index f8bfbe758222..620609f2f445 100644 +--- a/src/ssl_sock.c ++++ b/src/ssl_sock.c +@@ -2040,15 +2040,29 @@ static int ssl_sock_init(struct connection *conn) + return -1; + } + +- SSL_set_connect_state(conn->xprt_ctx); +- if (objt_server(conn->target)->ssl_ctx.reused_sess) +- SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess); +- + /* set fd on SSL session context */ +- SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd); ++ if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) { ++ SSL_free(conn->xprt_ctx); ++ conn->xprt_ctx = NULL; ++ conn->err_code = CO_ER_SSL_NO_MEM; ++ return -1; ++ } + + /* set connection pointer */ +- SSL_set_app_data(conn->xprt_ctx, conn); ++ if (!SSL_set_app_data(conn->xprt_ctx, conn)) { ++ SSL_free(conn->xprt_ctx); ++ conn->xprt_ctx = NULL; ++ conn->err_code = CO_ER_SSL_NO_MEM; ++ return -1; ++ } ++ ++ SSL_set_connect_state(conn->xprt_ctx); ++ if (objt_server(conn->target)->ssl_ctx.reused_sess) { ++ if(!SSL_set_session(conn->xprt_ctx, objt_server(conn->target)->ssl_ctx.reused_sess)) { ++ SSL_SESSION_free(objt_server(conn->target)->ssl_ctx.reused_sess); ++ objt_server(conn->target)->ssl_ctx.reused_sess = NULL; ++ } ++ } + + /* leave init state and start handshake */ + conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN; +@@ -2065,13 +2079,23 @@ static int ssl_sock_init(struct connection *conn) + return -1; + } + +- SSL_set_accept_state(conn->xprt_ctx); +- + /* set fd on SSL session context */ +- SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd); ++ if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) { ++ SSL_free(conn->xprt_ctx); ++ conn->xprt_ctx = NULL; ++ conn->err_code = CO_ER_SSL_NO_MEM; ++ return -1; ++ } + + /* set connection pointer */ +- SSL_set_app_data(conn->xprt_ctx, conn); ++ if (!SSL_set_app_data(conn->xprt_ctx, conn)) { ++ SSL_free(conn->xprt_ctx); ++ conn->xprt_ctx = NULL; ++ conn->err_code = CO_ER_SSL_NO_MEM; ++ return -1; ++ } ++ ++ SSL_set_accept_state(conn->xprt_ctx); + + /* leave init state and start handshake */ + conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN; +-- +2.1.3 + diff -Nru haproxy-1.5.8/debian/patches/from-upstream/0002-BUG-MEDIUM-ssl-force-a-full-GC-in-case-of-memory-sho.patch haproxy-1.5.8/debian/patches/from-upstream/0002-BUG-MEDIUM-ssl-force-a-full-GC-in-case-of-memory-sho.patch --- haproxy-1.5.8/debian/patches/from-upstream/0002-BUG-MEDIUM-ssl-force-a-full-GC-in-case-of-memory-sho.patch 1970-01-01 01:00:00.000000000 +0100 +++ haproxy-1.5.8/debian/patches/from-upstream/0002-BUG-MEDIUM-ssl-force-a-full-GC-in-case-of-memory-sho.patch 2014-12-07 11:24:54.000000000 +0100 @@ -0,0 +1,104 @@ +From 1d4f49cb26cf2e7a1ce153d961262c9df58e2bd8 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau <w...@1wt.eu> +Date: Thu, 13 Nov 2014 13:48:58 +0100 +Subject: [PATCH 2/9] BUG/MEDIUM: ssl: force a full GC in case of memory + shortage + +When memory becomes scarce and openssl refuses to allocate a new SSL +session, it is worth freeing the pools and trying again instead of +rejecting all incoming SSL connection. This can happen when some +memory usage limits have been assigned to the haproxy process using +-m or with ulimit -m/-v. + +This is mostly an enhancement of previous fix and is worth backporting +to 1.5. +(cherry picked from commit fba03cdc5ac6e3ca318b34915596cbc0a0dacc55) +--- + src/ssl_sock.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/src/ssl_sock.c b/src/ssl_sock.c +index 620609f2f445..f50efe504a8e 100644 +--- a/src/ssl_sock.c ++++ b/src/ssl_sock.c +@@ -2033,9 +2033,16 @@ static int ssl_sock_init(struct connection *conn) + /* If it is in client mode initiate SSL session + in connect state otherwise accept state */ + if (objt_server(conn->target)) { ++ int may_retry = 1; ++ ++ retry_connect: + /* Alloc a new SSL session ctx */ + conn->xprt_ctx = SSL_new(objt_server(conn->target)->ssl_ctx.ctx); + if (!conn->xprt_ctx) { ++ if (may_retry--) { ++ pool_gc2(); ++ goto retry_connect; ++ } + conn->err_code = CO_ER_SSL_NO_MEM; + return -1; + } +@@ -2044,6 +2051,10 @@ static int ssl_sock_init(struct connection *conn) + if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) { + SSL_free(conn->xprt_ctx); + conn->xprt_ctx = NULL; ++ if (may_retry--) { ++ pool_gc2(); ++ goto retry_connect; ++ } + conn->err_code = CO_ER_SSL_NO_MEM; + return -1; + } +@@ -2052,6 +2063,10 @@ static int ssl_sock_init(struct connection *conn) + if (!SSL_set_app_data(conn->xprt_ctx, conn)) { + SSL_free(conn->xprt_ctx); + conn->xprt_ctx = NULL; ++ if (may_retry--) { ++ pool_gc2(); ++ goto retry_connect; ++ } + conn->err_code = CO_ER_SSL_NO_MEM; + return -1; + } +@@ -2072,9 +2087,16 @@ static int ssl_sock_init(struct connection *conn) + return 0; + } + else if (objt_listener(conn->target)) { ++ int may_retry = 1; ++ ++ retry_accept: + /* Alloc a new SSL session ctx */ + conn->xprt_ctx = SSL_new(objt_listener(conn->target)->bind_conf->default_ctx); + if (!conn->xprt_ctx) { ++ if (may_retry--) { ++ pool_gc2(); ++ goto retry_accept; ++ } + conn->err_code = CO_ER_SSL_NO_MEM; + return -1; + } +@@ -2083,6 +2105,10 @@ static int ssl_sock_init(struct connection *conn) + if (!SSL_set_fd(conn->xprt_ctx, conn->t.sock.fd)) { + SSL_free(conn->xprt_ctx); + conn->xprt_ctx = NULL; ++ if (may_retry--) { ++ pool_gc2(); ++ goto retry_accept; ++ } + conn->err_code = CO_ER_SSL_NO_MEM; + return -1; + } +@@ -2091,6 +2117,10 @@ static int ssl_sock_init(struct connection *conn) + if (!SSL_set_app_data(conn->xprt_ctx, conn)) { + SSL_free(conn->xprt_ctx); + conn->xprt_ctx = NULL; ++ if (may_retry--) { ++ pool_gc2(); ++ goto retry_accept; ++ } + conn->err_code = CO_ER_SSL_NO_MEM; + return -1; + } +-- +2.1.3 + diff -Nru haproxy-1.5.8/debian/patches/from-upstream/0003-BUG-MEDIUM-checks-fix-conflicts-between-agent-checks.patch haproxy-1.5.8/debian/patches/from-upstream/0003-BUG-MEDIUM-checks-fix-conflicts-between-agent-checks.patch --- haproxy-1.5.8/debian/patches/from-upstream/0003-BUG-MEDIUM-checks-fix-conflicts-between-agent-checks.patch 1970-01-01 01:00:00.000000000 +0100 +++ haproxy-1.5.8/debian/patches/from-upstream/0003-BUG-MEDIUM-checks-fix-conflicts-between-agent-checks.patch 2014-12-07 11:24:54.000000000 +0100 @@ -0,0 +1,102 @@ +From 4aa82d2300e4739eeaeb079fc51f1929508f19c4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cyril=20Bont=C3=A9?= <cyril.bo...@free.fr> +Date: Sat, 15 Nov 2014 22:41:27 +0100 +Subject: [PATCH 3/9] BUG/MEDIUM: checks: fix conflicts between agent checks + and ssl healthchecks + +Lasse Birnbaum Jensen reported an issue when agent checks are used at the same +time as standard healthchecks when SSL is enabled on the server side. + +The symptom is that agent checks try to communicate in SSL while it should +manage raw data. This happens because the transport layer is shared between all +kind of checks. + +To fix the issue, the transport layer is now stored in each check type, +allowing to use SSL healthchecks when required, while an agent check should +always use the raw_sock implementation. + +The fix must be backported to 1.5. +(cherry picked from commit 9ce1311ebc834e20addc7a8392c0fc4e4ad687b7) +--- + include/types/checks.h | 3 ++- + include/types/server.h | 1 - + src/checks.c | 2 +- + src/server.c | 2 +- + src/ssl_sock.c | 2 +- + 5 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/include/types/checks.h b/include/types/checks.h +index a50043bb68f3..42b7b07c17c2 100644 +--- a/include/types/checks.h ++++ b/include/types/checks.h +@@ -125,6 +125,7 @@ enum { + }; + + struct check { ++ struct xprt_ops *xprt; /* transport layer operations for health checks */ + struct connection *conn; /* connection state for health checks */ + unsigned short port; /* the port to use for the health checks */ + struct buffer *bi, *bo; /* input and output buffers to send/recv check */ +@@ -132,7 +133,7 @@ struct check { + struct timeval start; /* last health check start time */ + long duration; /* time in ms took to finish last health check */ + short status, code; /* check result, check code */ +- char desc[HCHK_DESC_LEN]; /* health check descritpion */ ++ char desc[HCHK_DESC_LEN]; /* health check description */ + int use_ssl; /* use SSL for health checks */ + int send_proxy; /* send a PROXY protocol header with checks */ + struct tcpcheck_rule *current_step; /* current step when using tcpcheck */ +diff --git a/include/types/server.h b/include/types/server.h +index 313f58d71dd4..c419b40f9f4a 100644 +--- a/include/types/server.h ++++ b/include/types/server.h +@@ -194,7 +194,6 @@ struct server { + + struct { /* configuration used by health-check and agent-check */ + struct protocol *proto; /* server address protocol for health checks */ +- struct xprt_ops *xprt; /* transport layer operations for health checks */ + struct sockaddr_storage addr; /* the address to check, if different from <addr> */ + } check_common; + +diff --git a/src/checks.c b/src/checks.c +index 5318f35943c8..84bf0e5d0297 100644 +--- a/src/checks.c ++++ b/src/checks.c +@@ -1413,7 +1413,7 @@ static int connect_chk(struct task *t) + + /* prepare a new connection */ + conn_init(conn); +- conn_prepare(conn, s->check_common.proto, s->check_common.xprt); ++ conn_prepare(conn, s->check_common.proto, check->xprt); + conn_attach(conn, check, &check_conn_cb); + conn->target = &s->obj_type; + +diff --git a/src/server.c b/src/server.c +index fdb63cc33a2d..94a31b6659be 100644 +--- a/src/server.c ++++ b/src/server.c +@@ -929,7 +929,7 @@ int parse_server(const char *file, int linenum, char **args, struct proxy *curpr + + newsrv->addr = *sk; + newsrv->proto = newsrv->check_common.proto = protocol_by_family(newsrv->addr.ss_family); +- newsrv->xprt = newsrv->check_common.xprt = &raw_sock; ++ newsrv->xprt = newsrv->check.xprt = newsrv->agent.xprt = &raw_sock; + + if (!newsrv->proto) { + Alert("parsing [%s:%d] : Unknown protocol family %d '%s'\n", +diff --git a/src/ssl_sock.c b/src/ssl_sock.c +index f50efe504a8e..b73d6f9a9d47 100644 +--- a/src/ssl_sock.c ++++ b/src/ssl_sock.c +@@ -1812,7 +1812,7 @@ int ssl_sock_prepare_srv_ctx(struct server *srv, struct proxy *curproxy) + if (srv->use_ssl) + srv->xprt = &ssl_sock; + if (srv->check.use_ssl) +- srv->check_common.xprt = &ssl_sock; ++ srv->check.xprt = &ssl_sock; + + srv->ssl_ctx.ctx = SSL_CTX_new(SSLv23_client_method()); + if (!srv->ssl_ctx.ctx) { +-- +2.1.3 + diff -Nru haproxy-1.5.8/debian/patches/from-upstream/0004-BUG-MAJOR-frontend-initialize-capture-pointers-earli.patch haproxy-1.5.8/debian/patches/from-upstream/0004-BUG-MAJOR-frontend-initialize-capture-pointers-earli.patch --- haproxy-1.5.8/debian/patches/from-upstream/0004-BUG-MAJOR-frontend-initialize-capture-pointers-earli.patch 1970-01-01 01:00:00.000000000 +0100 +++ haproxy-1.5.8/debian/patches/from-upstream/0004-BUG-MAJOR-frontend-initialize-capture-pointers-earli.patch 2014-12-07 11:24:54.000000000 +0100 @@ -0,0 +1,59 @@ +From e7623987fda044a3c99cf061e45e51a1457edd69 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau <w...@1wt.eu> +Date: Tue, 18 Nov 2014 18:49:19 +0100 +Subject: [PATCH 4/9] BUG/MAJOR: frontend: initialize capture pointers earlier + +Denys Fedoryshchenko reported and diagnosed a nasty bug caused by TCP +captures, introduced in late 1.5-dev by commit 18bf01e ("MEDIUM: tcp: +add a new tcp-request capture directive"). The problem is that we're +using the array of capture pointers initially designed for HTTP usage +only, and that this array was only reset when starting to process an +HTTP request. In a tcp-only frontend, the pointers are not reset, and +if the capture pool is shared, we can very well point to whatever other +memory location, resulting in random crashes when tcp-request content +captures are processed. + +The fix simply consists in initializing these pointers when the pools +are prepared. + +A workaround for existing versions consists in either disabling TCP +captures in tcp-only frontends, or in forcing the frontends to work in +HTTP mode. + +Thanks to Denys for the amount of testing and detailed reports. + +This fix must be backported to 1.5. +(cherry picked from commit 9654e57fac86c773091b892f42015ba2ba56be5a) +--- + src/frontend.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/src/frontend.c b/src/frontend.c +index 3f80774ded29..29280477b0c3 100644 +--- a/src/frontend.c ++++ b/src/frontend.c +@@ -106,11 +106,17 @@ int frontend_accept(struct session *s) + if (global.tune.client_rcvbuf) + setsockopt(cfd, SOL_SOCKET, SO_RCVBUF, &global.tune.client_rcvbuf, sizeof(global.tune.client_rcvbuf)); + +- if (unlikely(s->fe->nb_req_cap > 0 && (s->txn.req.cap = pool_alloc2(s->fe->req_cap_pool)) == NULL)) +- goto out_return; /* no memory */ ++ if (unlikely(s->fe->nb_req_cap > 0)) { ++ if ((s->txn.req.cap = pool_alloc2(s->fe->req_cap_pool)) == NULL) ++ goto out_return; /* no memory */ ++ memset(s->txn.req.cap, 0, s->fe->nb_req_cap * sizeof(void *)); ++ } + +- if (unlikely(s->fe->nb_rsp_cap > 0 && (s->txn.rsp.cap = pool_alloc2(s->fe->rsp_cap_pool)) == NULL)) +- goto out_free_reqcap; /* no memory */ ++ if (unlikely(s->fe->nb_rsp_cap > 0)) { ++ if ((s->txn.rsp.cap = pool_alloc2(s->fe->rsp_cap_pool)) == NULL) ++ goto out_free_reqcap; /* no memory */ ++ memset(s->txn.rsp.cap, 0, s->fe->nb_rsp_cap * sizeof(void *)); ++ } + + if (s->fe->http_needed) { + /* we have to allocate header indexes only if we know +-- +2.1.3 + diff -Nru haproxy-1.5.8/debian/patches/from-upstream/0005-BUG-MEDIUM-connection-sanitize-PPv2-header-length-be.patch haproxy-1.5.8/debian/patches/from-upstream/0005-BUG-MEDIUM-connection-sanitize-PPv2-header-length-be.patch --- haproxy-1.5.8/debian/patches/from-upstream/0005-BUG-MEDIUM-connection-sanitize-PPv2-header-length-be.patch 1970-01-01 01:00:00.000000000 +0100 +++ haproxy-1.5.8/debian/patches/from-upstream/0005-BUG-MEDIUM-connection-sanitize-PPv2-header-length-be.patch 2014-12-07 11:24:54.000000000 +0100 @@ -0,0 +1,48 @@ +From 86664f6de45d2c1c48bd4b9db7aa5c0de4354325 Mon Sep 17 00:00:00 2001 +From: KOVACS Krisztian <hid...@balabit.com> +Date: Wed, 19 Nov 2014 10:53:20 +0100 +Subject: [PATCH 5/9] BUG/MEDIUM: connection: sanitize PPv2 header length + before parsing address information + +Previously, if hdr_v2->len was less than the length of the protocol +specific address information we could have read after the end of the +buffer and initialize the sockaddr structure with junk. + +Signed-off-by: KOVACS Krisztian <hid...@balabit.com> + +[WT: this is only tagged medium since proxy protocol is only used from + trusted sources] + +This must be backported to 1.5. +(cherry picked from commit efd3aa93412648cf923bf3d2e171c0b84e9d7a69) +--- + src/connection.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/connection.c b/src/connection.c +index 3af6d9afd7e9..b9f5c42b44e6 100644 +--- a/src/connection.c ++++ b/src/connection.c +@@ -424,6 +424,9 @@ int conn_recv_proxy(struct connection *conn, int flag) + case 0x01: /* PROXY command */ + switch (hdr_v2->fam) { + case 0x11: /* TCPv4 */ ++ if (ntohs(hdr_v2->len) < PP2_ADDR_LEN_INET) ++ goto bad_header; ++ + ((struct sockaddr_in *)&conn->addr.from)->sin_family = AF_INET; + ((struct sockaddr_in *)&conn->addr.from)->sin_addr.s_addr = hdr_v2->addr.ip4.src_addr; + ((struct sockaddr_in *)&conn->addr.from)->sin_port = hdr_v2->addr.ip4.src_port; +@@ -433,6 +436,9 @@ int conn_recv_proxy(struct connection *conn, int flag) + conn->flags |= CO_FL_ADDR_FROM_SET | CO_FL_ADDR_TO_SET; + break; + case 0x21: /* TCPv6 */ ++ if (ntohs(hdr_v2->len) < PP2_ADDR_LEN_INET6) ++ goto bad_header; ++ + ((struct sockaddr_in6 *)&conn->addr.from)->sin6_family = AF_INET6; + memcpy(&((struct sockaddr_in6 *)&conn->addr.from)->sin6_addr, hdr_v2->addr.ip6.src_addr, 16); + ((struct sockaddr_in6 *)&conn->addr.from)->sin6_port = hdr_v2->addr.ip6.src_port; +-- +2.1.3 + diff -Nru haproxy-1.5.8/debian/patches/from-upstream/0006-BUG-MEDIUM-pattern-don-t-load-more-than-once-a-patte.patch haproxy-1.5.8/debian/patches/from-upstream/0006-BUG-MEDIUM-pattern-don-t-load-more-than-once-a-patte.patch --- haproxy-1.5.8/debian/patches/from-upstream/0006-BUG-MEDIUM-pattern-don-t-load-more-than-once-a-patte.patch 1970-01-01 01:00:00.000000000 +0100 +++ haproxy-1.5.8/debian/patches/from-upstream/0006-BUG-MEDIUM-pattern-don-t-load-more-than-once-a-patte.patch 2014-12-07 11:24:54.000000000 +0100 @@ -0,0 +1,122 @@ +From a0e753b688853c7ac751bcb183978eba063e68f1 Mon Sep 17 00:00:00 2001 +From: Thierry FOURNIER <tfourn...@exceliance.fr> +Date: Mon, 24 Nov 2014 11:14:42 +0100 +Subject: [PATCH 6/9] BUG/MEDIUM: pattern: don't load more than once a pattern + list. + +A memory optimization can use the same pattern expression for many +equal pattern list (same parse method, index method and index_smp +method). + +The pattern expression is returned by "pattern_new_expr", but this +function dont indicate if the returned pattern is already in use. + +So, the caller function reload the list of patterns in addition with +the existing patterns. This behavior is not a problem with tree indexed +pattern, but it grows the lists indexed patterns. + +This fix add a "reuse" flag in return of the function "pattern_new_expr". +If the flag is set, I suppose that the patterns are already loaded. + +This fix must be backported into 1.5. +(cherry picked from commit 315ec4217f912f6cc8fcf98624d852f9cd8399f9) +--- + include/proto/pattern.h | 3 ++- + src/acl.c | 2 +- + src/pattern.c | 22 ++++++++++++++++++++-- + 3 files changed, 23 insertions(+), 4 deletions(-) + +diff --git a/include/proto/pattern.h b/include/proto/pattern.h +index 4a969ac199e4..7855474e5b44 100644 +--- a/include/proto/pattern.h ++++ b/include/proto/pattern.h +@@ -206,7 +206,8 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags, con + */ + void pattern_init_expr(struct pattern_expr *expr); + struct pattern_expr *pattern_lookup_expr(struct pattern_head *head, struct pat_ref *ref); +-struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref, char **err); ++struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref, ++ char **err, int *reuse); + struct sample_storage **pattern_find_smp(struct pattern_expr *expr, struct pat_ref_elt *elt); + int pattern_delete(struct pattern_expr *expr, struct pat_ref_elt *ref); + +diff --git a/src/acl.c b/src/acl.c +index 8f3fd9eaa746..d8b3000c0c36 100644 +--- a/src/acl.c ++++ b/src/acl.c +@@ -532,7 +532,7 @@ struct acl_expr *parse_acl_expr(const char **args, char **err, struct arg_list * + } + + /* Create new pattern expression associated to this reference. */ +- pattern_expr = pattern_new_expr(&expr->pat, ref, err); ++ pattern_expr = pattern_new_expr(&expr->pat, ref, err, NULL); + if (!pattern_expr) + goto out_free_expr; + +diff --git a/src/pattern.c b/src/pattern.c +index c63365d74bf7..20547f9607be 100644 +--- a/src/pattern.c ++++ b/src/pattern.c +@@ -1855,12 +1855,19 @@ struct pattern_expr *pattern_lookup_expr(struct pattern_head *head, struct pat_r + * <ref> can be NULL. If an error is occured, the function returns NULL and + * <err> is filled. Otherwise, the function returns new pattern_expr linked + * with <head> and <ref>. ++ * ++ * The returned value can be a alredy filled pattern list, in this case the ++ * flag <reuse> is set. + */ +-struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref, char **err) ++struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref *ref, ++ char **err, int *reuse) + { + struct pattern_expr *expr; + struct pattern_expr_list *list; + ++ if (reuse) ++ *reuse = 0; ++ + /* Memory and initialization of the chain element. */ + list = malloc(sizeof(*list)); + if (!list) { +@@ -1915,6 +1922,8 @@ struct pattern_expr *pattern_new_expr(struct pattern_head *head, struct pat_ref + * with ref and we must not free it. + */ + list->do_free = 0; ++ if (reuse) ++ *reuse = 1; + } + + /* The new list element reference the pattern_expr. */ +@@ -2087,6 +2096,7 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags, + struct pat_ref *ref; + struct pattern_expr *expr; + struct pat_ref_elt *elt; ++ int reuse; + + /* Lookup for the existing reference. */ + ref = pat_ref_lookup(filename); +@@ -2161,12 +2171,20 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags, + */ + expr = pattern_lookup_expr(head, ref); + if (!expr || (expr->mflags != patflags)) { +- expr = pattern_new_expr(head, ref, err); ++ expr = pattern_new_expr(head, ref, err, &reuse); + if (!expr) + return 0; + expr->mflags = patflags; + } + ++ /* The returned expression may be not empty, because the function ++ * "pattern_new_expr" lookup for similar pattern list and can ++ * reuse a already filled pattern list. In this case, we can not ++ * reload the patterns. ++ */ ++ if (reuse) ++ return 1; ++ + /* Load reference content in the pattern expression. */ + list_for_each_entry(elt, &ref->head, list) { + if (!pat_ref_push(elt, expr, patflags, err)) { +-- +2.1.3 + diff -Nru haproxy-1.5.8/debian/patches/from-upstream/0007-BUG-MAJOR-sessions-unlink-session-from-list-on-out-o.patch haproxy-1.5.8/debian/patches/from-upstream/0007-BUG-MAJOR-sessions-unlink-session-from-list-on-out-o.patch --- haproxy-1.5.8/debian/patches/from-upstream/0007-BUG-MAJOR-sessions-unlink-session-from-list-on-out-o.patch 1970-01-01 01:00:00.000000000 +0100 +++ haproxy-1.5.8/debian/patches/from-upstream/0007-BUG-MAJOR-sessions-unlink-session-from-list-on-out-o.patch 2014-12-07 11:24:54.000000000 +0100 @@ -0,0 +1,36 @@ +From 7f399f63f2d8414c6ef7ebde45db3689ad6453b9 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau <w...@1wt.eu> +Date: Tue, 25 Nov 2014 17:10:33 +0100 +Subject: [PATCH 7/9] BUG/MAJOR: sessions: unlink session from list on out of + memory + +Since embryonic sessions were introduced in 1.5-dev12 with commit +2542b53 ("MAJOR: session: introduce embryonic sessions"), a major +bug remained present. If haproxy cannot allocate memory during +session_complete() (for example, no more buffers), it will not +unlink the new session from the sessions list. This will cause +memory corruptions if the memory area from the session is reused +for anything else, and may also cause bogus output on "show sess" +on the CLI. + +This fix must be backported to 1.5. +(cherry picked from commit 3b24641745b32289235d765f441ec60fa7381f99) +--- + src/session.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/session.c b/src/session.c +index df85170cd13a..5b9e407118a3 100644 +--- a/src/session.c ++++ b/src/session.c +@@ -579,6 +579,7 @@ int session_complete(struct session *s) + /* and restore the connection pointer in case we destroyed it, + * because kill_mini_session() will need it. + */ ++ LIST_DEL(&s->list); + s->target = &conn->obj_type; + return ret; + } +-- +2.1.3 + diff -Nru haproxy-1.5.8/debian/patches/from-upstream/0008-BUG-MEDIUM-patterns-previous-fix-was-incomplete.patch haproxy-1.5.8/debian/patches/from-upstream/0008-BUG-MEDIUM-patterns-previous-fix-was-incomplete.patch --- haproxy-1.5.8/debian/patches/from-upstream/0008-BUG-MEDIUM-patterns-previous-fix-was-incomplete.patch 1970-01-01 01:00:00.000000000 +0100 +++ haproxy-1.5.8/debian/patches/from-upstream/0008-BUG-MEDIUM-patterns-previous-fix-was-incomplete.patch 2014-12-07 11:24:54.000000000 +0100 @@ -0,0 +1,34 @@ +From c14cbb9b8c360b63db24ec50a96625300186fca2 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau <w...@1wt.eu> +Date: Wed, 26 Nov 2014 13:17:03 +0100 +Subject: [PATCH 8/9] BUG/MEDIUM: patterns: previous fix was incomplete + +Dmitry Sivachenko <trtrmi...@gmail.com> reported that commit 315ec42 +("BUG/MEDIUM: pattern: don't load more than once a pattern list.") +relies on an uninitialised variable in the stack. While it used to +work fine during the tests, if the uninitialized variable is non-null, +some patterns may be aggregated if loaded multiple times, resulting in +slower processing, which was the original issue it tried to address. + +The fix needs to be backported to 1.5. +(cherry picked from commit 4deaf39243c4d941998b1b0175bad05b8a287c0b) +--- + src/pattern.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/pattern.c b/src/pattern.c +index 20547f9607be..208e33a448bd 100644 +--- a/src/pattern.c ++++ b/src/pattern.c +@@ -2096,7 +2096,7 @@ int pattern_read_from_file(struct pattern_head *head, unsigned int refflags, + struct pat_ref *ref; + struct pattern_expr *expr; + struct pat_ref_elt *elt; +- int reuse; ++ int reuse = 0; + + /* Lookup for the existing reference. */ + ref = pat_ref_lookup(filename); +-- +2.1.3 + diff -Nru haproxy-1.5.8/debian/patches/from-upstream/0009-BUG-MEDIUM-payload-ensure-that-a-request-channel-is-.patch haproxy-1.5.8/debian/patches/from-upstream/0009-BUG-MEDIUM-payload-ensure-that-a-request-channel-is-.patch --- haproxy-1.5.8/debian/patches/from-upstream/0009-BUG-MEDIUM-payload-ensure-that-a-request-channel-is-.patch 1970-01-01 01:00:00.000000000 +0100 +++ haproxy-1.5.8/debian/patches/from-upstream/0009-BUG-MEDIUM-payload-ensure-that-a-request-channel-is-.patch 2014-12-07 11:24:54.000000000 +0100 @@ -0,0 +1,49 @@ +From 92a009fca26ed45bb8ad64666a993dcfb86617de Mon Sep 17 00:00:00 2001 +From: Willy Tarreau <w...@1wt.eu> +Date: Wed, 26 Nov 2014 13:24:24 +0100 +Subject: [PATCH 9/9] BUG/MEDIUM: payload: ensure that a request channel is + available + +Denys Fedoryshchenko reported a segfault when using certain +sample fetch functions in the "tcp-request connection" rulesets +despite the warnings. This is because some tests for the existence +of the channel were missing. + +The fetches which were fixed are : + - req.ssl_hello_type + - rep.ssl_hello_type + - req.ssl_sni + +This fix must be backported to 1.5. +(cherry picked from commit 83f2592bcd2e186beeabcba16be16faaab82bd39) +--- + src/payload.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/payload.c b/src/payload.c +index 4057f6f85601..f62163c4143c 100644 +--- a/src/payload.c ++++ b/src/payload.c +@@ -72,6 +72,9 @@ smp_fetch_ssl_hello_type(struct proxy *px, struct session *s, void *l7, unsigned + + chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? s->rep : s->req; + ++ if (!chn) ++ goto not_ssl_hello; ++ + bleft = chn->buf->i; + data = (const unsigned char *)chn->buf->p; + +@@ -276,6 +279,9 @@ smp_fetch_ssl_hello_sni(struct proxy *px, struct session *s, void *l7, unsigned + + chn = ((opt & SMP_OPT_DIR) == SMP_OPT_DIR_RES) ? s->rep : s->req; + ++ if (!chn) ++ goto not_ssl_hello; ++ + bleft = chn->buf->i; + data = (unsigned char *)chn->buf->p; + +-- +2.1.3 + diff -Nru haproxy-1.5.8/debian/patches/series haproxy-1.5.8/debian/patches/series --- haproxy-1.5.8/debian/patches/series 2014-10-31 13:54:12.000000000 +0100 +++ haproxy-1.5.8/debian/patches/series 2014-12-07 11:24:54.000000000 +0100 @@ -3,3 +3,12 @@ haproxy.service-add-documentation.patch haproxy.service-check-config-before-reload.patch haproxy.service-use-environment-variables.patch +from-upstream/0001-BUG-MEDIUM-ssl-fix-bad-ssl-context-init-can-cause-se.patch +from-upstream/0002-BUG-MEDIUM-ssl-force-a-full-GC-in-case-of-memory-sho.patch +from-upstream/0003-BUG-MEDIUM-checks-fix-conflicts-between-agent-checks.patch +from-upstream/0004-BUG-MAJOR-frontend-initialize-capture-pointers-earli.patch +from-upstream/0005-BUG-MEDIUM-connection-sanitize-PPv2-header-length-be.patch +from-upstream/0006-BUG-MEDIUM-pattern-don-t-load-more-than-once-a-patte.patch +from-upstream/0007-BUG-MAJOR-sessions-unlink-session-from-list-on-out-o.patch +from-upstream/0008-BUG-MEDIUM-patterns-previous-fix-was-incomplete.patch +from-upstream/0009-BUG-MEDIUM-payload-ensure-that-a-request-channel-is-.patch
-- Write and test a big program in small pieces. - The Elements of Programming Style (Kernighan & Plauger)
signature.asc
Description: PGP signature