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:
parent
fff2e26a9b
commit
bc37a31b16
15 changed files with 9 additions and 600 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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).
|
|
@ -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;
|
||||
- }
|
||||
|
||||
}
|
||||
|
|
@ -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.
|
||||
*/
|
|
@ -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)
|
|
@ -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
|
|
@ -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;
|
|
@ -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
|
|
@ -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));
|
|
@ -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
|
|
@ -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;
|
Loading…
Reference in a new issue