haproxy: Update HAProxy to v2.0.10 10655/head
authorChristian Lachner <gladiac@gmail.com>
Thu, 28 Nov 2019 06:51:55 +0000 (07:51 +0100)
committerChristian Lachner <gladiac@gmail.com>
Fri, 29 Nov 2019 11:25:21 +0000 (12:25 +0100)
- Update haproxy download URL and hash
- Add new patches (see https://www.haproxy.org/bugs/bugs-2.0.10.html)
- This fixes CVE-2019-19330 (See: https://nvd.nist.gov/vuln/detail/CVE-2019-19330)

Signed-off-by: Christian Lachner <gladiac@gmail.com>
net/haproxy/Makefile
net/haproxy/get-latest-patches.sh
net/haproxy/patches/000-BUG-MINOR-stream-init-variables-when-the-list-is-empty.patch [new file with mode: 0644]
net/haproxy/patches/000-OPENWRT-add-uclibc-support.patch [deleted file]
net/haproxy/patches/001-BUG-MINOR-contrib-prometheus-exporter-Use-HTX-errors-and-not-legacy-ones.patch [new file with mode: 0644]
net/haproxy/patches/001-OPENWRT-openssl-deprecated.patch [deleted file]
net/haproxy/patches/002-BUG-MINOR-contrib-prometheus-exporter-decode-parameter-and-value-only.patch [new file with mode: 0644]
net/haproxy/patches/003-OPENWRT-add-uclibc-support.patch [new file with mode: 0644]
net/haproxy/patches/004-OPENWRT-openssl-deprecated.patch [new file with mode: 0644]

index 01a3eb9697822491890fb21a3818aa40336ceb69..a9e9d57c73b6c7e0510e7bb96bd7e73b7a60ce10 100644 (file)
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=haproxy
-PKG_VERSION:=2.0.9
+PKG_VERSION:=2.0.10
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://www.haproxy.org/download/2.0/src
-PKG_HASH:=35692801abfd6dde4976cb42fe5cee8aaf61959e743003426073c3141494c589
+PKG_HASH:=1d38ab3dd45e930b209e922a360ee8c636103e21e5b5a2656d3795401316a4ea
 
 PKG_MAINTAINER:=Thomas Heil <heil@terminal-consulting.de>, \
                Christian Lachner <gladiac@gmail.com>
index 0fd06d941bd506375f19d7e06672c4c9dc90ac80..5380be1523f31204086e572ad7c496c1d6d4e61d 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 CLONEURL=https://git.haproxy.org/git/haproxy-2.0.git
-BASE_TAG=v2.0.9
+BASE_TAG=v2.0.10
 TMP_REPODIR=tmprepo
 PATCHESDIR=patches
 
diff --git a/net/haproxy/patches/000-BUG-MINOR-stream-init-variables-when-the-list-is-empty.patch b/net/haproxy/patches/000-BUG-MINOR-stream-init-variables-when-the-list-is-empty.patch
new file mode 100644 (file)
index 0000000..5529ea2
--- /dev/null
@@ -0,0 +1,72 @@
+commit 54948f3fd310ffc74a6c252dc11046a8a18ab230
+Author: Jerome Magnin <jmagnin@haproxy.com>
+Date:   Sat Nov 9 18:00:47 2019 +0100
+
+    BUG/MINOR: stream: init variables when the list is empty
+    
+    We need to call vars_init() when the list is empty otherwise we
+    can't use variables in the response scope. This regression was
+    introduced by cda7f3f5 (MINOR: stream: don't prune variables if
+    the list is empty).
+    
+    The following config reproduces the issue:
+    
+     defaults
+       mode http
+    
+     frontend in
+       bind *:11223
+       http-request set-var(req.foo) str("foo")  if { path /bar }
+       http-request set-header bar %[var(req.foo)]  if { var(req.foo) -m found }
+       http-response set-var(res.bar) str("bar")
+       http-response set-header foo %[var(res.bar)] if { var(res.bar) -m found }
+       use_backend out
+    
+     backend out
+       server s1 127.0.0.1:11224
+    
+     listen back
+       bind *:11224
+       http-request deny deny_status 200
+    
+     > GET /ba HTTP/1.1
+     > Host: localhost:11223
+     > User-Agent: curl/7.66.0
+     > Accept: */*
+     >
+     < HTTP/1.0 200 OK
+     < Cache-Control: no-cache
+     < Content-Type: text/html
+    
+     > GET /bar HTTP/1.1
+     > Host: localhost:11223
+     > User-Agent: curl/7.66.0
+     > Accept: */*
+     >
+     < HTTP/1.0 200 OK
+     < Cache-Control: no-cache
+     < Content-Type: text/html
+     < foo: bar
+    
+    This must be backported as far as 1.9.
+    
+    (cherry picked from commit 2f44e8843a553ef0f9c53c9b27899727de097777)
+    Signed-off-by: Willy Tarreau <w@1wt.eu>
+
+diff --git a/src/stream.c b/src/stream.c
+index 4a7ced22..9fe0efaf 100644
+--- a/src/stream.c
++++ b/src/stream.c
+@@ -2399,10 +2399,9 @@ struct task *process_stream(struct task *t, void *context, unsigned short state)
+       if (si_state_in(si_b->state, SI_SB_REQ|SI_SB_QUE|SI_SB_TAR|SI_SB_ASS)) {
+               /* prune the request variables and swap to the response variables. */
+               if (s->vars_reqres.scope != SCOPE_RES) {
+-                      if (!LIST_ISEMPTY(&s->vars_reqres.head)) {
++                      if (!LIST_ISEMPTY(&s->vars_reqres.head))
+                               vars_prune(&s->vars_reqres, s->sess, s);
+-                              vars_init(&s->vars_reqres, SCOPE_RES);
+-                      }
++                      vars_init(&s->vars_reqres, SCOPE_RES);
+               }
+               do {
diff --git a/net/haproxy/patches/000-OPENWRT-add-uclibc-support.patch b/net/haproxy/patches/000-OPENWRT-add-uclibc-support.patch
deleted file mode 100644 (file)
index 2757025..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -327,6 +327,15 @@ ifeq ($(TARGET),linux-glibc)
-     USE_GETADDRINFO)
- endif
-+# For linux >= 2.6.28 and uclibc
-+ifeq ($(TARGET),linux-uclibc)
-+  set_target_defaults = $(call default_opts, \
-+    USE_POLL USE_TPROXY USE_DL USE_RT USE_NETFILTER                           \
-+    USE_CPU_AFFINITY USE_THREAD USE_EPOLL USE_FUTEX USE_LINUX_TPROXY          \
-+    USE_ACCEPT4 USE_LINUX_SPLICE USE_PRCTL USE_THREAD_DUMP USE_NS USE_TFO     \
-+    USE_GETADDRINFO)
-+endif
-+
- # Solaris 8 and above
- ifeq ($(TARGET),solaris)
-   # We also enable getaddrinfo() which works since solaris 8.
diff --git a/net/haproxy/patches/001-BUG-MINOR-contrib-prometheus-exporter-Use-HTX-errors-and-not-legacy-ones.patch b/net/haproxy/patches/001-BUG-MINOR-contrib-prometheus-exporter-Use-HTX-errors-and-not-legacy-ones.patch
new file mode 100644 (file)
index 0000000..e7dfba0
--- /dev/null
@@ -0,0 +1,29 @@
+commit 3a00e5fcc1af121dea16793d47627c16c97fb953
+Author: Christopher Faulet <cfaulet@haproxy.com>
+Date:   Wed Nov 27 11:22:37 2019 +0100
+
+    BUG/MINOR: contrib/prometheus-exporter: Use HTX errors and not legacy ones
+    
+    This bug was introduced when the commit 32d634f1 ("MINOR:
+    contrib/prometheus-exporter: filter exported metrics by scope") was backported
+    to 2.0.
+    
+    In 2.0, Error chunks exist in raw format (http_err_chunks[]) and in HTX format
+    (htx_err_chunks[]). Prometheus exported only supports the HTX. So error must not
+    be reported using the raw chunks.
+    
+    This fix is specific to 2.0. No backport needed.
+
+diff --git a/contrib/prometheus-exporter/service-prometheus.c b/contrib/prometheus-exporter/service-prometheus.c
+index 56d49a39..cfbfb8c3 100644
+--- a/contrib/prometheus-exporter/service-prometheus.c
++++ b/contrib/prometheus-exporter/service-prometheus.c
+@@ -2292,7 +2292,7 @@ static int promex_parse_uri(struct appctx *appctx, struct stream_interface *si)
+       return 1;
+   error:
+-      err = &http_err_chunks[HTTP_ERR_400];
++      err = &htx_err_chunks[HTTP_ERR_400];
+       channel_erase(res);
+       res->buf.data = b_data(err);
+       memcpy(res->buf.area, b_head(err), b_data(err));
diff --git a/net/haproxy/patches/001-OPENWRT-openssl-deprecated.patch b/net/haproxy/patches/001-OPENWRT-openssl-deprecated.patch
deleted file mode 100644 (file)
index 541077e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/include/common/openssl-compat.h
-+++ b/include/common/openssl-compat.h
-@@ -217,7 +217,8 @@ static inline int EVP_PKEY_base_id(EVP_PKEY *pkey)
- #define TLSEXT_signature_ecdsa      3
- #endif
--#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (LIBRESSL_VERSION_NUMBER < 0x20700000L)
-+#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
-+      (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x20700000L))
- #define X509_getm_notBefore     X509_get_notBefore
- #define X509_getm_notAfter      X509_get_notAfter
- #endif
diff --git a/net/haproxy/patches/002-BUG-MINOR-contrib-prometheus-exporter-decode-parameter-and-value-only.patch b/net/haproxy/patches/002-BUG-MINOR-contrib-prometheus-exporter-decode-parameter-and-value-only.patch
new file mode 100644 (file)
index 0000000..7bc5f2c
--- /dev/null
@@ -0,0 +1,142 @@
+commit 200c6215fe9c592d576f52d4a79627381ed6aa7f
+Author: William Dauchy <w.dauchy@criteo.com>
+Date:   Tue Nov 26 12:56:26 2019 +0100
+
+    BUG/MINOR: contrib/prometheus-exporter: decode parameter and value only
+    
+    we were decoding all substring and then parsing; this could lead to
+    consider & and = in decoding result as delimiters where it should not.
+    this patch reverses the order by first parsing and then decoding each key
+    and value separately.
+    
+    we also stop parsing after number sign (#).
+    
+    This patch should be backported to 2.1 and 2.0
+    
+    Signed-off-by: William Dauchy <w.dauchy@criteo.com>
+    (cherry picked from commit c65f656d75091db3087a752dbc956159392fc8f2)
+    Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
+    (cherry picked from commit 8ec21c5fef89f13fea2ac9be55d55215d4b9104a)
+    Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
+
+diff --git a/contrib/prometheus-exporter/service-prometheus.c b/contrib/prometheus-exporter/service-prometheus.c
+index cfbfb8c3..c34ee0e1 100644
+--- a/contrib/prometheus-exporter/service-prometheus.c
++++ b/contrib/prometheus-exporter/service-prometheus.c
+@@ -2220,7 +2220,8 @@ static int promex_parse_uri(struct appctx *appctx, struct stream_interface *si)
+       struct channel *res = si_ic(si);
+       struct htx *req_htx, *res_htx;
+       struct htx_sl *sl;
+-      const char *p, *end;
++      char *p, *key, *value;
++      const char *end;
+       struct buffer *err;
+       int default_scopes = PROMEX_FL_SCOPE_ALL;
+       int len;
+@@ -2234,57 +2235,72 @@ static int promex_parse_uri(struct appctx *appctx, struct stream_interface *si)
+       if (!p)
+               goto end;
+       end = HTX_SL_REQ_UPTR(sl) + HTX_SL_REQ_ULEN(sl);
+-      len = end-p;
+-      /* Decode the query-string */
++      /* copy the query-string */
++      len = end - p;
+       chunk_reset(&trash);
+       memcpy(trash.area, p, len);
+       trash.area[len] = 0;
+-      len = url_decode(trash.area);
+-      if (len == -1)
+-              goto error;
+       p = trash.area;
+-      end = p + len;
++      end = trash.area + len;
+       /* Parse the query-string */
+-      while (p < end) {
+-              if (*p == '&')
++      while (p < end && *p && *p != '#') {
++              value = NULL;
++
++              /* decode parameter name */
++              key = p;
++              while (p < end && *p != '=' && *p != '&' && *p != '#')
+                       ++p;
+-              else if (*p == 's' && (end-p) >= 6 && !memcmp(p, "scope=", 6)) {
+-                      default_scopes = 0; /* at least a scope defined, unset default scopes */
+-                      p += 6;             /* now p point on the parameter value */
+-                      len = 0;            /* len is the value length */
+-                      while ((p+len) < end && *(p+len) != '&')
+-                              ++len;
++              /* found a value */
++              if (*p == '=') {
++                      *(p++) = 0;
++                      value = p;
++              }
++              else if (*p == '&')
++                      *(p++) = 0;
++              else if (*p == '#')
++                      *p = 0;
++              len = url_decode(key);
++              if (len == -1)
++                      goto error;
++
++              /* decode value */
++              if (value) {
++                      while (p < end && *p != '=' && *p != '&' && *p != '#')
++                              ++p;
++                      if (*p == '=')
++                              goto error;
++                      if (*p == '&')
++                              *(p++) = 0;
++                      else if (*p == '#')
++                              *p = 0;
++                      len = url_decode(value);
++                      if (len == -1)
++                              goto error;
++              }
+-                      if (len == 0)
++              if (!strcmp(key, "scope")) {
++                      default_scopes = 0; /* at least a scope defined, unset default scopes */
++                      if (!value)
++                              goto error;
++                      else if (*value == 0)
+                               appctx->ctx.stats.flags &= ~PROMEX_FL_SCOPE_ALL;
+-                      else if (len == 1 && *p == '*')
++                      else if (*value == '*')
+                               appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_ALL;
+-                      else if (len == 6) {
+-                              if (!memcmp(p, "global", len))
+-                                      appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_GLOBAL;
+-                              else if (!memcmp(p, "server", len))
+-                                      appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_SERVER;
+-                      }
+-                      else if (len == 7 && !memcmp(p, "backend", len))
++                      else if (!strcmp(value, "global"))
++                              appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_GLOBAL;
++                      else if (!strcmp(value, "server"))
++                              appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_SERVER;
++                      else if (!strcmp(value, "backend"))
+                               appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_BACK;
+-                      else if (len == 8 && !memcmp(p, "frontend", len))
++                      else if (!strcmp(value, "frontend"))
+                               appctx->ctx.stats.flags |= PROMEX_FL_SCOPE_FRONT;
+                       else
+                               goto error;
+-
+-                      p += len;
+               }
+-              else if (*p == 'n' && (end-p) >= 8 && !memcmp(p, "no-maint", 8)) {
++              else if (!strcmp(key, "no-maint"))
+                       appctx->ctx.stats.flags |= PROMEX_FL_NO_MAINT_SRV;
+-                      p += 8;
+-              }
+-              else {
+-                      /* ignore all other params for now */
+-                      while (p < end && *p != '&')
+-                              p++;
+-              }
+       }
+   end:
diff --git a/net/haproxy/patches/003-OPENWRT-add-uclibc-support.patch b/net/haproxy/patches/003-OPENWRT-add-uclibc-support.patch
new file mode 100644 (file)
index 0000000..2757025
--- /dev/null
@@ -0,0 +1,18 @@
+--- a/Makefile
++++ b/Makefile
+@@ -327,6 +327,15 @@ ifeq ($(TARGET),linux-glibc)
+     USE_GETADDRINFO)
+ endif
++# For linux >= 2.6.28 and uclibc
++ifeq ($(TARGET),linux-uclibc)
++  set_target_defaults = $(call default_opts, \
++    USE_POLL USE_TPROXY USE_DL USE_RT USE_NETFILTER                           \
++    USE_CPU_AFFINITY USE_THREAD USE_EPOLL USE_FUTEX USE_LINUX_TPROXY          \
++    USE_ACCEPT4 USE_LINUX_SPLICE USE_PRCTL USE_THREAD_DUMP USE_NS USE_TFO     \
++    USE_GETADDRINFO)
++endif
++
+ # Solaris 8 and above
+ ifeq ($(TARGET),solaris)
+   # We also enable getaddrinfo() which works since solaris 8.
diff --git a/net/haproxy/patches/004-OPENWRT-openssl-deprecated.patch b/net/haproxy/patches/004-OPENWRT-openssl-deprecated.patch
new file mode 100644 (file)
index 0000000..541077e
--- /dev/null
@@ -0,0 +1,12 @@
+--- a/include/common/openssl-compat.h
++++ b/include/common/openssl-compat.h
+@@ -217,7 +217,8 @@ static inline int EVP_PKEY_base_id(EVP_PKEY *pkey)
+ #define TLSEXT_signature_ecdsa      3
+ #endif
+-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || (LIBRESSL_VERSION_NUMBER < 0x20700000L)
++#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
++      (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER < 0x20700000L))
+ #define X509_getm_notBefore     X509_get_notBefore
+ #define X509_getm_notAfter      X509_get_notAfter
+ #endif