diff -Nru haproxy-2.4.18/addons/promex/README haproxy-2.4.22/addons/promex/README --- haproxy-2.4.18/addons/promex/README 2022-07-27 13:10:44.000000000 +0000 +++ haproxy-2.4.22/addons/promex/README 2023-02-14 15:57:13.000000000 +0000 @@ -286,6 +286,8 @@ | haproxy_backend_max_total_time_seconds | | haproxy_backend_internal_errors_total | | haproxy_backend_uweight | +| haproxy_backend_agg_server_status | +| haproxy_backend_agg_check_status | +-----------------------------------------------------+ * Server metrics diff -Nru haproxy-2.4.18/addons/promex/service-prometheus.c haproxy-2.4.22/addons/promex/service-prometheus.c --- haproxy-2.4.18/addons/promex/service-prometheus.c 2022-07-27 13:10:44.000000000 +0000 +++ haproxy-2.4.22/addons/promex/service-prometheus.c 2023-02-14 15:57:13.000000000 +0000 @@ -289,6 +289,8 @@ [ST_F_NEED_CONN_EST] = { .n = IST("need_connections_current"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_SRV_METRIC) }, [ST_F_UWEIGHT] = { .n = IST("uweight"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) }, [ST_F_AGG_SRV_CHECK_STATUS] = { .n = IST("agg_server_check_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, + [ST_F_AGG_SRV_STATUS ] = { .n = IST("agg_server_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, + [ST_F_AGG_CHECK_STATUS] = { .n = IST("agg_check_status"), .type = PROMEX_MT_GAUGE, .flags = ( PROMEX_FL_BACK_METRIC ) }, }; /* Description of overridden stats fields */ @@ -792,6 +794,7 @@ double secs; enum promex_back_state bkd_state; enum promex_srv_state srv_state; + enum healthcheck_status srv_check_status; for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) { if (!(promex_st_metrics[appctx->st2].flags & appctx->ctx.stats.flags)) @@ -800,6 +803,8 @@ while (appctx->ctx.stats.obj1) { struct promex_label labels[PROMEX_MAX_LABELS-1] = {}; unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = { 0 }; + unsigned int srv_check_count[HCHK_STATUS_SIZE] = { 0 }; + const char *check_state; px = appctx->ctx.stats.obj1; @@ -814,7 +819,8 @@ return -1; switch (appctx->st2) { - case ST_F_AGG_SRV_CHECK_STATUS: + case ST_F_AGG_SRV_CHECK_STATUS: // DEPRECATED + case ST_F_AGG_SRV_STATUS: if (!px->srv) goto next_px; sv = px->srv; @@ -833,6 +839,28 @@ } appctx->ctx.stats.st_code = 0; goto next_px; + case ST_F_AGG_CHECK_STATUS: + if (!px->srv) + goto next_px; + sv = px->srv; + while (sv) { + srv_check_status = sv->check.status; + srv_check_count[srv_check_status] += 1; + sv = sv->next; + } + for (; appctx->ctx.stats.st_code < HCHK_STATUS_SIZE; appctx->ctx.stats.st_code++) { + if (get_check_status_result(appctx->ctx.stats.st_code) < CHK_RES_FAILED) + continue; + val = mkf_u32(FO_STATUS, srv_check_count[appctx->ctx.stats.st_code]); + check_state = get_check_status_info(appctx->ctx.stats.st_code); + labels[1].name = ist("state"); + labels[1].value = ist(check_state); + if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2], + &val, labels, &out, max)) + goto full; + } + appctx->ctx.stats.st_code = 0; + goto next_px; case ST_F_STATUS: bkd_state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0); for (; appctx->ctx.stats.st_code < PROMEX_BACK_STATE_COUNT; appctx->ctx.stats.st_code++) { @@ -1547,6 +1575,7 @@ res->flags |= CF_READ_NULL; si_shutr(si); si_shutw(si); + goto out; } struct applet promex_applet = { diff -Nru haproxy-2.4.18/addons/wurfl/dummy/wurfl/wurfl.h haproxy-2.4.22/addons/wurfl/dummy/wurfl/wurfl.h --- haproxy-2.4.18/addons/wurfl/dummy/wurfl/wurfl.h 2022-07-27 13:10:44.000000000 +0000 +++ haproxy-2.4.22/addons/wurfl/dummy/wurfl/wurfl.h 2023-02-14 15:57:13.000000000 +0000 @@ -4,11 +4,16 @@ * Copyright (c) ScientiaMobile, Inc. * http://www.scientiamobile.com * - * This software package is the property of ScientiaMobile Inc. and is licensed - * commercially according to a contract between the Licensee and ScientiaMobile Inc. (Licensor). - * If you represent the Licensee, please refer to the licensing agreement which has been signed - * between the two parties. If you do not represent the Licensee, you are not authorized to use - * this software in any way. + * This software package is the property of ScientiaMobile Inc. and is distributed under + * a dual licensing scheme: + * + * 1) commercially according to a contract between the Licensee and ScientiaMobile Inc. (Licensor). + * If you represent the Licensee, please refer to the licensing agreement which has been signed + * between the two parties. If you do not represent the Licensee, you are not authorized to use + * this software in any way. + * + * 2) LGPL when used in the context of the HAProxy project with the purpose of testing compatibility + * of HAProxy with ScientiaMobile software. * */ diff -Nru haproxy-2.4.18/CHANGELOG haproxy-2.4.22/CHANGELOG --- haproxy-2.4.18/CHANGELOG 2022-07-27 13:10:44.000000000 +0000 +++ haproxy-2.4.22/CHANGELOG 2023-02-14 15:57:13.000000000 +0000 @@ -1,6 +1,196 @@ ChangeLog : =========== +2023/02/14 : 2.4.22 + - BUG/MINOR: fcgi-app: prevent 'use-fcgi-app' in default section + - BUG/MEDIUM: ssl: wrong eviction from the session cache tree + - BUG/MINOR: ssl/crt-list: warn when a line is malformated + - BUG/MEDIUM: stick-table: do not leave entries in end of window during purge + - BUG/MEDIUM: cache: use the correct time reference when comparing dates + - DOC: config: fix option spop-check proxy compatibility + - DOC: config: 'http-send-name-header' option may be used in default section + - DOC: proxy-protocol: fix wrong byte in provided example + - BUG/MEDIUM: stconn: Schedule a shutw on shutr if data must be sent first + - CI: github: don't warn on deprecated openssl functions on windows + - BUG/CRITICAL: http: properly reject empty http header field names + +2023/01/27 : 2.4.21 + - BUG/MINOR: http-htx: Don't consider an URI as normalized after a set-uri action + - BUG/MEDIIM: stconn: Flush output data before forwarding close to write side + - CI: github: change "ubuntu-latest" to "ubuntu-20.04" + - BUILD: peers: peers-t.h depends on stick-table-t.h + - BUG/MINOR: resolvers: Don't wait periodic resolution on healthcheck failure + - BUG/MEDIUM: ssl: Verify error codes can exceed 63 + - BUG/MINOR: ssl: Fix potential overflow + - BUG/MEDIUM: mworker: fix segv in early failure of mworker mode with peers + - BUG/MINOR: promex: create haproxy_backend_agg_server_status + - MINOR: promex: introduce haproxy_backend_agg_check_status + - DOC: promex: Add missing backend metrics + - BUG/MAJOR: fcgi: Fix uninitialized reserved bytes + - REGTESTS: fix the race conditions in iff.vtc + - REGTESTS: startup: check maxconn computation + - BUG/MEDIUM: resolvers: Use tick_first() to update the resolvers task timeout + - LICENSE: wurfl: clarify the dummy library license. + - BUG/MINOR: ssl: Fix memory leak of find_chain in ssl_sock_load_cert_chain + - BUG/MEDIUM: mux-h2: Refuse interim responses with end-stream flag set + - BUG/MINOR: pool/stats: Use ullong to report total pool usage in bytes in stats + - BUILD: makefile: build the features list dynamically + - BUILD: makefile: sort the features list + - BUG/MINOR: http-fetch: Only fill txn status during prefetch if not already set + - BUG/MAJOR: buf: Fix copy of wrapping output data when a buffer is realigned + - REGTEST: fix the race conditions in json_query.vtc + - REGTEST: fix the race conditions in digest.vtc + - REGTEST: fix the race conditions in hmac.vtc + - BUG/MINOR: http: Memory leak of http redirect rules' format string + - CLEANUP: htx: fix a typo in an error message of http_str_to_htx + - BUG/MINOR: h1-htx: Remove flags about protocol upgrade on non-101 responses + - BUG/MINOR: resolvers: Wait the resolution execution for a do_resolv action + - BUG/MINOR: promex: Don't forget to consume the request on error + - BUG/MINOR: http-ana: Report SF_FINST_R flag on error waiting the request body + - BUG/MINOR: http-fetch: Don't block HTTP sample fetch eval in HTTP_MSG_ERROR state + - BUG/MINOR: http-ana: make set-status also update txn->status + - BUG/MINOR: listeners: fix suspend/resume of inherited FDs + - DOC: config: fix wrong section number for "protocol prefixes" + - DOC: config: fix aliases for protocol prefixes "udp4@" and "udp6@" + - BUG/MINOR: mux-fcgi: Correctly set pathinfo + - DOC: config: fix "Address formats" chapter syntax + - BUG/MINOR: listener: close tiny race between resume_listener() and stopping + - BUG/MINOR: mux-h2: add missing traces on failed headers decoding + - BUILD: hpack: include global.h for the trash that is needed in debug mode + - BUG/MINOR: sink: free the forwarding task on exit + +2022/12/09 : 2.4.20 + - BUG/MINOR: checks: update pgsql regex on auth packet + - DOC: config: Fix pgsql-check documentation to make user param mandatory + - BUG/MEDIUM: lua: Don't crash in hlua_lua2arg_check on failure + - BUG/MEDIUM: lua: handle stick table implicit arguments right. + - BUILD: h1: silence an initiialized warning with gcc-4.7 and -Os + - BUG/MINOR: http-fetch: Update method after a prefetch in smp_fetch_meth() + - BUILD: http_fetch: silence an uninitiialized warning with gcc-4/5/6 at -Os + - BUG/MINOR: mux-h1: Account consumed output data on synchronous connection error + - MINOR: smtpchk: Update expect rule to fully match replies to EHLO commands + - BUG/MINOR: smtpchk: SMTP Service check should gracefully close SMTP transaction + - BUG/MINOR: backend: only enforce turn-around state when not redispatching + - DOC: configuration: missing 'if' in tcp-request content example + - BUG/MAJOR: stick-tables: do not try to index a server name for applets + - BUG/MINOR: server: make sure "show servers state" hides private bits + - CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in matrix.py + - CI: Replace the deprecated `::set-output` command by writing to $GITHUB_OUTPUT in workflow definition + - BUG/MINOR: log: Preserve message facility when the log target is a ring buffer + - BUG/MINOR: ring: Properly parse connect timeout + - BUG/MEDIUM: compression: handle rewrite errors when updating response headers + - BUG/MINOR: sink: Only use backend capability for the sink proxies + - BUG/MINOR: sink: Set default connect/server timeout for implicit ring buffers + - CI: SSL: use proper version generating when "latest" semantic is used + - CI: SSL: temporarily stick to LibreSSL=3.5.3 + - BUG/MINOR: stick-table: Use server_id instead of std_t_sint in process_store_rules() + - DOC: management: add forgotten "show startup-logs" + - BUG/MAJOR: stick-table: don't process store-response rules for applets + - BUG/MEDIUM: stick-table: fix a race condition when updating the expiration task + - BUG/MINOR: log: fixing bug in tcp syslog_io_handler Octet-Counting + - CI: add monthly gcc cross compile jobs + - BUG/MINOR: ssl: Memory leak of AUTHORITY_KEYID struct when loading issuer + - BUG/MINOR: ssl: ocsp structure not freed properly in case of error + - CI: switch to the "latest" LibreSSL + - CI: emit the compiler's version in the build reports + - BUG/MEDIUM: wdt/clock: properly handle early task hangs + - BUG/MINOR: http-htx: Fix error handling during parsing http replies + - BUG/MINOR: resolvers: Set port before IP address when processing SRV records + - BUG/MINOR: mux-fcgi: Be sure to send empty STDING record in case of zero-copy + - BUG/MEDIUM: mux-fcgi: Avoid value length overflow when it doesn't fit at once + - BUG/MINOR: mux-h1: Do not send a last null chunk on body-less answers + - REG-TESTS: cache: Remove T-E header for 304-Not-Modified responses + - DOC: config: fix alphabetical ordering of global section + - BUG/MEDIUM: ring: fix creation of server in uninitialized ring + - BUG/MINOR: pool/cli: use ullong to report total pool usage in bytes + - BUG/MEDIUM: listener: Fix race condition when updating the global mngmt task + - BUG/MINOR: http_ana/txn: don't re-initialize txn and req var lists + - BUG/MINOR: ssl: don't initialize the keylog callback when not required + - BUG/MEDIUM: peers: messages about unkown tables not correctly ignored + - BUILD: peers: Remove unused variables + - BUG/MINOR: server/idle: at least use atomic stores when updating max_used_conns + - BUILD: listener: fix build warning on global_listener_rwlock without threads + - BUG/MINOR: cfgparse-listen: fix ebpt_next_dup pointer dereference on proxy "from" inheritance + - BUG/MINOR: log: fix parse_log_message rfc5424 size check + - BUG/MINOR: http-htx: Don't consider an URI as normalized after a set-uri action + - BUILD: http-htx: Silent build error about a possible NULL start-line + - BUG/MINOR: mux-h1: Fix handling of 408-Request-Time-Out + - Revert "BUG/MINOR: http-htx: Don't consider an URI as normalized after a set-uri action" + - DOC: config: provide some configuration hints for "http-reuse" + - DOC: config: clarify the fact that SNI should not be used in HTTP scenarios + - DOC: config: mention that a single monitor-uri rule is supported + - DOC: config: explain how default matching method for ACL works + - DOC: config: clarify the fact that "retries" is not just for connections + - DOC: config: clarify the -m dir and -m dom pattern matching methods + - SCRIPTS: announce-release: add a link to the data plane API + - Revert "CI: switch to the "latest" LibreSSL" + - Revert "CI: determine actual OpenSSL version dynamically" + +2022/09/28 : 2.4.19 + - BUG/MEDIUM: mworker: use default maxconn in wait mode + - MINOR: http: Add function to get port part of a host + - MINOR: http: Add function to detect default port + - BUG/MEDIUM: h1: Improve authority validation for CONNCET request + - MINOR: http-htx: Use new HTTP functions for the scheme based normalization + - MINOR: ebtree: add ebmb_lookup_shorter() to pursue lookups + - BUG/MEDIUM: pattern: only visit equivalent nodes when skipping versions + - MINOR: peers: Use a dedicated reconnect timeout when stopping the local peer + - BUG/MEDIUM: peers: limit reconnect attempts of the old process on reload + - BUG/MINOR: peers: Use right channel flag to consider the peer as connected + - BUG/MEDIUM: dns: Properly initialize new DNS session + - MINOR: server: Constify source server to copy its settings + - REORG: server: Export srv_settings_cpy() function + - BUG/MEDIUM: proxy: Perform a custom copy for default server settings + - BUG/MINOR: ring/cli: fix a race condition between the writer and the reader + - BUG/MINOR: sink: fix a race condition between the writer and the reader + - BUILD: cfgparse: always defined _GNU_SOURCE for sched.h and crypt.h + - BUG/MEDIUM: poller: use fd_delete() to release the poller pipes + - BUG/MEDIUM: task: relax one thread consistency check in task_unlink_wq() + - BUILD: debug: silence warning on gcc-5 + - BUG/MEDIUM: ring: fix too lax 'size' parser + - BUILD: http: silence an uninitialized warning affecting gcc-5 + - BUG/MEDIUM: http-ana: fix crash or wrong header deletion by http-restrict-req-hdr-names + - BUG/MEDIUM: mux-h2: do not fiddle with ->dsi to indicate demux is idle + - BUG/MAJOR: log-forward: Fix log-forward proxies not fully initialized + - BUG/MAJOR: mworker: fix infinite loop on master with no proxies. + - BUG/MINOR: resolvers: return the correct value in resolvers_finalize_config() + - BUG/MINOR: tcpcheck: Disable QUICKACK only if data should be sent after connect + - REGTESTS: Fix prometheus script to perform HTTP health-checks + - DOC: configuration: do-resolve doesn't work with a port in the string + - BUG/MEDIUM: spoe: Properly update streams waiting for a ACK in async mode + - BUG/MEDIUM: peers: Add connect and server timeut to peers proxy + - BUG/MEDIUM: peers: Don't use resync timer when local resync is in progress + - BUG/MEDIUM: peers: Don't start resync on reload if local peer is not up-to-date + - BUG/MINOR: hlua: Rely on CF_EOI to detect end of message in HTTP applets + - BUG/MINOR: tcpcheck: Disable QUICKACK for default tcp-check (with no rule) + - BUG/MEDIUM: mux-h1: do not refrain from signaling errors after end of input + - REGTESTS: http_request_buffer: Add a barrier to not mix up log messages + - BUG/MEDIUM: mux-h1: always use RST to kill idle connections in pools + - BUG/MINOR: mux-h2: fix the "show fd" dest buffer for the subscriber + - BUG/MINOR: mux-h1: fix the "show fd" dest buffer for the subscriber + - BUG/MINOR: mux-fcgi: fix the "show fd" dest buffer for the subscriber + - BUG/MINOR: regex: Properly handle PCRE2 lib compiled without JIT support + - BUILD: makefile: enable crypt(3) for NetBSD + - BUG/MINOR: h1: Support headers case adjustment for TCP proxies + - BUG/MINOR: task: always reset a new tasklet's call date + - BUG/MINOR: signals/poller: set the poller timeout to 0 when there are signals + - BUG/MINOR: signals/poller: ensure wakeup from signals + - CI: cirrus-ci: bump FreeBSD image to 13-1 + - BUG/MEDIUM: proxy: ensure pause_proxy() and resume_proxy() own PROXY_LOCK + - MINOR: listener: small API change + - BUG/MINOR: stats: fixing stat shows disabled frontend status as 'OPEN' + - REGTESTS: healthcheckmail: Relax matching on the healthcheck log message + - REGTESTS: log: test the log-forward feature + - BUG/MEDIUM: sink: bad init sequence on tcp sink from a ring. + - REGTESTS: ssl/log: test the log-forward with SSL + - DOC: fix TOC in starter guide for subsection 3.3.8. Statistics + - BUG/MEDIUM: captures: free() an error capture out of the proxy lock + - BUILD: fd: fix a build warning on the DWCAS + - SCRIPTS: announce-release: update some URLs to https + - BUG/MINOR: log: improper behavior when escaping log data + - REGTESTS: 4be_1srv_smtpchk_httpchk_layer47errors: Return valid SMTP replies + - BUG/MEDIUM: resolvers: Remove aborted resolutions from query_ids tree + 2022/07/27 : 2.4.18 - CI: determine actual LibreSSL version dynamically - MEDIUM: http-ana: Add a proxy option to restrict chars in request header names diff -Nru haproxy-2.4.18/.cirrus.yml haproxy-2.4.22/.cirrus.yml --- haproxy-2.4.18/.cirrus.yml 2022-07-27 13:10:44.000000000 +0000 +++ haproxy-2.4.22/.cirrus.yml 2023-02-14 15:57:13.000000000 +0000 @@ -1,7 +1,7 @@ FreeBSD_task: freebsd_instance: matrix: - image_family: freebsd-13-0 + image_family: freebsd-13-1 only_if: $CIRRUS_BRANCH =~ 'master|next' install_script: - pkg update -f && pkg upgrade -y && pkg install -y openssl git gmake lua53 socat pcre diff -Nru haproxy-2.4.18/debian/changelog haproxy-2.4.22/debian/changelog --- haproxy-2.4.18/debian/changelog 2023-03-31 17:18:03.000000000 +0000 +++ haproxy-2.4.22/debian/changelog 2023-08-14 23:00:52.000000000 +0000 @@ -1,3 +1,41 @@ +haproxy (2.4.22-0ubuntu0.22.04.2) jammy-security; urgency=medium + + * SECURITY UPDATE: incorrect handling of empty content-length header + - debian/patches/CVE-2023-40225-1.patch: add a proper check for empty + content-length header buffer in src/h1.c and src/h2.c. Also add + tests for it in reg-tests/http-messaging/h1_to_h1.vtc and + reg-tests/http-messaging/h2_to_h1.vtc. + - debian/patches/CVE-2023-40225-2.patch: add a check for leading zero + in content-length header buffer in src/h1.c and src/h2.c. Also add + tests in reg-tests/http-rules/h1or2_to_h1c.vtc. + - CVE-2023-40225 + + -- Rodrigo Figueiredo Zaiden Mon, 14 Aug 2023 20:00:52 -0300 + +haproxy (2.4.22-0ubuntu0.22.04.1) jammy; urgency=medium + + * New upstream release (LP: #2012557). + - Major and critical bug fixes according to the upstream changelog: + + BUG/MAJOR: log-forward: Fix log-forward proxies not fully initialized + + BUG/MAJOR: mworker: fix infinite loop on master with no proxies. + + BUG/MAJOR: stick-tables: do not try to index a server name for applets + + BUG/MAJOR: stick-table: don't process store-response rules for applets + + BUG/MAJOR: fcgi: Fix uninitialized reserved bytes + + BUG/MAJOR: buf: Fix copy of wrapping output data when a buffer is realigned + + BUG/CRITICAL: http: properly reject empty http header field names + - Remove patches applied by upstream in debian/patches: + + CVE-2023-0056.patch + + CVE-2023-25725.patch + + CVE-2023-0836.patch + - Refresh existing patches in debian/patches: + + haproxy.service-start-after-syslog.patch + + reproducible.patch + * Backport DEP-8 tests from Lunar: + - d/t/proxy-ssl-termination + - d/t/proxy-ssl-pass-through + + -- Lucas Kanashiro Wed, 22 Mar 2023 18:18:54 -0300 + haproxy (2.4.18-0ubuntu1.3) jammy-security; urgency=medium * SECURITY UPDATE: information leak via uninitialized bytes diff -Nru haproxy-2.4.18/debian/patches/CVE-2023-0056.patch haproxy-2.4.22/debian/patches/CVE-2023-0056.patch --- haproxy-2.4.18/debian/patches/CVE-2023-0056.patch 2023-01-19 15:47:45.000000000 +0000 +++ haproxy-2.4.22/debian/patches/CVE-2023-0056.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -From 827a6299e6995c5c3ba620d8b7cbacdaef67f2c4 Mon Sep 17 00:00:00 2001 -From: Christopher Faulet -Date: Thu, 22 Dec 2022 09:47:01 +0100 -Subject: [PATCH] BUG/MEDIUM: mux-h2: Refuse interim responses with end-stream - flag set - -As state in RFC9113#8.1, HEADERS frame with the ES flag set that carries an -informational status code is malformed. However, there is no test on this -condition. - -On 2.4 and higher, it is hard to predict consequences of this bug because -end of the message is only reported with a flag. But on 2.2 and lower, it -leads to a crash because there is an unexpected extra EOM block at the end -of an interim response. - -Now, when a ES flag is detected on a HEADERS frame for an interim message, a -stream error is sent (RST_STREAM/PROTOCOL_ERROR). - -This patch should solve the issue #1972. It should be backported as far as -2.0. ---- - src/mux_h2.c | 5 +++++ - 1 file changed, 5 insertions(+) - ---- a/src/mux_h2.c -+++ b/src/mux_h2.c -@@ -4940,6 +4940,11 @@ next_frame: - *flags |= H2_SF_HEADERS_RCVD; - - if (h2c->dff & H2_F_HEADERS_END_STREAM) { -+ if (msgf & H2_MSGF_RSP_1XX) { -+ /* RFC9113#8.1 : HEADERS frame with the ES flag set that carries an informational status code is malformed */ -+ TRACE_STATE("invalid interim response with ES flag!", H2_EV_RX_FRAME|H2_EV_RX_HDR|H2_EV_H2C_ERR|H2_EV_PROTO_ERR, h2c->conn); -+ goto fail; -+ } - /* no more data are expected for this message */ - htx->flags |= HTX_FL_EOM; - } diff -Nru haproxy-2.4.18/debian/patches/CVE-2023-0836.patch haproxy-2.4.22/debian/patches/CVE-2023-0836.patch --- haproxy-2.4.18/debian/patches/CVE-2023-0836.patch 2023-03-31 17:17:57.000000000 +0000 +++ haproxy-2.4.22/debian/patches/CVE-2023-0836.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,47 +0,0 @@ -From f988992d16f45ef03d5bbb024a1042ed8123e4c5 Mon Sep 17 00:00:00 2001 -From: Youfu Zhang -Date: Fri, 9 Dec 2022 19:15:48 +0800 -Subject: [PATCH] BUG/MAJOR: fcgi: Fix uninitialized reserved bytes - -The output buffer is not zero-initialized. If we don't clear reserved -bytes, fcgi requests sent to backend will leak sensitive data. - -This patch must be backported as far as 2.2. - -(cherry picked from commit 2e6bf0a2722866ae0128a4392fa2375bd1f03ff8) -Signed-off-by: Christopher Faulet -(cherry picked from commit db03179fee55c60a92ce6b86a0f04dbb9ba0328b) -Signed-off-by: Christopher Faulet ---- - src/fcgi.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/fcgi.c b/src/fcgi.c -index dcf2db2..1d1a82b 100644 ---- a/src/fcgi.c -+++ b/src/fcgi.c -@@ -47,7 +47,7 @@ int fcgi_encode_record_hdr(struct buffer *out, const struct fcgi_header *h) - out->area[len++] = ((h->len >> 8) & 0xff); - out->area[len++] = (h->len & 0xff); - out->area[len++] = h->padding; -- len++; /* rsv */ -+ out->area[len++] = 0; /* rsv */ - - out->data = len; - return 1; -@@ -94,7 +94,11 @@ int fcgi_encode_begin_request(struct buffer *out, const struct fcgi_begin_reques - out->area[len++] = ((r->role >> 8) & 0xff); - out->area[len++] = (r->role & 0xff); - out->area[len++] = r->flags; -- len += 5; /* rsv */ -+ out->area[len++] = 0; /* rsv */ -+ out->area[len++] = 0; -+ out->area[len++] = 0; -+ out->area[len++] = 0; -+ out->area[len++] = 0; - - out->data = len; - return 1; --- -1.7.10.4 - diff -Nru haproxy-2.4.18/debian/patches/CVE-2023-25725.patch haproxy-2.4.22/debian/patches/CVE-2023-25725.patch --- haproxy-2.4.18/debian/patches/CVE-2023-25725.patch 2023-02-13 12:42:20.000000000 +0000 +++ haproxy-2.4.22/debian/patches/CVE-2023-25725.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,145 +0,0 @@ -From a6c7ac9d51248a641f456906549120d3f6387049 Mon Sep 17 00:00:00 2001 -From: Willy Tarreau -Date: Thu, 9 Feb 2023 21:36:54 +0100 -Subject: BUG/CRITICAL: http: properly reject empty http header field names - -The HTTP header parsers surprizingly accepts empty header field names, -and this is a leftover from the original code that was agnostic to this. - -When muxes were introduced, for H2 first, the HPACK decompressor needed -to feed headers lists, and since empty header names were strictly -forbidden by the protocol, the lists of headers were purposely designed -to be terminated by an empty header field name (a principle that is -similar to H1's empty line termination). This principle was preserved -and generalized to other protocols migrated to muxes (H1/FCGI/H3 etc) -without anyone ever noticing that the H1 parser was still able to deliver -empty header field names to this list. In addition to this it turns out -that the HPACK decompressor, despite a comment in the code, may -successfully decompress an empty header field name, and this mistake -was propagated to the QPACK decompressor as well. - -The impact is that an empty header field name may be used to truncate -the list of headers and thus make some headers disappear. While for -H2/H3 the impact is limited as haproxy sees a request with missing -headers, and headers are not used to delimit messages, in the case of -HTTP/1, the impact is significant because the presence (and sometimes -contents) of certain sensitive headers is detected during the parsing. -Thus, some of these headers may be seen, marked as present, their value -extracted, but never delivered to upper layers and obviously not -forwarded to the other side either. This can have for consequence that -certain important header fields such as Connection, Upgrade, Host, -Content-length, Transfer-Encoding etc are possibly seen as different -between what haproxy uses to parse/forward/route and what is observed -in http-request rules and of course, forwarded. One direct consequence -is that it is possible to exploit this property in HTTP/1 to make -affected versions of haproxy forward more data than is advertised on -the other side, and bypass some access controls or routing rules by -crafting extraneous requests. Note, however, that responses to such -requests will normally not be passed back to the client, but this can -still cause some harm. - -This specific risk can be mostly worked around in configuration using -the following rule that will rely on the bug's impact to precisely -detect the inconsistency between the known body size and the one -expected to be advertised to the server (the rule works from 2.0 to -2.8-dev): - - http-request deny if { fc_http_major 1 } !{ req.body_size 0 } !{ req.hdr(content-length) -m found } !{ req.hdr(transfer-encoding) -m found } !{ method CONNECT } - -This will exclusively block such carefully crafted requests delivered -over HTTP/1. HTTP/2 and HTTP/3 do not need content-length, and a body -that arrives without being announced with a content-length will be -forwarded using transfer-encoding, hence will not cause discrepancies. -In HAProxy 2.0 in legacy mode ("no option http-use-htx"), this rule will -simply have no effect but will not cause trouble either. - -A clean solution would consist in modifying the loops iterating over -these headers lists to check the header name's pointer instead of its -length (since both are zero at the end of the list), but this requires -to touch tens of places and it's very easy to miss one. Functions such -as htx_add_header(), htx_add_trailer(), htx_add_all_headers() would be -good starting points for such a possible future change. - -Instead the current fix focuses on blocking empty headers where they -are first inserted, hence in the H1/HPACK/QPACK decoders. One benefit -of the current solution (for H1) is that it allows "show errors" to -report a precise diagnostic when facing such invalid HTTP/1 requests, -with the exact location of the problem and the originating address: - - $ printf "GET / HTTP/1.1\r\nHost: localhost\r\n:empty header\r\n\r\n" | nc 0 8001 - HTTP/1.1 400 Bad request - Content-length: 90 - Cache-Control: no-cache - Connection: close - Content-Type: text/html - -

400 Bad request

- Your browser sent an invalid request. - - - $ socat /var/run/haproxy.stat <<< "show errors" - Total events captured on [10/Feb/2023:16:29:37.530] : 1 - - [10/Feb/2023:16:29:34.155] frontend decrypt (#2): invalid request - backend (#-1), server (#-1), event #0, src 127.0.0.1:31092 - buffer starts at 0 (including 0 out), 16334 free, - len 50, wraps at 16336, error at position 33 - H1 connection flags 0x00000000, H1 stream flags 0x00000810 - H1 msg state MSG_HDR_NAME(17), H1 msg flags 0x00001410 - H1 chunk len 0 bytes, H1 body len 0 bytes : - - 00000 GET / HTTP/1.1\r\n - 00016 Host: localhost\r\n - 00033 :empty header\r\n - 00048 \r\n - -I want to address sincere and warm thanks for their great work to the -team composed of the following security researchers who found the issue -together and reported it: Bahruz Jabiyev, Anthony Gavazzi, and Engin -Kirda from Northeastern University, Kaan Onarlioglu from Akamai -Technologies, Adi Peleg and Harvey Tuch from Google. And kudos to Amaury -Denoyelle from HAProxy Technologies for spotting that the HPACK and -QPACK decoders would let this pass despite the comment explicitly -saying otherwise. - -This fix must be backported as far as 2.0. The QPACK changes can be -dropped before 2.6. In 2.0 there is also the equivalent code for legacy -mode, which doesn't suffer from the list truncation, but it would better -be fixed regardless. ---- - src/h1.c | 4 ++++ - src/hpack-dec.c | 9 +++++++++ - src/qpack-dec.c | 9 +++++++++ - 3 files changed, 22 insertions(+) - ---- a/src/h1.c -+++ b/src/h1.c -@@ -706,6 +706,10 @@ int h1_headers_to_hdr_list(char *start, - - if (likely(*ptr == ':')) { - col = ptr - start; -+ if (col <= sol) { -+ state = H1_MSG_HDR_NAME; -+ goto http_msg_invalid; -+ } - EAT_AND_JUMP_OR_RETURN(ptr, end, http_msg_hdr_l1_sp, http_msg_ood, state, H1_MSG_HDR_L1_SP); - } - ---- a/src/hpack-dec.c -+++ b/src/hpack-dec.c -@@ -419,6 +419,15 @@ int hpack_decode_frame(struct hpack_dht - /* and are correctly filled here */ - } - -+ /* We must not accept empty header names (forbidden by the spec and used -+ * as a list termination). -+ */ -+ if (!name.len) { -+ hpack_debug_printf("##ERR@%d##\n", __LINE__); -+ ret = -HPACK_ERR_INVALID_ARGUMENT; -+ goto leave; -+ } -+ - /* here's what we have here : - * - name.len > 0 - * - value is filled with either const data or data allocated from tmp diff -Nru haproxy-2.4.18/debian/patches/CVE-2023-40225-1.patch haproxy-2.4.22/debian/patches/CVE-2023-40225-1.patch --- haproxy-2.4.18/debian/patches/CVE-2023-40225-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ haproxy-2.4.22/debian/patches/CVE-2023-40225-1.patch 2023-08-14 22:59:57.000000000 +0000 @@ -0,0 +1,265 @@ +From ba9afd2774c03e434165475b537d0462801f49bb Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Wed, 9 Aug 2023 08:32:48 +0200 +Subject: [PATCH] BUG/MAJOR: http: reject any empty content-length header + value + +The content-length header parser has its dedicated function, in order +to take extreme care about invalid, unparsable, or conflicting values. +But there's a corner case in it, by which it stops comparing values +when reaching the end of the header. This has for a side effect that +an empty value or a value that ends with a comma does not deserve +further analysis, and it acts as if the header was absent. + +While this is not necessarily a problem for the value ending with a +comma as it will be cause a header folding and will disappear, it is a +problem for the first isolated empty header because this one will not +be recontructed when next ones are seen, and will be passed as-is to the +backend server. A vulnerable HTTP/1 server hosted behind haproxy that +would just use this first value as "0" and ignore the valid one would +then not be protected by haproxy and could be attacked this way, taking +the payload for an extra request. + +In field the risk depends on the server. Most commonly used servers +already have safe content-length parsers, but users relying on haproxy +to protect a known-vulnerable server might be at risk (and the risk of +a bug even in a reputable server should never be dismissed). + +A configuration-based work-around consists in adding the following rule +in the frontend, to explicitly reject requests featuring an empty +content-length header that would have not be folded into an existing +one: + + http-request deny if { hdr_len(content-length) 0 } + +The real fix consists in adjusting the parser so that it always expects a +value at the beginning of the header or after a comma. It will now reject +requests and responses having empty values anywhere in the C-L header. + +This needs to be backported to all supported versions. Note that the +modification was made to functions h1_parse_cont_len_header() and +http_parse_cont_len_header(). Prior to 2.8 the latter was in +h2_parse_cont_len_header(). One day the two should be refused but the +former is also used by Lua. + +The HTTP messaging reg-tests were completed to test these cases. + +Thanks to Ben Kallus of Dartmouth College and Narf Industries for +reporting this! (this is in GH #2237). + +(cherry picked from commit 6492f1f29d738457ea9f382aca54537f35f9d856) +Signed-off-by: Amaury Denoyelle +(cherry picked from commit a32f99f6f991d123ea3e307bf8aa63220836d365) +Signed-off-by: Amaury Denoyelle +(cherry picked from commit 65921ee12d88e9fb1fa9f6cd8198fd64b3a3f37f) +Signed-off-by: Amaury Denoyelle +(cherry picked from commit d17c50010d591d1c070e1cb0567a06032d8869e9) +[wt: applied to h2_parse_cont_len_header() in src/h2.c instead] +Signed-off-by: Willy Tarreau +--- + reg-tests/http-messaging/h1_to_h1.vtc | 26 ++++++++++++++ + reg-tests/http-messaging/h2_to_h1.vtc | 60 +++++++++++++++++++++++++++++++++ + src/h1.c | 20 +++++++++-- + src/h2.c | 20 +++++++++-- + 4 files changed, 120 insertions(+), 6 deletions(-) + +--- haproxy-2.4.22.orig/reg-tests/http-messaging/h1_to_h1.vtc ++++ haproxy-2.4.22/reg-tests/http-messaging/h1_to_h1.vtc +@@ -275,3 +275,29 @@ client c3h1 -connect ${h1_feh1_sock} { + # arrive here. + expect_close + } -run ++ ++client c4h1 -connect ${h1_feh1_sock} { ++ # this request is invalid and advertises an invalid C-L ending with an ++ # empty value, which results in a stream error. ++ txreq \ ++ -req "GET" \ ++ -url "/test31.html" \ ++ -hdr "content-length: 0," \ ++ -hdr "connection: close" ++ rxresp ++ expect resp.status == 400 ++ expect_close ++} -run ++ ++client c5h1 -connect ${h1_feh1_sock} { ++ # this request is invalid and advertises an empty C-L, which results ++ # in a stream error. ++ txreq \ ++ -req "GET" \ ++ -url "/test41.html" \ ++ -hdr "content-length:" \ ++ -hdr "connection: close" ++ rxresp ++ expect resp.status == 400 ++ expect_close ++} -run +--- haproxy-2.4.22.orig/reg-tests/http-messaging/h2_to_h1.vtc ++++ haproxy-2.4.22/reg-tests/http-messaging/h2_to_h1.vtc +@@ -10,6 +10,8 @@ barrier b1 cond 2 -cyclic + barrier b2 cond 2 -cyclic + barrier b3 cond 2 -cyclic + barrier b4 cond 2 -cyclic ++barrier b5 cond 2 -cyclic ++barrier b6 cond 2 -cyclic + + server s1 { + rxreq +@@ -31,6 +33,12 @@ server s1 { + + barrier b4 sync + # the next request is never received ++ ++ barrier b5 sync ++ # the next request is never received ++ ++ barrier b6 sync ++ # the next request is never received + } -repeat 2 -start + + haproxy h1 -conf { +@@ -121,6 +129,32 @@ client c1h2 -connect ${h1_feh2_sock} { + txdata -data "this is sent and ignored" + rxrst + } -run ++ ++ # fifth request is invalid and advertises an invalid C-L ending with an ++ # empty value, which results in a stream error. ++ stream 9 { ++ barrier b5 sync ++ txreq \ ++ -req "GET" \ ++ -scheme "https" \ ++ -url "/test5.html" \ ++ -hdr "content-length" "0," \ ++ -nostrend ++ rxrst ++ } -run ++ ++ # sixth request is invalid and advertises an empty C-L, which results ++ # in a stream error. ++ stream 11 { ++ barrier b6 sync ++ txreq \ ++ -req "GET" \ ++ -scheme "https" \ ++ -url "/test6.html" \ ++ -hdr "content-length" "" \ ++ -nostrend ++ rxrst ++ } -run + } -run + + # HEAD requests : don't work well yet +@@ -263,4 +297,30 @@ client c3h2 -connect ${h1_feh2_sock} { + txdata -data "this is sent and ignored" + rxrst + } -run ++ ++ # fifth request is invalid and advertises invalid C-L ending with an ++ # empty value, which results in a stream error. ++ stream 9 { ++ barrier b5 sync ++ txreq \ ++ -req "POST" \ ++ -scheme "https" \ ++ -url "/test25.html" \ ++ -hdr "content-length" "0," \ ++ -nostrend ++ rxrst ++ } -run ++ ++ # sixth request is invalid and advertises an empty C-L, which results ++ # in a stream error. ++ stream 11 { ++ barrier b6 sync ++ txreq \ ++ -req "POST" \ ++ -scheme "https" \ ++ -url "/test26.html" \ ++ -hdr "content-length" "" \ ++ -nostrend ++ rxrst ++ } -run + } -run +--- haproxy-2.4.22.orig/src/h1.c ++++ haproxy-2.4.22/src/h1.c +@@ -34,13 +34,20 @@ int h1_parse_cont_len_header(struct h1m + int not_first = !!(h1m->flags & H1_MF_CLEN); + struct ist word; + +- word.ptr = value->ptr - 1; // -1 for next loop's pre-increment ++ word.ptr = value->ptr; + e = value->ptr + value->len; + +- while (++word.ptr < e) { ++ while (1) { ++ if (word.ptr >= e) { ++ /* empty header or empty value */ ++ goto fail; ++ } ++ + /* skip leading delimiter and blanks */ +- if (unlikely(HTTP_IS_LWS(*word.ptr))) ++ if (unlikely(HTTP_IS_LWS(*word.ptr))) { ++ word.ptr++; + continue; ++ } + + /* digits only now */ + for (cl = 0, n = word.ptr; n < e; n++) { +@@ -79,6 +86,13 @@ int h1_parse_cont_len_header(struct h1m + h1m->flags |= H1_MF_CLEN; + h1m->curr_len = h1m->body_len = cl; + *value = word; ++ ++ /* Now either n==e and we're done, or n points to the comma, ++ * and we skip it and continue. ++ */ ++ if (n++ == e) ++ break; ++ + word.ptr = n; + } + /* here we've reached the end with a single value or a series of +--- haproxy-2.4.22.orig/src/h2.c ++++ haproxy-2.4.22/src/h2.c +@@ -80,13 +80,20 @@ int h2_parse_cont_len_header(unsigned in + int not_first = !!(*msgf & H2_MSGF_BODY_CL); + struct ist word; + +- word.ptr = value->ptr - 1; // -1 for next loop's pre-increment ++ word.ptr = value->ptr; + e = value->ptr + value->len; + +- while (++word.ptr < e) { ++ while (1) { ++ if (word.ptr >= e) { ++ /* empty header or empty value */ ++ goto fail; ++ } ++ + /* skip leading delimiter and blanks */ +- if (unlikely(HTTP_IS_LWS(*word.ptr))) ++ if (unlikely(HTTP_IS_LWS(*word.ptr))) { ++ word.ptr++; + continue; ++ } + + /* digits only now */ + for (cl = 0, n = word.ptr; n < e; n++) { +@@ -125,6 +132,13 @@ int h2_parse_cont_len_header(unsigned in + *msgf |= H2_MSGF_BODY_CL; + *body_len = cl; + *value = word; ++ ++ /* Now either n==e and we're done, or n points to the comma, ++ * and we skip it and continue. ++ */ ++ if (n++ == e) ++ break; ++ + word.ptr = n; + } + /* here we've reached the end with a single value or a series of diff -Nru haproxy-2.4.18/debian/patches/CVE-2023-40225-2.patch haproxy-2.4.22/debian/patches/CVE-2023-40225-2.patch --- haproxy-2.4.18/debian/patches/CVE-2023-40225-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ haproxy-2.4.22/debian/patches/CVE-2023-40225-2.patch 2023-08-14 23:00:28.000000000 +0000 @@ -0,0 +1,143 @@ +From c48acd15011dc6c66977bc088065693f430821df Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Wed, 9 Aug 2023 11:02:34 +0200 +Subject: [PATCH] BUG/MINOR: http: skip leading zeroes in content-length + values + +Ben Kallus also noticed that we preserve leading zeroes on content-length +values. While this is totally valid, it would be safer to at least trim +them before passing the value, because a bogus server written to parse +using "strtol(value, NULL, 0)" could inadvertently take a leading zero +as a prefix for an octal value. While there is not much that can be done +to protect such servers in general (e.g. lack of check for overflows etc), +at least it's quite cheap to make sure the transmitted value is normalized +and not taken for an octal one. + +This is not really a bug, rather a missed opportunity to sanitize the +input, but is marked as a bug so that we don't forget to backport it to +stable branches. + +A combined regtest was added to h1or2_to_h1c which already validates +end-to-end syntax consistency on aggregate headers. + +(cherry picked from commit 22731762d9fe2c98d9e6c3942b1568266b23c69f) +Signed-off-by: Amaury Denoyelle +(cherry picked from commit c33738c7d4ed50e1758dbedd39dfe5bd929a5076) +Signed-off-by: Amaury Denoyelle +(cherry picked from commit 84462c9390c3efe95b748bb9fc3bd2edc3decd2f) +Signed-off-by: Amaury Denoyelle +(cherry picked from commit e2e464018fda41758bd42d3bcd6ac623c88a110e) +[wt: applied the http.c to h2.c] +Signed-off-by: Willy Tarreau +--- + reg-tests/http-rules/h1or2_to_h1c.vtc | 16 ++++++++++++---- + src/h1.c | 8 ++++++++ + src/h2.c | 8 ++++++++ + 3 files changed, 28 insertions(+), 4 deletions(-) + +--- haproxy-2.4.22.orig/reg-tests/http-rules/h1or2_to_h1c.vtc ++++ haproxy-2.4.22/reg-tests/http-rules/h1or2_to_h1c.vtc +@@ -27,11 +27,11 @@ server s1 { + -body "This is a body" + + expect req.method == "GET" +- expect req.http.fe-sl1-crc == 992395575 +- expect req.http.fe-sl2-crc == 1270056220 ++ expect req.http.fe-sl1-crc == 1874847043 ++ expect req.http.fe-sl2-crc == 1142278307 + expect req.http.fe-hdr-crc == 1719311923 +- expect req.http.be-sl1-crc == 2604236007 +- expect req.http.be-sl2-crc == 4181358964 ++ expect req.http.be-sl1-crc == 3455320059 ++ expect req.http.be-sl2-crc == 2509326257 + expect req.http.be-hdr-crc == 3634102538 + } -repeat 2 -start + +@@ -53,6 +53,7 @@ haproxy h1 -conf { + http-request set-var(req.path) path + http-request set-var(req.query) query + http-request set-var(req.param) url_param(qs_arg) ++ http-request set-var(req.cl) req.fhdr(content-length) + + http-request set-header sl1 "sl1: " + +@@ -65,8 +66,10 @@ haproxy h1 -conf { + + http-request set-header sl1 "%[req.fhdr(sl1)] method=<%[var(req.method)]>; uri=<%[var(req.uri)]>; path=<%[var(req.path)]>;" + http-request set-header sl1 "%[req.fhdr(sl1)] query=<%[var(req.query)]>; param=<%[var(req.param)]>" ++ http-request set-header sl1 "%[req.fhdr(sl1)] cl=<%[var(req.cl)]>" + http-request set-header sl2 "%[req.fhdr(sl2)] method=<%[method]>; uri=<%[url]>; path=<%[path]>; " + http-request set-header sl2 "%[req.fhdr(sl2)] query=<%[query]>; param=<%[url_param(qs_arg)]>" ++ http-request set-header sl2 "%[req.fhdr(sl2)] cl=<%[req.fhdr(content-length)]>" + http-request set-header hdr "%[req.fhdr(hdr)] hdr1=<%[req.hdr(hdr1)]>; fhdr1=<%[req.fhdr(hdr1)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr2=<%[req.hdr(hdr2)]>; fhdr2=<%[req.fhdr(hdr2)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr3=<%[req.hdr(hdr3)]>; fhdr3=<%[req.fhdr(hdr3)]>;" +@@ -120,6 +123,7 @@ haproxy h1 -conf { + http-request set-var(req.path) path + http-request set-var(req.query) query + http-request set-var(req.param) url_param(qs_arg) ++ http-request set-var(req.cl) req.fhdr(content-length) + + http-request set-header sl1 "sl1: " + +@@ -132,8 +136,10 @@ haproxy h1 -conf { + + http-request set-header sl1 "%[req.fhdr(sl1)] method=<%[var(req.method)]>; uri=<%[var(req.uri)]>; path=<%[var(req.path)]>;" + http-request set-header sl1 "%[req.fhdr(sl1)] query=<%[var(req.query)]>; param=<%[var(req.param)]>" ++ http-request set-header sl1 "%[req.fhdr(sl1)] cl=<%[var(req.cl)]>" + http-request set-header sl2 "%[req.fhdr(sl2)] method=<%[method]>; uri=<%[url]>; path=<%[path]>; " + http-request set-header sl2 "%[req.fhdr(sl2)] query=<%[query]>; param=<%[url_param(qs_arg)]>" ++ http-request set-header sl2 "%[req.fhdr(sl2)] cl=<%[req.fhdr(content-length)]>" + http-request set-header hdr "%[req.fhdr(hdr)] hdr1=<%[req.hdr(hdr1)]>; fhdr1=<%[req.fhdr(hdr1)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr2=<%[req.hdr(hdr2)]>; fhdr2=<%[req.fhdr(hdr2)]>;" + http-request set-header hdr "%[req.fhdr(hdr)] hdr3=<%[req.hdr(hdr3)]>; fhdr3=<%[req.fhdr(hdr3)]>;" +@@ -171,6 +177,7 @@ client c1h1 -connect ${h1_feh1_sock} { + txreq \ + -req GET \ + -url /path/to/file.extension?qs_arg=qs_value \ ++ -hdr "content-length: 000, 00" \ + -hdr "hdr1: val1" \ + -hdr "hdr2: val2a" \ + -hdr "hdr2: val2b" \ +@@ -205,6 +212,7 @@ client c1h2 -connect ${h1_feh2_sock} { + -req GET \ + -scheme "https" \ + -url /path/to/file.extension?qs_arg=qs_value \ ++ -hdr "content-length" "000, 00" \ + -hdr "hdr1" "val1" \ + -hdr "hdr2" " val2a" \ + -hdr "hdr2" " val2b" \ +--- haproxy-2.4.22.orig/src/h1.c ++++ haproxy-2.4.22/src/h1.c +@@ -58,6 +58,14 @@ int h1_parse_cont_len_header(struct h1m + goto fail; + break; + } ++ ++ if (unlikely(!cl && n > word.ptr)) { ++ /* There was a leading zero before this digit, ++ * let's trim it. ++ */ ++ word.ptr = n; ++ } ++ + if (unlikely(cl > ULLONG_MAX / 10ULL)) + goto fail; /* multiply overflow */ + cl = cl * 10ULL; +--- haproxy-2.4.22.orig/src/h2.c ++++ haproxy-2.4.22/src/h2.c +@@ -104,6 +104,14 @@ int h2_parse_cont_len_header(unsigned in + goto fail; + break; + } ++ ++ if (unlikely(!cl && n > word.ptr)) { ++ /* There was a leading zero before this digit, ++ * let's trim it. ++ */ ++ word.ptr = n; ++ } ++ + if (unlikely(cl > ULLONG_MAX / 10ULL)) + goto fail; /* multiply overflow */ + cl = cl * 10ULL; diff -Nru haproxy-2.4.18/debian/patches/haproxy.service-start-after-syslog.patch haproxy-2.4.22/debian/patches/haproxy.service-start-after-syslog.patch --- haproxy-2.4.18/debian/patches/haproxy.service-start-after-syslog.patch 2022-08-25 18:52:23.000000000 +0000 +++ haproxy-2.4.22/debian/patches/haproxy.service-start-after-syslog.patch 2023-03-22 21:18:54.000000000 +0000 @@ -13,8 +13,6 @@ admin/systemd/haproxy.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -diff --git a/admin/systemd/haproxy.service.in b/admin/systemd/haproxy.service.in -index 74e66e3..243acf2 100644 --- a/admin/systemd/haproxy.service.in +++ b/admin/systemd/haproxy.service.in @@ -1,6 +1,6 @@ diff -Nru haproxy-2.4.18/debian/patches/reproducible.patch haproxy-2.4.22/debian/patches/reproducible.patch --- haproxy-2.4.18/debian/patches/reproducible.patch 2022-08-25 18:52:23.000000000 +0000 +++ haproxy-2.4.22/debian/patches/reproducible.patch 2023-03-22 21:18:54.000000000 +0000 @@ -1,8 +1,6 @@ -diff --git a/Makefile b/Makefile -index 566bdb26a3e7..8603dea25c21 100644 --- a/Makefile +++ b/Makefile -@@ -975,7 +975,7 @@ src/haproxy.o: src/haproxy.c $(DEP) +@@ -995,7 +995,7 @@ -DBUILD_ARCH='"$(strip $(ARCH))"' \ -DBUILD_CPU='"$(strip $(CPU))"' \ -DBUILD_CC='"$(strip $(CC))"' \ diff -Nru haproxy-2.4.18/debian/patches/series haproxy-2.4.22/debian/patches/series --- haproxy-2.4.18/debian/patches/series 2023-03-31 17:17:57.000000000 +0000 +++ haproxy-2.4.22/debian/patches/series 2023-08-14 23:00:23.000000000 +0000 @@ -4,6 +4,5 @@ # applied during the build process: # debianize-dconv.patch reproducible.patch -CVE-2023-0056.patch -CVE-2023-25725.patch -CVE-2023-0836.patch +CVE-2023-40225-1.patch +CVE-2023-40225-2.patch diff -Nru haproxy-2.4.18/debian/tests/control haproxy-2.4.22/debian/tests/control --- haproxy-2.4.18/debian/tests/control 2022-08-25 18:52:23.000000000 +0000 +++ haproxy-2.4.22/debian/tests/control 2023-03-22 21:18:54.000000000 +0000 @@ -5,3 +5,11 @@ Tests: proxy-localhost Depends: haproxy, wget, apache2 Restrictions: needs-root, allow-stderr, isolation-container + +Tests: proxy-ssl-termination +Depends: haproxy, wget, apache2, gnutls-bin, ssl-cert +Restrictions: needs-root, allow-stderr, isolation-container + +Tests: proxy-ssl-pass-through +Depends: haproxy, wget, apache2, gnutls-bin, ssl-cert +Restrictions: needs-root, allow-stderr, isolation-container diff -Nru haproxy-2.4.18/debian/tests/proxy-localhost haproxy-2.4.22/debian/tests/proxy-localhost --- haproxy-2.4.18/debian/tests/proxy-localhost 2022-08-25 18:52:23.000000000 +0000 +++ haproxy-2.4.22/debian/tests/proxy-localhost 2023-03-22 21:18:54.000000000 +0000 @@ -2,6 +2,9 @@ set -eux +WDIR=$(dirname "$0") +. "${WDIR}/utils" + cat > /etc/haproxy/haproxy.cfg < /etc/haproxy/haproxy.cfg < /etc/haproxy/haproxy.cfg < /etc/ssl/ca.info +cn = Example Company +ca +cert_signing_key +expiration_days = 3650 +EOF + + certtool --generate-self-signed \ + --load-privkey /etc/ssl/private/mycakey.pem \ + --template /etc/ssl/ca.info \ + --outfile /usr/local/share/ca-certificates/mycacert.crt + + update-ca-certificates +} + +create_selfsigned_cert() { + dir="$1" + mkdir -p "${dir}" + + certtool --generate-privkey --bits 2048 --outfile "${dir}/localhost_key.pem" + + cat < "${dir}/localhost.info" +organization = Example Company +cn = localhost +tls_www_server +encryption_key +signing_key +expiration_days = 365 +EOF + + certtool --generate-certificate \ + --load-privkey "${dir}/localhost_key.pem" \ + --load-ca-certificate /etc/ssl/certs/mycacert.pem \ + --load-ca-privkey /etc/ssl/private/mycakey.pem \ + --template "${dir}/localhost.info" \ + --outfile "${dir}/localhost_cert.pem" + + cat "${dir}/localhost_cert.pem" "${dir}/localhost_key.pem" | tee "${dir}/localhost.pem" + chgrp haproxy "${dir}/localhost_key.pem" "${dir}/localhost.pem" + chmod 0640 "${dir}/localhost_key.pem" "${dir}/localhost.pem" +} + +check_index_file() { + haproxy_url="$1" + # index.html is shipped with apache2 + # Download it via haproxy and compare + if wget -t1 "${haproxy_url}" -O- | cmp /var/www/html/index.html -; then + echo "OK: index.html downloaded via haproxy matches the source file." + else + echo "FAIL: downloaded index.html via haproxy is different from the" + echo " file delivered by apache." + exit 1 + fi +} diff -Nru haproxy-2.4.18/doc/configuration.txt haproxy-2.4.22/doc/configuration.txt --- haproxy-2.4.18/doc/configuration.txt 2022-07-27 13:10:44.000000000 +0000 +++ haproxy-2.4.22/doc/configuration.txt 2023-02-14 15:57:13.000000000 +0000 @@ -3,7 +3,7 @@ Configuration Manual ---------------------- version 2.4 - 2022/07/27 + 2023/02/14 This document covers the configuration language as implemented in the version @@ -965,32 +965,36 @@ The following keywords are supported in the "global" section : * Process management and security + - 51degrees-cache-size + - 51degrees-data-file + - 51degrees-property-name-list + - 51degrees-property-separator - ca-base - chroot - - crt-base - cpu-map + - crt-base - daemon - default-path - description - deviceatlas-json-file - deviceatlas-log-level - - deviceatlas-separator - deviceatlas-properties-cookie + - deviceatlas-separator - expose-experimental-directives - external-check - gid - group - - hard-stop-after - h1-case-adjust - h1-case-adjust-file + - h2-workaround-bogus-websocket-clients + - hard-stop-after - insecure-fork-wanted - insecure-setuid-wanted - issuers-chain-path - - h2-workaround-bogus-websocket-clients - localpeer - log - - log-tag - log-send-hostname + - log-tag - lua-load - lua-load-per-thread - lua-prepend-path @@ -1003,13 +1007,9 @@ - pp2-never-send-local - presetenv - resetenv - - uid - - ulimit-n - - user - set-dumpable - set-var - setenv - - stats - ssl-default-bind-ciphers - ssl-default-bind-ciphersuites - ssl-default-bind-curves @@ -1020,25 +1020,25 @@ - ssl-dh-param-file - ssl-server-verify - ssl-skip-self-issued-ca + - stats + - strict-limits + - uid + - ulimit-n - unix-bind - unsetenv - - 51degrees-data-file - - 51degrees-property-name-list - - 51degrees-property-separator - - 51degrees-cache-size + - user + - wurfl-cache-size - wurfl-data-file - wurfl-information-list - wurfl-information-list-separator - - wurfl-cache-size - - strict-limits * Performance tuning - busy-polling - max-spread-checks + - maxcompcpuusage + - maxcomprate - maxconn - maxconnrate - - maxcomprate - - maxcompcpuusage - maxpipes - maxsessrate - maxsslconn @@ -1046,16 +1046,16 @@ - maxzlibmem - no-memory-trimming - noepoll - - nokqueue - noevports - - nopoll - - nosplice - nogetaddrinfo + - nokqueue + - nopoll - noreuseport + - nosplice - profiling.tasks - - spread-checks - server-state-base - server-state-file + - spread-checks - ssl-engine - ssl-mode-async - tune.buffers.limit @@ -1074,9 +1074,9 @@ - tune.idletimer - tune.lua.forced-yield - tune.lua.maxmem + - tune.lua.service-timeout - tune.lua.session-timeout - tune.lua.task-timeout - - tune.lua.service-timeout - tune.maxaccept - tune.maxpollevents - tune.maxrewrite @@ -1092,13 +1092,13 @@ - tune.sndbuf.client - tune.sndbuf.server - tune.ssl.cachesize + - tune.ssl.capture-cipherlist-size + - tune.ssl.default-dh-param + - tune.ssl.force-private-cache - tune.ssl.keylog - tune.ssl.lifetime - - tune.ssl.force-private-cache - tune.ssl.maxrecord - - tune.ssl.default-dh-param - tune.ssl.ssl-ctx-cache-size - - tune.ssl.capture-cipherlist-size - tune.vars.global-max-size - tune.vars.proc-max-size - tune.vars.reqres-max-size @@ -1115,6 +1115,36 @@ 3.1. Process management and security ------------------------------------ +51degrees-data-file + The path of the 51Degrees data file to provide device detection services. The + file should be unzipped and accessible by HAProxy with relevant permissions. + + Please note that this option is only available when HAProxy has been + compiled with USE_51DEGREES. + +51degrees-property-name-list [ ...] + A list of 51Degrees property names to be load from the dataset. A full list + of names is available on the 51Degrees website: + https://51degrees.com/resources/property-dictionary + + Please note that this option is only available when HAProxy has been + compiled with USE_51DEGREES. + +51degrees-property-separator + A char that will be appended to every property value in a response header + containing 51Degrees results. If not set that will be set as ','. + + Please note that this option is only available when HAProxy has been + compiled with USE_51DEGREES. + +51degrees-cache-size + Sets the size of the 51Degrees converter cache to entries. This + is an LRU cache which reminds previous device detections and their results. + By default, this cache is disabled. + + Please note that this option is only available when HAProxy has been + compiled with USE_51DEGREES. + ca-base Assigns a default directory to fetch SSL CA certificates and CRLs from when a relative path is used with "ca-file", "ca-verify-file" or "crl-file" @@ -1267,6 +1297,13 @@ paths. A robust approach could consist in prefixing all files names with their respective site name, or in doing so at the directory level. +description + Add a text that describes the instance. + + Please note that it is required to escape certain characters (# for example) + and this text is inserted into a html page so you should avoid using + "<" and ">" characters. + deviceatlas-json-file Sets the path of the DeviceAtlas JSON data file to be loaded by the API. The path must be a valid JSON data file and accessible by HAProxy process. @@ -1275,15 +1312,15 @@ Sets the level of information returned by the API. This directive is optional and set to 0 by default if not set. -deviceatlas-separator - Sets the character separator for the API properties results. This directive - is optional and set to | by default if not set. - deviceatlas-properties-cookie Sets the client cookie's name used for the detection if the DeviceAtlas Client-side component was used during the request. This directive is optional and set to DAPROPS by default if not set. +deviceatlas-separator + Sets the character separator for the API properties results. This directive + is optional and set to | by default if not set. + expose-experimental-directives This statement must appear before using directives tagged as experimental or the config file will be rejected. @@ -1309,22 +1346,6 @@ Similar to "gid" but uses the GID of group name from /etc/group. See also "gid" and "user". -hard-stop-after