- Add new patches (see https://www.haproxy.org/bugs/bugs-1.8.14.html) - Raise PKG_RELEASE to 4 Signed-off-by: Christian Lachner <gladiac@gmail.com>lilik-openwrt-22.03
@ -0,0 +1,24 @@ | |||
commit c1ef9f5389e5debb132b7e2ab40f178ed413a978 | |||
Author: Lukas Tribus <lukas@ltri.eu> | |||
Date: Wed Oct 17 01:40:11 2018 +0200 | |||
DOC: fix reference to map files in MAINTAINERS | |||
s/maps/map | |||
(cherry picked from commit b75e828b298c958beb10c830a1ccb3df0840c30c) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/MAINTAINERS b/MAINTAINERS | |||
index 3a9e435a..df7cc336 100644 | |||
--- a/MAINTAINERS | |||
+++ b/MAINTAINERS | |||
@@ -24,7 +24,7 @@ Files: src/hlua.c, include/*/hlua.h | |||
Maps and pattern matching | |||
Maintainer: Thierry Fournier <tfournier@arpalert.org> | |||
-Files: src/maps.c, src/pattern.c, include/*/maps.h, include/*/pattern.h | |||
+Files: src/map.c, src/pattern.c, include/*/map.h, include/*/pattern.h | |||
DNS | |||
Maintainer: Baptiste Assmann <bedis9@gmail.com> |
@ -0,0 +1,41 @@ | |||
commit 9011ff6c9fb5128dd50b4210e05199ea6337b82b | |||
Author: Willy Tarreau <w@1wt.eu> | |||
Date: Sat Oct 20 17:45:48 2018 +0200 | |||
BUILD: compiler: rename __unreachable() to my_unreachable() | |||
Olivier reported that on FreeBSD __unreachable is already defined | |||
and causes build warnings. Let's rename it then. | |||
(cherry picked from commit 4e7cc3381b27e3971b02b73a113ecc13916e1f20) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/include/common/compiler.h b/include/common/compiler.h | |||
index 6f4f5a67..60549307 100644 | |||
--- a/include/common/compiler.h | |||
+++ b/include/common/compiler.h | |||
@@ -89,9 +89,9 @@ | |||
* below was introduced in gcc 4.5, and before it we didn't care. | |||
*/ | |||
#if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) | |||
-#define __unreachable() __builtin_unreachable() | |||
+#define my_unreachable() __builtin_unreachable() | |||
#else | |||
-#define __unreachable() | |||
+#define my_unreachable() | |||
#endif | |||
/* | |||
diff --git a/src/hlua.c b/src/hlua.c | |||
index c3bb269a..085544dc 100644 | |||
--- a/src/hlua.c | |||
+++ b/src/hlua.c | |||
@@ -64,7 +64,7 @@ | |||
* MAY_LJMP() marks an lua function that may use longjmp. | |||
*/ | |||
#define __LJMP | |||
-#define WILL_LJMP(func) do { func; __unreachable(); } while(0) | |||
+#define WILL_LJMP(func) do { func; my_unreachable(); } while(0) | |||
#define MAY_LJMP(func) func | |||
/* This couple of function executes securely some Lua calls outside of |
@ -0,0 +1,33 @@ | |||
commit 7e751a3c24a7021075fb298025c4a1ce98a5b049 | |||
Author: Olivier Houchard <cognet@ci0.org> | |||
Date: Sun Oct 21 01:33:11 2018 +0200 | |||
BUG/MEDIUM: pools: Fix the usage of mmap()) with DEBUG_UAF. | |||
When mapping memory with mmap(), we should use a fd of -1, not 0. 0 may | |||
work on linux, but it doesn't work on FreeBSD, and probably other OSes. | |||
It would be nice to backport this to 1.8 to help debugging there. | |||
(cherry picked from commit 62975a7740cba4bdaf1c096dd246feba854d2410) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/include/common/memory.h b/include/common/memory.h | |||
index a2237da5..da0641de 100644 | |||
--- a/include/common/memory.h | |||
+++ b/include/common/memory.h | |||
@@ -186,12 +186,13 @@ static inline void pool_free_area(void *area, size_t __maybe_unused size) | |||
* some padding is added, the area's start address is copied at the end of the | |||
* padding to help detect underflows. | |||
*/ | |||
+#include <errno.h> | |||
static inline void *pool_alloc_area(size_t size) | |||
{ | |||
size_t pad = (4096 - size) & 0xFF0; | |||
void *ret; | |||
- ret = mmap(NULL, (size + 4095) & -4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); | |||
+ ret = mmap(NULL, (size + 4095) & -4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |||
if (ret == MAP_FAILED) | |||
return NULL; | |||
if (pad >= sizeof(void *)) |
@ -0,0 +1,28 @@ | |||
commit 105abe2f7a2e518afda9eb3bda5cceb60f6fd1b2 | |||
Author: Olivier Houchard <cognet@ci0.org> | |||
Date: Sun Oct 21 03:01:20 2018 +0200 | |||
BUG/MEDIUM: h2: Close connection if no stream is left an GOAWAY was sent. | |||
When we're closing a stream, is there's no stream left and a goaway was sent, | |||
close the connection, there's no reason to keep it open. | |||
[wt: it's likely that this is needed in 1.8 as well, though it's unclear | |||
how to trigger this issue, some tests are needed] | |||
(cherry picked from commit 52b946686c28891a4359e9361676dc62af4fffad) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/src/mux_h2.c b/src/mux_h2.c | |||
index b1b039fe..6881302b 100644 | |||
--- a/src/mux_h2.c | |||
+++ b/src/mux_h2.c | |||
@@ -2540,7 +2540,7 @@ static void h2_detach(struct conn_stream *cs) | |||
if (eb_is_empty(&h2c->streams_by_id) && /* don't close if streams exist */ | |||
((h2c->conn->flags & CO_FL_ERROR) || /* errors close immediately */ | |||
(h2c->st0 >= H2_CS_ERROR && !h2c->task) || /* a timeout stroke earlier */ | |||
- (h2c->flags & H2_CF_GOAWAY_FAILED) || | |||
+ (h2c->flags & (H2_CF_GOAWAY_FAILED | H2_CF_GOAWAY_SENT)) || | |||
(!h2c->mbuf->o && /* mux buffer empty, also process clean events below */ | |||
(conn_xprt_read0_pending(h2c->conn) || | |||
(h2c->last_sid >= 0 && h2c->max_id >= h2c->last_sid))))) { |
@ -0,0 +1,46 @@ | |||
commit e1b3aa5613a5edbb52a44d69b3e6007d9d631981 | |||
Author: Willy Tarreau <w@1wt.eu> | |||
Date: Mon Oct 22 06:22:46 2018 +0200 | |||
BUILD: Makefile: add the new ERR variable to force -Werror | |||
Instead of having to fiddle with the CFLAGS, let's have ERR=1 to enable | |||
-Werror. | |||
(cherry picked from commit 23cd43e2d6fa2b6892a786a1a720c5f24e657f10) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/Makefile b/Makefile | |||
index 6ffc1b06..94e04738 100644 | |||
--- a/Makefile | |||
+++ b/Makefile | |||
@@ -57,6 +57,7 @@ | |||
# DEP may be cleared to ignore changes to include files during development | |||
# SMALL_OPTS may be used to specify some options to shrink memory usage. | |||
# DEBUG may be used to set some internal debugging options. | |||
+# ERR may be set to non-empty to pass -Werror to the compiler | |||
# ADDINC may be used to complete the include path in the form -Ipath. | |||
# ADDLIB may be used to complete the library list in the form -Lpath -llib. | |||
# DEFINE may be used to specify any additional define, which will be reported | |||
@@ -143,6 +144,9 @@ LD = $(CC) | |||
# Those flags only feed CFLAGS so it is not mandatory to use this form. | |||
DEBUG_CFLAGS = -g | |||
+#### Add -Werror when set to non-empty | |||
+ERR = | |||
+ | |||
#### Compiler-specific flags that may be used to disable some negative over- | |||
# optimization or to silence some warnings. -fno-strict-aliasing is needed with | |||
# gcc >= 4.4. | |||
@@ -807,6 +811,11 @@ EBTREE_DIR := ebtree | |||
#### Global compile options | |||
VERBOSE_CFLAGS = $(CFLAGS) $(TARGET_CFLAGS) $(SMALL_OPTS) $(DEFINE) | |||
COPTS = -Iinclude -I$(EBTREE_DIR) -Wall | |||
+ | |||
+ifneq ($(ERR),) | |||
+COPTS += -Werror | |||
+endif | |||
+ | |||
COPTS += $(CFLAGS) $(TARGET_CFLAGS) $(SMALL_OPTS) $(DEFINE) $(SILENT_DEFINE) | |||
COPTS += $(DEBUG) $(OPTIONS_CFLAGS) $(ADDINC) | |||
@ -0,0 +1,55 @@ | |||
commit bf7b382e528ab62a9f695b07e659d2f77545e93d | |||
Author: Frédéric Lécaille <flecaille@haproxy.com> | |||
Date: Thu Oct 25 20:17:45 2018 +0200 | |||
BUG/MINOR: cache: Crashes with "total-max-size" > 2047(MB). | |||
With this patch we support cache size larger than 2047 (MB) and prevent haproxy from crashing when "total-max-size" is parsed as negative values by atoi(). | |||
The limit at parsing time is 4095 MB (UINT_MAX >> 20). | |||
May be backported to 1.8. | |||
(cherry picked from commit b9b8b6b6beb84b6b942d24eda56bfbe3812cc294) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/src/cache.c b/src/cache.c | |||
index 39e0bad4..df3649ea 100644 | |||
--- a/src/cache.c | |||
+++ b/src/cache.c | |||
@@ -770,17 +770,32 @@ int cfg_parse_cache(const char *file, int linenum, char **args, int kwm) | |||
tmp_cache_config->maxblocks = 0; | |||
} | |||
} else if (strcmp(args[0], "total-max-size") == 0) { | |||
- int maxsize; | |||
+ unsigned long int maxsize; | |||
+ char *err; | |||
if (alertif_too_many_args(1, file, linenum, args, &err_code)) { | |||
err_code |= ERR_ABORT; | |||
goto out; | |||
} | |||
+ maxsize = strtoul(args[1], &err, 10); | |||
+ if (err == args[1] || *err != '\0') { | |||
+ ha_warning("parsing [%s:%d]: total-max-size wrong value '%s'\n", | |||
+ file, linenum, args[1]); | |||
+ err_code |= ERR_ABORT; | |||
+ goto out; | |||
+ } | |||
+ | |||
+ if (maxsize > (UINT_MAX >> 20)) { | |||
+ ha_warning("parsing [%s:%d]: \"total-max-size\" (%s) must not be greater than %u\n", | |||
+ file, linenum, args[1], UINT_MAX >> 20); | |||
+ err_code |= ERR_ABORT; | |||
+ goto out; | |||
+ } | |||
+ | |||
/* size in megabytes */ | |||
- maxsize = atoi(args[1]) * 1024 * 1024 / CACHE_BLOCKSIZE; | |||
+ maxsize *= 1024 * 1024 / CACHE_BLOCKSIZE; | |||
tmp_cache_config->maxblocks = maxsize; | |||
- | |||
} else if (strcmp(args[0], "max-age") == 0) { | |||
if (alertif_too_many_args(1, file, linenum, args, &err_code)) { | |||
err_code |= ERR_ABORT; |
@ -0,0 +1,28 @@ | |||
commit 68c23dedaaae8f29d26c4791b30d138ed1411548 | |||
Author: Frédéric Lécaille <flecaille@haproxy.com> | |||
Date: Thu Oct 25 20:18:59 2018 +0200 | |||
BUG/MINOR: cache: Wrong usage of shctx_init(). | |||
With this patch we check that shctx_init() does not returns 0. | |||
This is possible if the maxblocks argument, which is passed as an | |||
int, is negative due to an implicit conversion. | |||
Must be backported to 1.8. | |||
(cherry picked from commit bc584494e625983f16f35982aa6dd6889e8dd222) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/src/cache.c b/src/cache.c | |||
index df3649ea..667cede3 100644 | |||
--- a/src/cache.c | |||
+++ b/src/cache.c | |||
@@ -837,7 +837,7 @@ int cfg_post_parse_section_cache() | |||
ret_shctx = shctx_init(&shctx, tmp_cache_config->maxblocks, CACHE_BLOCKSIZE, sizeof(struct cache), 1); | |||
- if (ret_shctx < 0) { | |||
+ if (ret_shctx <= 0) { | |||
if (ret_shctx == SHCTX_E_INIT_LOCK) | |||
ha_alert("Unable to initialize the lock for the cache.\n"); | |||
else |
@ -0,0 +1,26 @@ | |||
commit 49f82640bf3c9a9c808568344bfa94d279c95b7e | |||
Author: Frédéric Lécaille <flecaille@haproxy.com> | |||
Date: Thu Oct 25 20:22:46 2018 +0200 | |||
BUG/MINOR: ssl: Wrong usage of shctx_init(). | |||
With this patch we check that shctx_init() does not return 0. | |||
Must be backported to 1.8. | |||
(cherry picked from commit 4c8aa117f9bda3b5253f03ad5a7135a9165060f5) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/src/ssl_sock.c b/src/ssl_sock.c | |||
index cfbc38b7..19e41743 100644 | |||
--- a/src/ssl_sock.c | |||
+++ b/src/ssl_sock.c | |||
@@ -4768,7 +4768,7 @@ int ssl_sock_prepare_bind_conf(struct bind_conf *bind_conf) | |||
sizeof(struct sh_ssl_sess_hdr) + SHSESS_BLOCK_MIN_SIZE, | |||
sizeof(*sh_ssl_sess_tree), | |||
((global.nbthread > 1) || (!global_ssl.private_cache && (global.nbproc > 1))) ? 1 : 0); | |||
- if (alloc_ctx < 0) { | |||
+ if (alloc_ctx <= 0) { | |||
if (alloc_ctx == SHCTX_E_INIT_LOCK) | |||
ha_alert("Unable to initialize the lock for the shared SSL session cache. You can retry using the global statement 'tune.ssl.force-private-cache' but it could increase CPU usage due to renegotiations if nbproc > 1.\n"); | |||
else |
@ -0,0 +1,24 @@ | |||
commit 9c416cf3cc449fd46880d5a7c3fdd1bb98447b68 | |||
Author: Frédéric Lécaille <flecaille@haproxy.com> | |||
Date: Thu Oct 25 10:46:40 2018 +0200 | |||
DOC: cache: Missing information about "total-max-size" | |||
(cherry picked from commit e3c83d80e3aadb7b2641b861725c9d1dd7dc6713) | |||
[wt: this only retrieves from the original patch the part related to | |||
the max configurable size for total-max-size] | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/doc/configuration.txt b/doc/configuration.txt | |||
index 7a268386..09980248 100644 | |||
--- a/doc/configuration.txt | |||
+++ b/doc/configuration.txt | |||
@@ -17132,7 +17132,7 @@ cache <name> | |||
total-max-size <megabytes> | |||
Define the size in RAM of the cache in megabytes. This size is split in | |||
- blocks of 1kB which are used by the cache entries. | |||
+ blocks of 1kB which are used by the cache entries. Its maximum value is 4095. | |||
max-age <seconds> | |||
Define the maximum expiration duration. The expiration is set has the lowest |
@ -0,0 +1,94 @@ | |||
commit 7b728d616e417f0a8cd25375f70b8a332ad23a71 | |||
Author: Lukas Tribus <lukas@ltri.eu> | |||
Date: Sat Oct 27 20:06:59 2018 +0200 | |||
BUG/MINOR: only mark connections private if NTLM is detected | |||
Instead of marking all connections that see a 401/407 response private | |||
(for connection reuse), this patch detects a RFC4559/NTLM authentication | |||
scheme and restricts the private setting to those connections. | |||
This is so we can reuse connections with 401/407 responses with | |||
deterministic load balancing algorithms later (which requires another fix). | |||
This fixes the problem reported here by Elliot Barlas : | |||
https://discourse.haproxy.org/t/unable-to-configure-load-balancing-per-request-over-persistent-connection/3144 | |||
Should be backported to 1.8. | |||
(cherry picked from commit fd9b68c48ecdba5e7971899f4eec315c8e3a3cfe) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/doc/configuration.txt b/doc/configuration.txt | |||
index 09980248..43b1b822 100644 | |||
--- a/doc/configuration.txt | |||
+++ b/doc/configuration.txt | |||
@@ -4798,10 +4798,8 @@ http-reuse { never | safe | aggressive | always } | |||
- connections sent to a server with a TLS SNI extension are marked private | |||
and are never shared; | |||
- - connections receiving a status code 401 or 407 expect some authentication | |||
- to be sent in return. Due to certain bogus authentication schemes (such | |||
- as NTLM) relying on the connection, these connections are marked private | |||
- and are never shared; | |||
+ - connections with certain bogus authentication schemes (relying on the | |||
+ connection) like NTLM are detected, marked private and are never shared; | |||
No connection pool is involved, once a session dies, the last idle connection | |||
it was attached to is deleted at the same time. This ensures that connections | |||
diff --git a/src/proto_http.c b/src/proto_http.c | |||
index 8f86422d..cde2dbf7 100644 | |||
--- a/src/proto_http.c | |||
+++ b/src/proto_http.c | |||
@@ -4388,8 +4388,6 @@ void http_end_txn_clean_session(struct stream *s) | |||
* it's better to do it (at least it helps with debugging). | |||
*/ | |||
s->txn->flags |= TX_PREFER_LAST; | |||
- if (srv_conn) | |||
- srv_conn->flags |= CO_FL_PRIVATE; | |||
} | |||
/* Never ever allow to reuse a connection from a non-reuse backend */ | |||
@@ -5053,10 +5051,13 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) | |||
struct http_txn *txn = s->txn; | |||
struct http_msg *msg = &txn->rsp; | |||
struct hdr_ctx ctx; | |||
+ struct connection *srv_conn; | |||
int use_close_only; | |||
int cur_idx; | |||
int n; | |||
+ srv_conn = cs_conn(objt_cs(s->si[1].end)); | |||
+ | |||
DPRINTF(stderr,"[%u] %s: stream=%p b=%p, exp(r,w)=%u,%u bf=%08x bh=%d analysers=%02x\n", | |||
now_ms, __FUNCTION__, | |||
s, | |||
@@ -5588,6 +5589,27 @@ int http_wait_for_response(struct stream *s, struct channel *rep, int an_bit) | |||
msg->body_len = msg->chunk_len = cl; | |||
} | |||
+ /* check for NTML authentication headers in 401 (WWW-Authenticate) and | |||
+ * 407 (Proxy-Authenticate) responses and set the connection to private | |||
+ */ | |||
+ if (srv_conn && txn->status == 401) { | |||
+ /* check for Negotiate/NTLM WWW-Authenticate headers */ | |||
+ ctx.idx = 0; | |||
+ while (http_find_header2("WWW-Authenticate", 16, rep->buf->p, &txn->hdr_idx, &ctx)) { | |||
+ if ((ctx.vlen >= 9 && word_match(ctx.line + ctx.val, ctx.vlen, "Negotiate", 9)) || | |||
+ (ctx.vlen >= 4 && word_match(ctx.line + ctx.val, ctx.vlen, "NTLM", 4))) | |||
+ srv_conn->flags |= CO_FL_PRIVATE; | |||
+ } | |||
+ } else if (srv_conn && txn->status == 407) { | |||
+ /* check for Negotiate/NTLM Proxy-Authenticate headers */ | |||
+ ctx.idx = 0; | |||
+ while (http_find_header2("Proxy-Authenticate", 18, rep->buf->p, &txn->hdr_idx, &ctx)) { | |||
+ if ((ctx.vlen >= 9 && word_match(ctx.line + ctx.val, ctx.vlen, "Negotiate", 9)) || | |||
+ (ctx.vlen >= 4 && word_match(ctx.line + ctx.val, ctx.vlen, "NTLM", 4))) | |||
+ srv_conn->flags |= CO_FL_PRIVATE; | |||
+ } | |||
+ } | |||
+ | |||
skip_content_length: | |||
/* Now we have to check if we need to modify the Connection header. | |||
* This is more difficult on the response than it is on the request, |
@ -0,0 +1,76 @@ | |||
commit a100980f50f92e588c2b60f20571e84bf749f3e3 | |||
Author: Lukas Tribus <lukas@ltri.eu> | |||
Date: Sat Oct 27 20:07:40 2018 +0200 | |||
BUG/MINOR: only auto-prefer last server if lb-alg is non-deterministic | |||
While "option prefer-last-server" only applies to non-deterministic load | |||
balancing algorithms, 401/407 responses actually caused haproxy to prefer | |||
the last server unconditionally. | |||
As this breaks deterministic load balancing algorithms like uri, this | |||
patch applies the same condition here. | |||
Should be backported to 1.8 (together with "BUG/MINOR: only mark | |||
connections private if NTLM is detected"). | |||
(cherry picked from commit 80512b186fd7f4ef3bc7d9c92b281c549d72aa8a) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/doc/configuration.txt b/doc/configuration.txt | |||
index 43b1b822..f0558d5e 100644 | |||
--- a/doc/configuration.txt | |||
+++ b/doc/configuration.txt | |||
@@ -2498,6 +2498,11 @@ balance url_param <param> [check_post] | |||
algorithm, mode nor option have been set. The algorithm may only be set once | |||
for each backend. | |||
+ With authentication schemes that require the same connection like NTLM, URI | |||
+ based alghoritms must not be used, as they would cause subsequent requests | |||
+ to be routed to different backend servers, breaking the invalid assumptions | |||
+ NTLM relies on. | |||
+ | |||
Examples : | |||
balance roundrobin | |||
balance url_param userid | |||
@@ -6486,8 +6491,9 @@ no option prefer-last-server | |||
close of the connection. This can make sense for static file servers. It does | |||
not make much sense to use this in combination with hashing algorithms. Note, | |||
haproxy already automatically tries to stick to a server which sends a 401 or | |||
- to a proxy which sends a 407 (authentication required). This is mandatory for | |||
- use with the broken NTLM authentication challenge, and significantly helps in | |||
+ to a proxy which sends a 407 (authentication required), when the load | |||
+ balancing algorithm is not deterministic. This is mandatory for use with the | |||
+ broken NTLM authentication challenge, and significantly helps in | |||
troubleshooting some faulty applications. Option prefer-last-server might be | |||
desirable in these environments as well, to avoid redistributing the traffic | |||
after every other response. | |||
diff --git a/src/backend.c b/src/backend.c | |||
index fc1eac0d..b3fd6c67 100644 | |||
--- a/src/backend.c | |||
+++ b/src/backend.c | |||
@@ -572,9 +572,9 @@ int assign_server(struct stream *s) | |||
if (conn && | |||
(conn->flags & CO_FL_CONNECTED) && | |||
objt_server(conn->target) && __objt_server(conn->target)->proxy == s->be && | |||
+ (s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI && | |||
((s->txn && s->txn->flags & TX_PREFER_LAST) || | |||
((s->be->options & PR_O_PREF_LAST) && | |||
- (s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI && | |||
(!s->be->max_ka_queue || | |||
server_has_room(__objt_server(conn->target)) || | |||
(__objt_server(conn->target)->nbpend + 1) < s->be->max_ka_queue))) && | |||
diff --git a/src/proto_http.c b/src/proto_http.c | |||
index cde2dbf7..a48c4fdb 100644 | |||
--- a/src/proto_http.c | |||
+++ b/src/proto_http.c | |||
@@ -4385,7 +4385,8 @@ void http_end_txn_clean_session(struct stream *s) | |||
* server over the same connection. This is required by some | |||
* broken protocols such as NTLM, and anyway whenever there is | |||
* an opportunity for sending the challenge to the proper place, | |||
- * it's better to do it (at least it helps with debugging). | |||
+ * it's better to do it (at least it helps with debugging), at | |||
+ * least for non-deterministic load balancing algorithms. | |||
*/ | |||
s->txn->flags |= TX_PREFER_LAST; | |||
} |
@ -0,0 +1,39 @@ | |||
commit 69d4ddf919fc4bc6d296a743baeccdd44fb89be6 | |||
Author: Willy Tarreau <w@1wt.eu> | |||
Date: Sun Oct 28 20:13:12 2018 +0100 | |||
BUG/MAJOR: http: http_txn_get_path() may deference an inexisting buffer | |||
When the "path" sample fetch function is called without any path, the | |||
function doesn't check that the request buffer is allocated. While this | |||
doesn't happen with the request during processing, it can definitely | |||
happen when mistakenly trying to reference a path from the response | |||
since the request channel is not allocated anymore. | |||
It's certain that this bug was emphasized by the buffer changes that | |||
went in 1.9 and the HTTP refactoring, but at first glance, 1.8 doesn't | |||
seem 100% safe either so it's possible that older version are affected | |||
as well. | |||
Thanks to PiBa-NL for reporting this bug with a reproducer. | |||
(cherry picked from commit 9d9ccdbf8b1178fefa2843c83bc6612733f9eca6) | |||
[wt: minor adaptation to older buffer API. There are some call places | |||
which don't look structurally safe though in their context the | |||
buffer always ought to be there] | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/src/proto_http.c b/src/proto_http.c | |||
index a48c4fdb..fb18357b 100644 | |||
--- a/src/proto_http.c | |||
+++ b/src/proto_http.c | |||
@@ -985,6 +985,9 @@ char *http_get_path(struct http_txn *txn) | |||
{ | |||
char *ptr, *end; | |||
+ if (!txn->req.chn->buf->size) | |||
+ return NULL; | |||
+ | |||
ptr = txn->req.chn->buf->p + txn->req.sl.rq.u; | |||
end = ptr + txn->req.sl.rq.u_l; | |||
@ -0,0 +1,77 @@ | |||
commit a873c161d251abd025008034c0ddef8cd7f39511 | |||
Author: Willy Tarreau <w@1wt.eu> | |||
Date: Mon Oct 29 18:02:54 2018 +0100 | |||
BUG/MEDIUM: auth/threads: use of crypt() is not thread-safe | |||
It was reported here that authentication may fail when threads are | |||
enabled : | |||
https://bugzilla.redhat.com/show_bug.cgi?id=1643941 | |||
While I couldn't reproduce the issue, it's obvious that there is a | |||
problem with the use of the non-reentrant crypt() function there. | |||
On Linux systems there's crypt_r() but not on the vast majority of | |||
other ones. Thus a first approach consists in placing a lock around | |||
this crypt() call. Another patch may relax it when crypt_r() is | |||
available. | |||
This fix must be backported to 1.8. Thanks to Ryan O'Hara for the | |||
quick notification. | |||
(cherry picked from commit 34d4b525a129baa6f52a930ae629ddb1ba4255c2) | |||
Signed-off-by: Willy Tarreau <w@1wt.eu> | |||
diff --git a/include/common/hathreads.h b/include/common/hathreads.h | |||
index 44bd66d1..24fb1d1a 100644 | |||
--- a/include/common/hathreads.h | |||
+++ b/include/common/hathreads.h | |||
@@ -373,6 +373,7 @@ enum lock_label { | |||
START_LOCK, | |||
TLSKEYS_REF_LOCK, | |||
PENDCONN_LOCK, | |||
+ AUTH_LOCK, | |||
LOCK_LABELS | |||
}; | |||
struct lock_stat { | |||
@@ -495,6 +496,7 @@ static inline const char *lock_label(enum lock_label label) | |||
case START_LOCK: return "START"; | |||
case TLSKEYS_REF_LOCK: return "TLSKEYS_REF"; | |||
case PENDCONN_LOCK: return "PENDCONN"; | |||
+ case AUTH_LOCK: return "AUTH"; | |||
case LOCK_LABELS: break; /* keep compiler happy */ | |||
}; | |||
/* only way to come here is consecutive to an internal bug */ | |||
diff --git a/src/auth.c b/src/auth.c | |||
index a2c689f7..e0fb1352 100644 | |||
--- a/src/auth.c | |||
+++ b/src/auth.c | |||
@@ -28,6 +28,7 @@ | |||
#include <types/global.h> | |||
#include <common/config.h> | |||
#include <common/errors.h> | |||
+#include <common/hathreads.h> | |||
#include <proto/acl.h> | |||
#include <proto/log.h> | |||
@@ -37,6 +38,10 @@ | |||
struct userlist *userlist = NULL; /* list of all existing userlists */ | |||
+#ifdef CONFIG_HAP_CRYPT | |||
+__decl_hathreads(static HA_SPINLOCK_T auth_lock); | |||
+#endif | |||
+ | |||
/* find targets for selected gropus. The function returns pointer to | |||
* the userlist struct ot NULL if name is NULL/empty or unresolvable. | |||
*/ | |||
@@ -245,7 +250,9 @@ check_user(struct userlist *ul, const char *user, const char *pass) | |||
if (!(u->flags & AU_O_INSECURE)) { | |||
#ifdef CONFIG_HAP_CRYPT | |||
+ HA_SPIN_LOCK(AUTH_LOCK, &auth_lock); | |||
ep = crypt(pass, u->pass); | |||
+ HA_SPIN_UNLOCK(AUTH_LOCK, &auth_lock); | |||
#else | |||
return 0; | |||
#endif |