diff --git a/net/haproxy/Makefile b/net/haproxy/Makefile index 202a2056f..bacde98cc 100644 --- a/net/haproxy/Makefile +++ b/net/haproxy/Makefile @@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=haproxy PKG_VERSION:=1.8.14 -PKG_RELEASE:=3 +PKG_RELEASE:=4 PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://www.haproxy.org/download/1.8/src/ diff --git a/net/haproxy/patches/0028-DOC-fix-reference-to-map-files-in-MAINTAINERS.patch b/net/haproxy/patches/0028-DOC-fix-reference-to-map-files-in-MAINTAINERS.patch new file mode 100644 index 000000000..cb9f7cce6 --- /dev/null +++ b/net/haproxy/patches/0028-DOC-fix-reference-to-map-files-in-MAINTAINERS.patch @@ -0,0 +1,24 @@ +commit c1ef9f5389e5debb132b7e2ab40f178ed413a978 +Author: Lukas Tribus +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 + +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 +-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 diff --git a/net/haproxy/patches/0029-BUILD-compiler-rename-__unreachable-to-my_unreachable.patch b/net/haproxy/patches/0029-BUILD-compiler-rename-__unreachable-to-my_unreachable.patch new file mode 100644 index 000000000..3c6b7b721 --- /dev/null +++ b/net/haproxy/patches/0029-BUILD-compiler-rename-__unreachable-to-my_unreachable.patch @@ -0,0 +1,41 @@ +commit 9011ff6c9fb5128dd50b4210e05199ea6337b82b +Author: Willy Tarreau +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 + +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 diff --git a/net/haproxy/patches/0030-BUG-MEDIUM-pools-Fix-the-usage-of-mmap-with-DEBUG_UAF.patch b/net/haproxy/patches/0030-BUG-MEDIUM-pools-Fix-the-usage-of-mmap-with-DEBUG_UAF.patch new file mode 100644 index 000000000..cf258df86 --- /dev/null +++ b/net/haproxy/patches/0030-BUG-MEDIUM-pools-Fix-the-usage-of-mmap-with-DEBUG_UAF.patch @@ -0,0 +1,33 @@ +commit 7e751a3c24a7021075fb298025c4a1ce98a5b049 +Author: Olivier Houchard +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 + +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 + 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 *)) diff --git a/net/haproxy/patches/0031-BUG-MEDIUM-h2-Close-connection-if-no-stream-is-left-an-GOAWAY-was-sent.patch b/net/haproxy/patches/0031-BUG-MEDIUM-h2-Close-connection-if-no-stream-is-left-an-GOAWAY-was-sent.patch new file mode 100644 index 000000000..69eb6cf54 --- /dev/null +++ b/net/haproxy/patches/0031-BUG-MEDIUM-h2-Close-connection-if-no-stream-is-left-an-GOAWAY-was-sent.patch @@ -0,0 +1,28 @@ +commit 105abe2f7a2e518afda9eb3bda5cceb60f6fd1b2 +Author: Olivier Houchard +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 + +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))))) { diff --git a/net/haproxy/patches/0032-BUILD-Makefile-add-the-new-ERR-variable-to-force--Werror.patch b/net/haproxy/patches/0032-BUILD-Makefile-add-the-new-ERR-variable-to-force--Werror.patch new file mode 100644 index 000000000..8edd76e98 --- /dev/null +++ b/net/haproxy/patches/0032-BUILD-Makefile-add-the-new-ERR-variable-to-force--Werror.patch @@ -0,0 +1,46 @@ +commit e1b3aa5613a5edbb52a44d69b3e6007d9d631981 +Author: Willy Tarreau +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 + +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) + diff --git a/net/haproxy/patches/0033-BUG-MINOR-cache-Crashes-with-total-max-size-2047MB.patch b/net/haproxy/patches/0033-BUG-MINOR-cache-Crashes-with-total-max-size-2047MB.patch new file mode 100644 index 000000000..886b8a87d --- /dev/null +++ b/net/haproxy/patches/0033-BUG-MINOR-cache-Crashes-with-total-max-size-2047MB.patch @@ -0,0 +1,55 @@ +commit bf7b382e528ab62a9f695b07e659d2f77545e93d +Author: Frédéric Lécaille +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 + +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; diff --git a/net/haproxy/patches/0034-BUG-MINOR-cache-Wrong-usage-of-shctx_init.patch b/net/haproxy/patches/0034-BUG-MINOR-cache-Wrong-usage-of-shctx_init.patch new file mode 100644 index 000000000..ba799e7bd --- /dev/null +++ b/net/haproxy/patches/0034-BUG-MINOR-cache-Wrong-usage-of-shctx_init.patch @@ -0,0 +1,28 @@ +commit 68c23dedaaae8f29d26c4791b30d138ed1411548 +Author: Frédéric Lécaille +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 + +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 diff --git a/net/haproxy/patches/0035-BUG-MINOR-ssl-Wrong-usage-of-shctx_init.patch b/net/haproxy/patches/0035-BUG-MINOR-ssl-Wrong-usage-of-shctx_init.patch new file mode 100644 index 000000000..a07575c02 --- /dev/null +++ b/net/haproxy/patches/0035-BUG-MINOR-ssl-Wrong-usage-of-shctx_init.patch @@ -0,0 +1,26 @@ +commit 49f82640bf3c9a9c808568344bfa94d279c95b7e +Author: Frédéric Lécaille +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 + +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 diff --git a/net/haproxy/patches/0036-DOC-cache-Missing-information-about-total-max-size.patch b/net/haproxy/patches/0036-DOC-cache-Missing-information-about-total-max-size.patch new file mode 100644 index 000000000..2373a6521 --- /dev/null +++ b/net/haproxy/patches/0036-DOC-cache-Missing-information-about-total-max-size.patch @@ -0,0 +1,24 @@ +commit 9c416cf3cc449fd46880d5a7c3fdd1bb98447b68 +Author: Frédéric Lécaille +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 + +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 + + total-max-size + 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 + Define the maximum expiration duration. The expiration is set has the lowest diff --git a/net/haproxy/patches/0037-BUG-MINOR-only-mark-connections-private-if-NTLM-is-detected.patch b/net/haproxy/patches/0037-BUG-MINOR-only-mark-connections-private-if-NTLM-is-detected.patch new file mode 100644 index 000000000..dd3748f82 --- /dev/null +++ b/net/haproxy/patches/0037-BUG-MINOR-only-mark-connections-private-if-NTLM-is-detected.patch @@ -0,0 +1,94 @@ +commit 7b728d616e417f0a8cd25375f70b8a332ad23a71 +Author: Lukas Tribus +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 + +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, diff --git a/net/haproxy/patches/0038-BUG-MINOR-only-auto-prefer-last-server-if-lb-alg-is-non-deterministic.patch b/net/haproxy/patches/0038-BUG-MINOR-only-auto-prefer-last-server-if-lb-alg-is-non-deterministic.patch new file mode 100644 index 000000000..e3f8a1456 --- /dev/null +++ b/net/haproxy/patches/0038-BUG-MINOR-only-auto-prefer-last-server-if-lb-alg-is-non-deterministic.patch @@ -0,0 +1,76 @@ +commit a100980f50f92e588c2b60f20571e84bf749f3e3 +Author: Lukas Tribus +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 + +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 [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; + } diff --git a/net/haproxy/patches/0039-BUG-MAJOR-http-http_txn_get_path-may-deference-an-inexisting-buffer.patch b/net/haproxy/patches/0039-BUG-MAJOR-http-http_txn_get_path-may-deference-an-inexisting-buffer.patch new file mode 100644 index 000000000..920eac52a --- /dev/null +++ b/net/haproxy/patches/0039-BUG-MAJOR-http-http_txn_get_path-may-deference-an-inexisting-buffer.patch @@ -0,0 +1,39 @@ +commit 69d4ddf919fc4bc6d296a743baeccdd44fb89be6 +Author: Willy Tarreau +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 + +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; + diff --git a/net/haproxy/patches/0040-BUG-MEDIUM-auth-threads-use-of-crypt-is-not-thread-safe.patch b/net/haproxy/patches/0040-BUG-MEDIUM-auth-threads-use-of-crypt-is-not-thread-safe.patch new file mode 100644 index 000000000..b5531c5e1 --- /dev/null +++ b/net/haproxy/patches/0040-BUG-MEDIUM-auth-threads-use-of-crypt-is-not-thread-safe.patch @@ -0,0 +1,77 @@ +commit a873c161d251abd025008034c0ddef8cd7f39511 +Author: Willy Tarreau +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 + +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 + #include + #include ++#include + + #include + #include +@@ -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 diff --git a/net/haproxy/patches/0028-deprecated-openssl.patch b/net/haproxy/patches/0041-deprecated-openssl.patch similarity index 100% rename from net/haproxy/patches/0028-deprecated-openssl.patch rename to net/haproxy/patches/0041-deprecated-openssl.patch