haproxy: Update HAProxy to v1.8.23

- Update haproxy download URL and hash
- This fixes CVE-2019-19330 (See: https://nvd.nist.gov/vuln/detail/CVE-2019-19330)

Signed-off-by: Christian Lachner <gladiac@gmail.com>
This commit is contained in:
Christian Lachner 2019-11-29 14:01:50 +01:00
parent fff2e26a9b
commit bc37a31b16
15 changed files with 9 additions and 600 deletions

View File

@ -10,12 +10,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy
PKG_VERSION:=1.8.21
PKG_VERSION:=1.8.23
PKG_RELEASE:=1
PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.haproxy.org/download/1.8/src/
PKG_HASH:=34bc80bbaab6edae80add1e8b321636e50ccc56cb583040d98d5d245570680e1
PKG_HASH:=de919164876ee0501e1ef01ca5ccc0d3bda2b96003f9d240f7b856010ccbf7eb
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_LICENSE:=GPL-2.0

View File

@ -1,7 +1,7 @@
#!/bin/bash
CLONEURL=http://git.haproxy.org/git/haproxy-1.8.git
BASE_TAG=v1.8.21
BASE_TAG=v1.8.23
TMP_REPODIR=tmprepo
PATCHESDIR=patches

View File

@ -1,33 +0,0 @@
commit db95dd53f88bb15e288b553de5c6687260756f03
Author: Willy Tarreau <w@1wt.eu>
Date: Tue Feb 12 10:59:32 2019 +0100
BUILD/MINOR: stream: avoid a build warning with threads disabled
gcc 6+ complains about a possible null-deref here due to the test in
objt_server() :
if (objt_server(s->target))
HA_ATOMIC_ADD(&objt_server(s->target)->counters.retries, 1);
Let's simply change it to __objt_server(). This can be backported to
1.9 and 1.8.
(cherry picked from commit 1ef724e2169eaff7f0272278c3fba9b34d5c7f78)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 3d3b67f1877718abbbc8cc500aae373640e454e9)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/stream.c b/src/stream.c
index f443cc74..99a133a9 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -746,7 +746,7 @@ static int sess_update_st_cer(struct stream *s)
si->state = SI_ST_REQ;
} else {
if (objt_server(s->target))
- HA_ATOMIC_ADD(&objt_server(s->target)->counters.retries, 1);
+ HA_ATOMIC_ADD(&__objt_server(s->target)->counters.retries, 1);
HA_ATOMIC_ADD(&s->be->be_counters.retries, 1);
si->state = SI_ST_ASS;
}

View File

@ -46,7 +46,7 @@
goto mkcert_error;
/* set public key in the certificate */
@@ -6299,7 +6311,7 @@ smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char
@@ -6399,7 +6411,7 @@ smp_fetch_ssl_x_notafter(const struct arg *args, struct sample *smp, const char
goto out;
smp_trash = get_trash_chunk();
@ -55,7 +55,7 @@
goto out;
smp->data.u.str = *smp_trash;
@@ -6399,7 +6411,7 @@ smp_fetch_ssl_x_notbefore(const struct a
@@ -6499,7 +6511,7 @@ smp_fetch_ssl_x_notbefore(const struct a
goto out;
smp_trash = get_trash_chunk();
@ -64,7 +64,7 @@
goto out;
smp->data.u.str = *smp_trash;
@@ -8977,7 +8989,9 @@ static void __ssl_sock_init(void)
@@ -9070,7 +9082,9 @@ static void __ssl_sock_init(void)
#endif
xprt_register(XPRT_SSL, &ssl_sock);
@ -74,7 +74,7 @@
#if (!defined(OPENSSL_NO_COMP) && !defined(SSL_OP_NO_COMPRESSION))
cm = SSL_COMP_get_compression_methods();
i = sk_SSL_COMP_num(cm);
@@ -8986,7 +9000,7 @@ static void __ssl_sock_init(void)
@@ -9079,7 +9093,7 @@ static void __ssl_sock_init(void)
}
#endif
@ -83,7 +83,7 @@
ssl_locking_init();
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined OPENSSL_NO_TLSEXT && !defined OPENSSL_IS_BORINGSSL && !defined LIBRESSL_VERSION_NUMBER)
@@ -9015,8 +9029,8 @@ static void __ssl_sock_init(void)
@@ -9108,8 +9122,8 @@ static void __ssl_sock_init(void)
#else /* OPENSSL_IS_BORINGSSL */
OPENSSL_VERSION_TEXT
"\nRunning on OpenSSL version : %s%s",
@ -94,7 +94,7 @@
#endif
memprintf(&ptr, "%s\nOpenSSL library supports TLS extensions : "
#if OPENSSL_VERSION_NUMBER < 0x00907000L
@@ -9107,12 +9121,14 @@ static void __ssl_sock_deinit(void)
@@ -9200,12 +9214,14 @@ static void __ssl_sock_deinit(void)
}
#endif

View File

@ -1,32 +0,0 @@
commit ccb3136727d1fd5efccd4689199aa29f530f6ed0
Author: Dragan Dosen <ddosen@haproxy.com>
Date: Tue Apr 30 00:38:36 2019 +0200
BUG/MINOR: haproxy: fix rule->file memory leak
When using the "use_backend" configuration directive, the configuration
file name stored as rule->file was not freed in some situations. This
was introduced in commit 4ed1c95 ("MINOR: http/conf: store the
use_backend configuration file and line for logs").
This patch should be backported to 1.9, 1.8 and 1.7.
(cherry picked from commit 2a7c20f602e5d40e9f23c703fbcb12e3af762337)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 60277d1a38b45b014478d33627a9bbb99cc9ee9e)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/haproxy.c b/src/haproxy.c
index 6ea17a0c..61169243 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -2123,8 +2123,8 @@ void deinit(void)
if (rule->cond) {
prune_acl_cond(rule->cond);
free(rule->cond);
- free(rule->file);
}
+ free(rule->file);
free(rule);
}

View File

@ -1,33 +0,0 @@
commit a196f480348402a263aa65eed55261e9a59d2da7
Author: Willy Tarreau <w@1wt.eu>
Date: Thu Sep 6 14:52:21 2018 +0200
MINOR: connection: add new function conn_is_back()
This function returns true if the connection is a backend connection
and false if it's a frontend connection.
(cherry picked from commit 57f8185625f967f868187d336f995fac28f83fc5)
[wt: backported since used by next commit]
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/include/proto/connection.h b/include/proto/connection.h
index 352f2fcc..31e746a1 100644
--- a/include/proto/connection.h
+++ b/include/proto/connection.h
@@ -912,6 +912,15 @@ static inline const struct mux_ops *alpn_get_mux(const struct ist token, int htt
return fallback;
}
+/* returns 0 if the connection is valid and is a frontend connection, otherwise
+ * returns 1 indicating it's a backend connection. And uninitialized connection
+ * also returns 1 to better handle the usage in the middle of initialization.
+ */
+static inline int conn_is_back(const struct connection *conn)
+{
+ return !objt_listener(conn->target);
+}
+
/* finds the best mux for incoming connection <conn> and mode <http_mode> for
* the proxy. Null cannot be returned unless there's a serious bug somewhere
* else (no fallback mux registered).

View File

@ -1,77 +0,0 @@
commit ad838cae47c15dc0be018be6c081e241d41ed45f
Author: Olivier Houchard <ohouchard@haproxy.com>
Date: Fri May 3 20:56:19 2019 +0200
BUG/MEDIUM: ssl: Use the early_data API the right way.
We can only read early data if we're a server, and write if we're a client,
so don't attempt to mix both.
This should be backported to 1.8 and 1.9.
(cherry picked from commit 010941f87605e8219d25becdbc652350a687d6a2)
[wt: minor context adjustments due to latest SSL API changes in 2.0]
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 3d14cbddd971f8f301f795c8446ae2bcadab6cc2)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/backend.c b/src/backend.c
index 0cf14cfd..c43fb72f 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1214,10 +1214,8 @@ int connect_server(struct stream *s)
(srv->ssl_ctx.options & SRV_SSL_O_EARLY_DATA) &&
(cli_conn->flags & CO_FL_EARLY_DATA) &&
!channel_is_empty(si_oc(&s->si[1])) &&
- srv_conn->flags & CO_FL_SSL_WAIT_HS) {
+ srv_conn->flags & CO_FL_SSL_WAIT_HS)
srv_conn->flags &= ~(CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN);
- srv_conn->flags |= CO_FL_EARLY_SSL_HS;
- }
#endif
if (err != SF_ERR_NONE)
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 1fc01c1c..76767242 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -5549,7 +5549,7 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
if (!conn->xprt_ctx)
goto out_error;
- if (conn->flags & CO_FL_HANDSHAKE)
+ if (conn->flags & (CO_FL_HANDSHAKE | CO_FL_EARLY_SSL_HS))
/* a handshake was requested */
return 0;
@@ -5578,7 +5578,7 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
}
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L)
- if (!SSL_is_init_finished(conn->xprt_ctx)) {
+ if (!SSL_is_init_finished(conn->xprt_ctx) && conn_is_back(conn)) {
unsigned int max_early;
if (objt_listener(conn->target))
@@ -5593,8 +5593,7 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
if (try + conn->sent_early_data > max_early) {
try -= (try + conn->sent_early_data) - max_early;
if (try <= 0) {
- if (!(conn->flags & CO_FL_EARLY_SSL_HS))
- conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
+ conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN;
break;
}
}
@@ -5602,10 +5601,8 @@ static int ssl_sock_from_buf(struct connection *conn, struct buffer *buf, int fl
if (ret == 1) {
ret = written_data;
conn->sent_early_data += ret;
- if (objt_server(conn->target)) {
- conn->flags &= ~CO_FL_EARLY_SSL_HS;
+ if (objt_server(conn->target))
conn->flags |= CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN | CO_FL_EARLY_DATA;
- }
}

View File

@ -1,39 +0,0 @@
commit ae6824e2c836f1714827e9d3f585e729ea022f30
Author: Willy Tarreau <w@1wt.eu>
Date: Sun May 5 06:54:22 2019 +0200
BUG/MEDIUM: checks: make sure the warmup task takes the server lock
The server warmup task is used when a server uses the "slowstart"
parameter. This task affects the server's weight and maxconn, and may
dequeue pending connections from the queue. This must be done under
the server's lock, which was not the case.
This must be backported to 1.9 and 1.8.
(cherry picked from commit 4fc49a9aabacc8028877e2dcbdb54d8a19c398c4)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 207ba5a6bc1c03f2ba15ac3cd49bfa756fb760bb)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/checks.c b/src/checks.c
index 1ecc4050..fbe14ca1 100644
--- a/src/checks.c
+++ b/src/checks.c
@@ -1445,12 +1445,16 @@ static struct task *server_warmup(struct task *t)
(s->next_state != SRV_ST_STARTING))
return t;
+ HA_SPIN_LOCK(SERVER_LOCK, &s->lock);
+
/* recalculate the weights and update the state */
server_recalc_eweight(s);
/* probably that we can refill this server with a bit more connections */
pendconn_grab_from_px(s);
+ HA_SPIN_UNLOCK(SERVER_LOCK, &s->lock);
+
/* get back there in 1 second or 1/20th of the slowstart interval,
* whichever is greater, resulting in small 5% steps.
*/

View File

@ -1,108 +0,0 @@
commit dc90debd638a2aa94e062e66c00b1b8a9ab3c115
Author: Willy Tarreau <w@1wt.eu>
Date: Sun May 5 10:11:39 2019 +0200
BUG/MINOR: logs/threads: properly split the log area upon startup
If logs were emitted before creating the threads, then the dataptr pointer
keeps a copy of the end of the log header. Then after the threads are
created, the headers are reallocated for each thread. However the end
pointer was not reset until the end of the first second, which may result
in logs emitted by multiple threads during the first second to be mangled,
or possibly in some cases to use a memory area that was reused for something
else. The fix simply consists in reinitializing the end pointers immediately
when the threads are created.
This fix must be backported to 1.9 and 1.8.
(cherry picked from commit 55e2f5ad14a6d9ec39c218296ad3f1a521cc74a1)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 55c3bd480fbbbb4692368655d3d4a425b5248e2a)
[wt: ctx, buf->chunk]
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/log.c b/src/log.c
index 313fa55d..1d8cf335 100644
--- a/src/log.c
+++ b/src/log.c
@@ -212,11 +212,13 @@ char default_rfc5424_sd_log_format[] = "- ";
* update_log_hdr().
*/
THREAD_LOCAL char *logheader = NULL;
+THREAD_LOCAL char *logheader_end = NULL;
/* This is a global syslog header for messages in RFC5424 format. It is
* updated by update_log_hdr_rfc5424().
*/
THREAD_LOCAL char *logheader_rfc5424 = NULL;
+THREAD_LOCAL char *logheader_rfc5424_end = NULL;
/* This is a global syslog message buffer, common to all outgoing
* messages. It contains only the data part.
@@ -986,11 +988,10 @@ char *lf_port(char *dst, struct sockaddr *sockaddr, size_t size, struct logforma
static char *update_log_hdr(const time_t time)
{
static THREAD_LOCAL long tvsec;
- static THREAD_LOCAL char *dataptr = NULL; /* backup of last end of header, NULL first time */
static THREAD_LOCAL struct chunk host = { NULL, 0, 0 };
static THREAD_LOCAL int sep = 0;
- if (unlikely(time != tvsec || dataptr == NULL)) {
+ if (unlikely(time != tvsec || logheader_end == NULL)) {
/* this string is rebuild only once a second */
struct tm tm;
int hdr_len;
@@ -1016,12 +1017,12 @@ static char *update_log_hdr(const time_t time)
if (hdr_len < 0 || hdr_len > global.max_syslog_len)
hdr_len = global.max_syslog_len;
- dataptr = logheader + hdr_len;
+ logheader_end = logheader + hdr_len;
}
- dataptr[0] = 0; // ensure we get rid of any previous attempt
+ logheader_end[0] = 0; // ensure we get rid of any previous attempt
- return dataptr;
+ return logheader_end;
}
/* Re-generate time-based part of the syslog header in RFC5424 format at
@@ -1031,10 +1032,9 @@ static char *update_log_hdr(const time_t time)
static char *update_log_hdr_rfc5424(const time_t time)
{
static THREAD_LOCAL long tvsec;
- static THREAD_LOCAL char *dataptr = NULL; /* backup of last end of header, NULL first time */
const char *gmt_offset;
- if (unlikely(time != tvsec || dataptr == NULL)) {
+ if (unlikely(time != tvsec || logheader_rfc5424_end == NULL)) {
/* this string is rebuild only once a second */
struct tm tm;
int hdr_len;
@@ -1056,12 +1056,12 @@ static char *update_log_hdr_rfc5424(const time_t time)
if (hdr_len < 0 || hdr_len > global.max_syslog_len)
hdr_len = global.max_syslog_len;
- dataptr = logheader_rfc5424 + hdr_len;
+ logheader_rfc5424_end = logheader_rfc5424 + hdr_len;
}
- dataptr[0] = 0; // ensure we get rid of any previous attempt
+ logheader_rfc5424_end[0] = 0; // ensure we get rid of any previous attempt
- return dataptr;
+ return logheader_rfc5424_end;
}
/*
@@ -1369,7 +1369,9 @@ static void deinit_log_buffers_per_thread()
int init_log_buffers()
{
logheader = my_realloc2(logheader, global.max_syslog_len + 1);
+ logheader_end = NULL;
logheader_rfc5424 = my_realloc2(logheader_rfc5424, global.max_syslog_len + 1);
+ logheader_rfc5424_end = NULL;
logline = my_realloc2(logline, global.max_syslog_len + 1);
logline_rfc5424 = my_realloc2(logline_rfc5424, global.max_syslog_len + 1);
if (!logheader || !logline_rfc5424 || !logline || !logline_rfc5424)

View File

@ -1,32 +0,0 @@
commit b6aa92725eaf823c4b18316729eae494783daa85
Author: Olivier Houchard <ohouchard@haproxy.com>
Date: Mon May 6 18:58:48 2019 +0200
MINOR: doc: Document allow-0rtt on the server line.
Briefly document allow-0rtt on the server line, and only the part that apply
to 1.8 and 1.9.
This should be backported to 1.8 and 1.9.
(cherry picked from commit 8cb2d2e94199b8a6a9186ec12ee8146421a5d227)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 895b6a4568287b87d69599f347da01dcd1cfc9b2)
[wt: context]
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/doc/configuration.txt b/doc/configuration.txt
index 7768e761..720b32e3 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -11223,6 +11223,10 @@ agent-port <port>
See also the "agent-check" and "agent-inter" parameters.
+allow-0rtt
+ Allow sending early data to the server when using TLS 1.3.
+ Note that early data will be sent only if the client used early data.
+
backup
When "backup" is present on a server line, the server is only used in load
balancing when all other non-backup servers are unavailable. Requests coming

View File

@ -1,50 +0,0 @@
commit dcb8c973fdfa6b96b651b06740b74b1d492cb92d
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Mon May 6 09:53:10 2019 +0200
BUG/MEDIUM: spoe: Be sure the sample is found before setting its context
When a sample fetch is encoded, we use its context to set info about the
fragmentation. But if the sample is not found, the function sample_process()
returns NULL. So we me be sure the sample exists before setting its context.
This patch must be backported to 1.9 and 1.8.
(cherry picked from commit 3b1d004d410129efcf365643d2583dcd2cb6ed0f)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 2e062883b8f94500314b7c863c1a13e3c9af23ca)
[wt: adjust buf->chunk context]
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/include/proto/spoe.h b/include/proto/spoe.h
index cce13e50..74fe9466 100644
--- a/include/proto/spoe.h
+++ b/include/proto/spoe.h
@@ -169,8 +169,8 @@ spoe_encode_data(struct sample *smp, char **buf, char *end)
* reamining. When all the sample is encoded, the offset is reset to 0.
* So the caller know it can try to encode the next sample. */
struct chunk *chk = &smp->data.u.str;
- unsigned int *len = (smp->ctx.a[0] ? smp->ctx.a[0] : 0);
- unsigned int *off = (smp->ctx.a[1] ? smp->ctx.a[1] : 0);
+ unsigned int *len = smp->ctx.a[0];
+ unsigned int *off = smp->ctx.a[1];
if (!*off) {
/* First evaluation of the sample : encode the
diff --git a/src/flt_spoe.c b/src/flt_spoe.c
index aeb1fde7..9f745943 100644
--- a/src/flt_spoe.c
+++ b/src/flt_spoe.c
@@ -2187,8 +2187,10 @@ spoe_encode_message(struct stream *s, struct spoe_context *ctx,
/* Fetch the arguement value */
smp = sample_process(s->be, s->sess, s, dir|SMP_OPT_FINAL, arg->expr, NULL);
- smp->ctx.a[0] = &ctx->frag_ctx.curlen;
- smp->ctx.a[1] = &ctx->frag_ctx.curoff;
+ if (smp) {
+ smp->ctx.a[0] = &ctx->frag_ctx.curlen;
+ smp->ctx.a[1] = &ctx->frag_ctx.curoff;
+ }
ret = spoe_encode_data(smp, buf, end);
if (ret == -1 || ctx->frag_ctx.curoff)
goto too_big;

View File

@ -1,31 +0,0 @@
commit 42c7b87b18bce3a12a8b1a08435e393ed543f79f
Author: n9@users.noreply.github.com <n9@users.noreply.github.com>
Date: Fri Aug 23 11:21:05 2019 +0200
DOC: fixed typo in management.txt
replaced fot -> for
added two periods
(cherry picked from commit 25a1c8e4539c12c19a3fe04aabe563cdac5e36db)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 7c80af0fb53f2a1d93a597f7d97cc67996e36be2)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit 4c43256c7e78643f8972f4248ed11688137609bb)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/doc/management.txt b/doc/management.txt
index 8fdea722..e79b3cd0 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -1483,8 +1483,8 @@ enable agent <backend>/<server>
level "admin".
enable dynamic-cookie backend <backend>
- Enable the generation of dynamic cookies fot the backend <backend>
- A secret key must also be provided
+ Enable the generation of dynamic cookies for the backend <backend>.
+ A secret key must also be provided.
enable frontend <frontend>
Resume a frontend which was temporarily stopped. It is possible that some of

View File

@ -1,39 +0,0 @@
commit 7ae43ca14823ae61c547ac08c0a237b6ec55e04a
Author: Willy Tarreau <w@1wt.eu>
Date: Mon Aug 26 10:37:39 2019 +0200
BUG/MINOR: mworker: disable SIGPROF on re-exec
If haproxy is built with profiling enabled with -pg, it is possible to
see the master quit during a reload while it's re-executing itself with
error code 155 (signal 27) saying "Profile timer expired)". This happens
if the SIGPROF signal is delivered during the execve() call while the
handler was already unregistered. The issue itself is not directly inside
haproxy but it's easy to address. This patch disables this signal before
calling execvp() during a master reload. A simple test for this consists
in running this little script with haproxy started in master-worker mode :
$ while usleep 50000; do killall -USR2 haproxy; done
This fix should be backported to all versions using the master-worker
model.
(cherry picked from commit e0d86e2c1caaaa2141118e3309d479de5f67e855)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit f259fcc00a04e633a7a64f894a719f78f3644867)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit f2c9971cb51d28f0c4422d1197447406aa72e945)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/haproxy.c b/src/haproxy.c
index 61169243..ef5a05cc 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -705,6 +705,7 @@ static void mworker_reload()
}
ha_warning("Reexecuting Master process\n");
+ signal(SIGPROF, SIG_IGN);
execvp(next_argv[0], next_argv);
ha_warning("Failed to reexecute the master process [%d]: %s\n", pid, strerror(errno));

View File

@ -1,57 +0,0 @@
commit ae9e97ed9d2ac46515e0fba1cb71028169cc3be6
Author: Willy Tarreau <w@1wt.eu>
Date: Mon Aug 26 10:55:52 2019 +0200
BUG/MEDIUM: listener/threads: fix an AB/BA locking issue in delete_listener()
The delete_listener() function takes the listener's lock before taking
the proto_lock, which is contrary to what other functions do, possibly
causing an AB/BA deadlock. In practice the two only places where both
are taken are during protocol_enable_all() and delete_listener(), the
former being used during startup and the latter during stop. In practice
during reload floods, it is technically possible for a thread to be
initializing the listeners while another one is stopping. While this
is too hard to trigger on 2.0 and above due to the synchronization of
all threads during startup, it's reasonably easy to do in 1.9 by having
hundreds of listeners, starting 64 threads and flooding them with reloads
like this :
$ while usleep 50000; do killall -USR2 haproxy; done
Usually in less than a minute, all threads will be deadlocked. The fix
consists in always taking the proto_lock before the listener lock. It
seems to be the only place where these two locks were reversed. This
fix needs to be backported to 2.0, 1.9, and 1.8.
(cherry picked from commit 6ee9f8df3bfbb811526cff3313da5758b1277bc6)
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit b10c8d7641cc8ceae6fba4506b7f987d66109bd9)
[wt: adjusted context]
Signed-off-by: Willy Tarreau <w@1wt.eu>
(cherry picked from commit bf64d1021bd0db1f9892ec34473e34033cdb1dd9)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/src/listener.c b/src/listener.c
index 9832794d..92cc0f75 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -424,17 +424,17 @@ int create_listeners(struct bind_conf *bc, const struct sockaddr_storage *ss,
*/
void delete_listener(struct listener *listener)
{
+ HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
HA_SPIN_LOCK(LISTENER_LOCK, &listener->lock);
if (listener->state == LI_ASSIGNED) {
listener->state = LI_INIT;
- HA_SPIN_LOCK(PROTO_LOCK, &proto_lock);
LIST_DEL(&listener->proto_list);
listener->proto->nb_listeners--;
- HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
HA_ATOMIC_SUB(&jobs, 1);
HA_ATOMIC_SUB(&listeners, 1);
}
HA_SPIN_UNLOCK(LISTENER_LOCK, &listener->lock);
+ HA_SPIN_UNLOCK(PROTO_LOCK, &proto_lock);
}
/* This function is called on a read event from a listening socket, corresponding

View File

@ -1,60 +0,0 @@
commit ba3abeda541ffe93fd528e9bc8701d4faadfb680
Author: Christopher Faulet <cfaulet@haproxy.com>
Date: Wed Sep 4 09:39:42 2019 +0200
BUG/MEDIUM: proto-http: Always start the parsing if there is no outgoing data
When we are waiting for a request or a response, if the channel's buffer is not
rewritable (the reservce is not fully free), nothing is done and we wait to have
a rewritable buffer. It was an old implicit assumption of HTTP analyzers. On old
versions, at this stage, if a buffer was not rewritable, it meant some outgoing
data were pending to be sent.
On recent versions, it should not happen because all outgoing data are sent
before starting the analysis of the next transaction. But the applets may be
lead to use the reserve. For instance, the cache applet adds the header "Age" to
cached responses. It may use the reserve to do so if the size of the response
headers is huge. So, in such case, the implicit assumption of a no rewritable
buffer because of output data is wrong. But the message analysis remains
blocked, sometime infinitely depending on circumstances.
To fix the bug and to avoid any ambiguity, we now also check if there are some
outgoing data when the buffer is not rewritable to postpone the message
analysis. In fact, this code may probably be removed because it should never
happen. But I prefer to be conservative here and don't introduce a bug because of
an unknown/unexpected hidden corner case. Anyway, it is not a big deal because
all legacy HTTP code is removed in the 2.1.
This is a direct commit to the 2.0 branch, as the problem doesn't exist in
master. It must be backported at least to 1.9 and 1.8 because of the cache. But
it may be also backported to all stable versions.
This patch should partly fix the github issue #233.
(cherry picked from commit 3d36d4e720a76a12c7f6cd64c7971237d7d92d78)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit d09d66853a3700d2b9261c02e1027d13b4420f5b)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/proto_http.c b/src/proto_http.c
index c64ba0ea..411eb698 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -1633,7 +1633,7 @@ int http_wait_for_request(struct stream *s, struct channel *req, int an_bit)
*/
if (buffer_not_empty(req->buf) && msg->msg_state < HTTP_MSG_ERROR) {
if (txn->flags & TX_NOT_FIRST) {
- if (unlikely(!channel_is_rewritable(req))) {
+ if (unlikely(!channel_is_rewritable(req) && req->buf->o)) {
if (req->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_WRITE_ERROR|CF_WRITE_TIMEOUT))
goto failed_keep_alive;
/* some data has still not left the buffer, wake us once that's done */
@@ -5102,7 +5102,7 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit)
* data later, which is much more complicated.
*/
if (buffer_not_empty(rep->buf) && msg->msg_state < HTTP_MSG_ERROR) {
- if (unlikely(!channel_is_rewritable(rep))) {
+ if (unlikely(!channel_is_rewritable(rep) && rep->buf->o)) {
/* some data has still not left the buffer, wake us once that's done */
if (rep->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_WRITE_ERROR|CF_WRITE_TIMEOUT))
goto abort_response;