Browse Source

haproxy: new release 1.5.4 that fixes recent cve

- BUG: config: error in http-response replace-header number of arguments
    - BUG/MINOR: Fix search for -p argument in systemd wrapper.
    - BUG/MEDIUM: auth: fix segfault with http-auth and a configuration with an unknown encryption algorithm
    - BUG/MEDIUM: config: userlists should ensure that encrypted passwords are supported
    - MEDIUM: connection: add new bit in Proxy Protocol V2
    - BUG/MINOR: server: move the directive #endif to the end of file
    - BUG/MEDIUM: http: tarpit timeout is reset
    - BUG/MAJOR: tcp: fix a possible busy spinning loop in content track-sc*
    - BUG/MEDIUM: http: fix inverted condition in pat_match_meth()
    - BUG/MEDIUM: http: fix improper parsing of HTTP methods for use with ACLs
    - BUG/MINOR: pattern: remove useless allocation of unused trash in pat_parse_reg()
    - BUG/MEDIUM: acl: correctly compute the output type when a converter is used
    - CLEANUP: acl: cleanup some of the redundancy and spaghetti after last fix
    - BUG/CRITICAL: http: don't update msg->sov once data start to leave the buffer

Signed-off-by: Thomas Heil <heil@terminal-consulting.de>
lilik-openwrt-22.03
Thomas Heil 10 years ago
parent
commit
fbe4697b49
7 changed files with 3 additions and 389 deletions
  1. +3
    -3
      net/haproxy/Makefile
  2. +0
    -42
      net/haproxy/patches/0001-BUG-MINOR-server-move-the-directive-endif-to-the-end.patch
  3. +0
    -42
      net/haproxy/patches/0002-BUG-MINOR-Fix-search-for-p-argument-in-systemd-wrapp.patch
  4. +0
    -111
      net/haproxy/patches/0003-BUG-MAJOR-tcp-fix-a-possible-busy-spinning-loop-in-c.patch
  5. +0
    -34
      net/haproxy/patches/0004-BUG-config-error-in-http-response-replace-header-num.patch
  6. +0
    -45
      net/haproxy/patches/0005-BUG-MEDIUM-http-tarpit-timeout-is-reset.patch
  7. +0
    -112
      net/haproxy/patches/0006-MEDIUM-connection-add-new-bit-in-Proxy-Protocol-V2.patch

+ 3
- 3
net/haproxy/Makefile View File

@ -9,11 +9,11 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=haproxy PKG_NAME:=haproxy
PKG_VERSION:=1.5.3
PKG_RELEASE:=06
PKG_VERSION:=1.5.4
PKG_RELEASE:=01
PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz PKG_SOURCE:=haproxy-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.5/src/ PKG_SOURCE_URL:=http://haproxy.1wt.eu/download/1.5/src/
PKG_MD5SUM:=e999a547d57445d5a5ab7eb6a06df9a1
PKG_MD5SUM:=b027035bfd8f28326634f802c3447a34
PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de> PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>
PKG_LICENSE:=GPL-2.0 PKG_LICENSE:=GPL-2.0


+ 0
- 42
net/haproxy/patches/0001-BUG-MINOR-server-move-the-directive-endif-to-the-end.patch View File

@ -1,42 +0,0 @@
From ad65af7dab9b8d8033fd09d8031cc774a6fbf768 Mon Sep 17 00:00:00 2001
From: Godbach <nylzhaowei@gmail.com>
Date: Mon, 28 Jul 2014 17:31:57 +0800
Subject: [PATCH 1/3] BUG/MINOR: server: move the directive #endif to the end
of file
If a source file includes proto/server.h twice or more, redefinition errors will
be triggered for such inline functions as server_throttle_rate(),
server_is_draining(), srv_adm_set_maint() and so on. Just move #endif directive
to the end of file to solve this issue.
Signed-off-by: Godbach <nylzhaowei@gmail.com>
(cherry picked from commit e468d55998e134dac1b18d5d9d075ffd5691c827)
---
include/proto/server.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/proto/server.h b/include/proto/server.h
index 9893266..71c8b13 100644
--- a/include/proto/server.h
+++ b/include/proto/server.h
@@ -54,8 +54,6 @@ static void inline srv_set_sess_last(struct server *s)
s->counters.last_sess = now.tv_sec;
}
-#endif /* _PROTO_SERVER_H */
-
/*
* Registers the server keyword list <kwl> as a list of valid keywords for next
* parsing sessions.
@@ -200,6 +198,8 @@ static inline void srv_adm_set_ready(struct server *s)
srv_clr_admin_flag(s, SRV_ADMF_FMAINT);
}
+#endif /* _PROTO_SERVER_H */
+
/*
* Local variables:
* c-indent-level: 8
--
1.8.5.5

+ 0
- 42
net/haproxy/patches/0002-BUG-MINOR-Fix-search-for-p-argument-in-systemd-wrapp.patch View File

@ -1,42 +0,0 @@
From 715e9b892f564e58489f86c125aed2a8994f16e9 Mon Sep 17 00:00:00 2001
From: Conrad Hoffmann <conrad@soundcloud.com>
Date: Mon, 28 Jul 2014 23:22:43 +0200
Subject: [PATCH 2/3] BUG/MINOR: Fix search for -p argument in systemd wrapper.
Searching for the pid file in the list of arguments did not
take flags without parameters into account, like e.g. -de. Because
of this, the wrapper would use a different pid file than haproxy
if such an argument was specified before -p.
The new version can still yield a false positive for some crazy
situations, like your config file name starting with "-p", but
I think this is as good as it gets without using getopt or some
library.
Signed-off-by: Conrad Hoffmann <conrad@soundcloud.com>
(cherry picked from commit eb2cf45b72a7e14c581276247381dc1ac76be2c0)
---
src/haproxy-systemd-wrapper.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/src/haproxy-systemd-wrapper.c b/src/haproxy-systemd-wrapper.c
index ba07ebe..529b213 100644
--- a/src/haproxy-systemd-wrapper.c
+++ b/src/haproxy-systemd-wrapper.c
@@ -130,11 +130,8 @@ static void sigint_handler(int signum __attribute__((unused)))
static void init(int argc, char **argv)
{
while (argc > 1) {
- if (**argv == '-') {
- char *flag = *argv + 1;
- --argc; ++argv;
- if (*flag == 'p')
- pid_file = *argv;
+ if ((*argv)[0] == '-' && (*argv)[1] == 'p') {
+ pid_file = *(argv + 1);
}
--argc; ++argv;
}
--
1.8.5.5

+ 0
- 111
net/haproxy/patches/0003-BUG-MAJOR-tcp-fix-a-possible-busy-spinning-loop-in-c.patch View File

@ -1,111 +0,0 @@
From f94735eb76e634d7531f9c903113f64820c4cec0 Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 30 Jul 2014 08:56:35 +0200
Subject: [PATCH 3/3] BUG/MAJOR: tcp: fix a possible busy spinning loop in
content track-sc*
As a consequence of various recent changes on the sample conversion,
a corner case has emerged where it is possible to wait forever for a
sample in track-sc*.
The issue is caused by the fact that functions relying on sample_process()
don't all exactly work the same regarding the SMP_F_MAY_CHANGE flag and
the output result. Here it was possible to wait forever for an output
sample from stktable_fetch_key() without checking the SMP_OPT_FINAL flag.
As a result, if the client connects and closes without sending the data
and haproxy expects a sample which is capable of coming, it will ignore
this impossible case and will continue to wait.
This change adds control for SMP_OPT_FINAL before waiting for extra data.
The various relevant functions have been better documented regarding their
output values.
This fix must be backported to 1.5 since it appeared there.
(cherry picked from commit 6bcb0a84e7256f00793fa8ec8a0d6c19c3b22935)
---
src/proto_tcp.c | 4 ++--
src/sample.c | 23 ++++++++++++++++++++++-
src/stick_table.c | 11 ++++++++++-
3 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 9778856..72dc92b 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1048,8 +1048,8 @@ int tcp_inspect_request(struct session *s, struct channel *req, int an_bit)
t = rule->act_prm.trk_ctr.table.t;
key = stktable_fetch_key(t, s->be, s, &s->txn, SMP_OPT_DIR_REQ | partial, rule->act_prm.trk_ctr.expr, &smp);
- if (smp.flags & SMP_F_MAY_CHANGE)
- goto missing_data;
+ if ((smp.flags & SMP_F_MAY_CHANGE) && !(partial & SMP_OPT_FINAL))
+ goto missing_data; /* key might appear later */
if (key && (ts = stktable_get_entry(t, key))) {
session_track_stkctr(&s->stkctr[tcp_trk_idx(rule->action)], t, ts);
diff --git a/src/sample.c b/src/sample.c
index 3a0f3fb..8e62640 100644
--- a/src/sample.c
+++ b/src/sample.c
@@ -896,6 +896,18 @@ out_error:
* Note: the fetch functions are required to properly set the return type. The
* conversion functions must do so too. However the cast functions do not need
* to since they're made to cast mutiple types according to what is required.
+ *
+ * The caller may indicate in <opt> if it considers the result final or not.
+ * The caller needs to check the SMP_F_MAY_CHANGE flag in p->flags to verify
+ * if the result is stable or not, according to the following table :
+ *
+ * return MAY_CHANGE FINAL Meaning for the sample
+ * NULL 0 * Not present and will never be (eg: header)
+ * NULL 1 0 Not present yet, could change (eg: POST param)
+ * NULL 1 1 Not present yet, will not change anymore
+ * smp 0 * Present and will not change (eg: header)
+ * smp 1 0 Present, may change (eg: request length)
+ * smp 1 1 Present, last known value (eg: request length)
*/
struct sample *sample_process(struct proxy *px, struct session *l4, void *l7,
unsigned int opt,
@@ -1153,7 +1165,16 @@ int smp_resolve_args(struct proxy *p)
* and <opt> does not contain SMP_OPT_FINAL, then the sample is returned as-is
* with its SMP_F_MAY_CHANGE flag so that the caller can check it and decide to
* take actions (eg: wait longer). If a sample could not be found or could not
- * be converted, NULL is returned.
+ * be converted, NULL is returned. The caller MUST NOT use the sample if the
+ * SMP_F_MAY_CHANGE flag is present, as it is used only as a hint that there is
+ * still hope to get it after waiting longer, and is not converted to string.
+ * The possible output combinations are the following :
+ *
+ * return MAY_CHANGE FINAL Meaning for the sample
+ * NULL * * Not present and will never be (eg: header)
+ * smp 0 * Final value converted (eg: header)
+ * smp 1 0 Not present yet, may appear later (eg: header)
+ * smp 1 1 never happens (either flag is cleared on output)
*/
struct sample *sample_fetch_string(struct proxy *px, struct session *l4, void *l7,
unsigned int opt, struct sample_expr *expr)
diff --git a/src/stick_table.c b/src/stick_table.c
index a708d3c..d39b4ff 100644
--- a/src/stick_table.c
+++ b/src/stick_table.c
@@ -603,7 +603,16 @@ static sample_to_key_fct sample_to_key[SMP_TYPES][STKTABLE_TYPES] = {
* no key could be extracted, or a pointer to the converted result stored in
* static_table_key in format <table_type>. If <smp> is not NULL, it will be reset
* and its flags will be initialized so that the caller gets a copy of the input
- * sample, and knows why it was not accepted (eg: SMP_F_MAY_CHANGE is present).
+ * sample, and knows why it was not accepted (eg: SMP_F_MAY_CHANGE is present
+ * without SMP_OPT_FINAL). The output will be usable like this :
+ *
+ * return MAY_CHANGE FINAL Meaning for the sample
+ * NULL 0 * Not present and will never be (eg: header)
+ * NULL 1 0 Not present or unstable, could change (eg: req_len)
+ * NULL 1 1 Not present, will not change anymore
+ * smp 0 * Present and will not change (eg: header)
+ * smp 1 0 not possible
+ * smp 1 1 Present, last known value (eg: request length)
*/
struct stktable_key *stktable_fetch_key(struct stktable *t, struct proxy *px, struct session *l4, void *l7,
unsigned int opt, struct sample_expr *expr, struct sample *smp)
--
1.8.5.5

+ 0
- 34
net/haproxy/patches/0004-BUG-config-error-in-http-response-replace-header-num.patch View File

@ -1,34 +0,0 @@
From a772b945d757c25037ac58de64ccc27ceeb4b4a7 Mon Sep 17 00:00:00 2001
From: Baptiste Assmann <bedis9@gmail.com>
Date: Fri, 8 Aug 2014 17:29:06 +0200
Subject: [PATCH 4/4] BUG: config: error in http-response replace-header number
of arguments
A couple of typo fixed in 'http-response replace-header':
- an error when counting the number of arguments
- a typo in the alert message
This should be backported to 1.5.
(cherry picked from commit 12cb00b216d67468b7c4bd84abedcb4ecd1a32bc)
---
src/proto_http.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/proto_http.c b/src/proto_http.c
index b7ed85d..2b75b32 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -9281,8 +9281,8 @@ struct http_res_rule *parse_http_res_cond(const char **args, const char *file, i
cur_arg = 1;
if (!*args[cur_arg] || !*args[cur_arg+1] || !*args[cur_arg+2] ||
- (*args[cur_arg+3] && strcmp(args[cur_arg+2], "if") != 0 && strcmp(args[cur_arg+2], "unless") != 0)) {
- Alert("parsing [%s:%d]: 'http-request %s' expects exactly 3 arguments.\n",
+ (*args[cur_arg+3] && strcmp(args[cur_arg+3], "if") != 0 && strcmp(args[cur_arg+3], "unless") != 0)) {
+ Alert("parsing [%s:%d]: 'http-response %s' expects exactly 3 arguments.\n",
file, linenum, args[0]);
goto out_err;
}
--
1.8.5.5

+ 0
- 45
net/haproxy/patches/0005-BUG-MEDIUM-http-tarpit-timeout-is-reset.patch View File

@ -1,45 +0,0 @@
From fc566b541e4c67cfbd8d6b40b627ce27dfc8a7cb Mon Sep 17 00:00:00 2001
From: Thierry FOURNIER <tfournier@exceliance.fr>
Date: Fri, 22 Aug 2014 06:55:26 +0200
Subject: [PATCH 5/6] BUG/MEDIUM: http: tarpit timeout is reset
Before the commit bbba2a8ecc35daf99317aaff7015c1931779c33b
(1.5-dev24-8), the tarpit section set timeout and return, after this
commit, the tarpit section set the timeout, and go to the "done" label
which reset the timeout.
Thanks Bryan Talbot for the bug report and analysis.
This should be backported in 1.5.
(cherry picked from commit 7566e30477bf5ea4206bda5950d2d83108c4a3dc)
---
src/proto_http.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/proto_http.c b/src/proto_http.c
index 2b75b32..bebc8bf 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -4117,8 +4117,9 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
done: /* done with this analyser, continue with next ones that the calling
* points will have set, if any.
*/
- req->analysers &= ~an_bit;
req->analyse_exp = TICK_ETERNITY;
+ done_without_exp: /* done with this analyser, but dont reset the analyse_exp. */
+ req->analysers &= ~an_bit;
return 1;
tarpit:
@@ -4144,7 +4145,7 @@ int http_process_req_common(struct session *s, struct channel *req, int an_bit,
s->be->be_counters.denied_req++;
if (s->listener->counters)
s->listener->counters->denied_req++;
- goto done;
+ goto done_without_exp;
deny: /* this request was blocked (denied) */
txn->flags |= TX_CLDENY;
--
1.8.5.5

+ 0
- 112
net/haproxy/patches/0006-MEDIUM-connection-add-new-bit-in-Proxy-Protocol-V2.patch View File

@ -1,112 +0,0 @@
From d6ec605d2059191163cad27b7d7b215ed8d3725b Mon Sep 17 00:00:00 2001
From: Dave McCowan <11235david@gmail.com>
Date: Wed, 30 Jul 2014 10:39:13 -0400
Subject: [PATCH 6/6] MEDIUM: connection: add new bit in Proxy Protocol V2
There are two sample commands to get information about the presence of a
client certificate.
ssl_fc_has_crt is true if there is a certificate present in the current
connection
ssl_c_used is true if there is a certificate present in the session.
If a session has stopped and resumed, then ssl_c_used could be true, while
ssl_fc_has_crt is false.
In the client byte of the TLS TLV of Proxy Protocol V2, there is only one
bit to indicate whether a certificate is present on the connection. The
attached patch adds a second bit to indicate the presence for the session.
This maintains backward compatibility.
[wt: this should be backported to 1.5 to help maintain compatibility
between versions]
(cherry picked from commit 328fb58d745c03a0dc706da9e2fcd4e9f860a14b)
---
include/proto/ssl_sock.h | 3 ++-
include/types/connection.h | 5 +++--
src/connection.c | 6 ++++--
src/ssl_sock.c | 21 +++++++++++++++++++--
4 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/include/proto/ssl_sock.h b/include/proto/ssl_sock.h
index 3e111cd..10541ed 100644
--- a/include/proto/ssl_sock.h
+++ b/include/proto/ssl_sock.h
@@ -51,7 +51,8 @@ void ssl_sock_free_all_ctx(struct bind_conf *bind_conf);
const char *ssl_sock_get_cipher_name(struct connection *conn);
const char *ssl_sock_get_proto_version(struct connection *conn);
char *ssl_sock_get_version(struct connection *conn);
-int ssl_sock_get_cert_used(struct connection *conn);
+int ssl_sock_get_cert_used_sess(struct connection *conn);
+int ssl_sock_get_cert_used_conn(struct connection *conn);
int ssl_sock_get_remote_common_name(struct connection *conn, struct chunk *out);
unsigned int ssl_sock_get_verify_result(struct connection *conn);
#ifdef SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB
diff --git a/include/types/connection.h b/include/types/connection.h
index 2ae16d7..b317007 100644
--- a/include/types/connection.h
+++ b/include/types/connection.h
@@ -345,8 +345,9 @@ struct tlv_ssl {
uint8_t sub_tlv[0];
}__attribute__((packed));
-#define PP2_CLIENT_SSL 0x01
-#define PP2_CLIENT_CERT 0x02
+#define PP2_CLIENT_SSL 0x01
+#define PP2_CLIENT_CERT_CONN 0x02
+#define PP2_CLIENT_CERT_SESS 0x04
#endif /* _TYPES_CONNECTION_H */
diff --git a/src/connection.c b/src/connection.c
index 2dd2c02..3af6d9a 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -678,9 +678,11 @@ int make_proxy_line_v2(char *buf, int buf_len, struct server *srv, struct connec
tlv_len = make_tlv(&buf[ret+ssl_tlv_len], (buf_len-ret-ssl_tlv_len), PP2_TYPE_SSL_VERSION, strlen(value), value);
ssl_tlv_len += tlv_len;
}
- if (ssl_sock_get_cert_used(remote)) {
- tlv->client |= PP2_CLIENT_CERT;
+ if (ssl_sock_get_cert_used_sess(remote)) {
+ tlv->client |= PP2_CLIENT_CERT_SESS;
tlv->verify = htonl(ssl_sock_get_verify_result(remote));
+ if (ssl_sock_get_cert_used_conn(remote))
+ tlv->client |= PP2_CLIENT_CERT_CONN;
}
if (srv->pp_opts & SRV_PP_V2_SSL_CN) {
cn_trash = get_trash_chunk();
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index cf8adc7..da99a30 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -2720,8 +2720,25 @@ out:
return result;
}
-/* returns 1 if client passed a certificate, 0 if not */
-int ssl_sock_get_cert_used(struct connection *conn)
+/* returns 1 if client passed a certificate for this session, 0 if not */
+int ssl_sock_get_cert_used_sess(struct connection *conn)
+{
+ X509 *crt = NULL;
+
+ if (!ssl_sock_is_ssl(conn))
+ return 0;
+
+ /* SSL_get_peer_certificate, it increase X509 * ref count */
+ crt = SSL_get_peer_certificate(conn->xprt_ctx);
+ if (!crt)
+ return 0;
+
+ X509_free(crt);
+ return 1;
+}
+
+/* returns 1 if client passed a certificate for this connection, 0 if not */
+int ssl_sock_get_cert_used_conn(struct connection *conn)
{
if (!ssl_sock_is_ssl(conn))
return 0;
--
1.8.5.5

Loading…
Cancel
Save