From 9deebc2273d30ca9a72a9a708352ceaa114bdb1f Mon Sep 17 00:00:00 2001 From: Thomas Perale Date: Tue, 15 Sep 2026 13:47:01 +0200 Subject: [PATCH] Revert "package/openvpn: add patches for CVE-2026-84732" Commit 1afe223d4c4ed592cecb0a49631b1f156103a78d was wrongly applied. This commit was the v1 of a series that as since been superseeded and fixed. Revert this commit to correctly apply the patch that fix CVE-2026-84732. Signed-off-by: Thomas Perale --- ...avoid-unbounded-reliable-tls-timeout.patch | 129 ----------- ...r-packets-that-cannot-be-outstanding.patch | 206 ------------------ package/openvpn/openvpn.mk | 4 - 3 files changed, 339 deletions(-) delete mode 100644 package/openvpn/0001-avoid-unbounded-reliable-tls-timeout.patch delete mode 100644 package/openvpn/0002-ignore-acks-for-packets-that-cannot-be-outstanding.patch diff --git a/package/openvpn/0001-avoid-unbounded-reliable-tls-timeout.patch b/package/openvpn/0001-avoid-unbounded-reliable-tls-timeout.patch deleted file mode 100644 index c559ffcb4d..0000000000 --- a/package/openvpn/0001-avoid-unbounded-reliable-tls-timeout.patch +++ /dev/null @@ -1,129 +0,0 @@ -From: Arne Schwabe -Date: Tue, 1 Sep 2026 13:35:09 +0200 -Subject: Avoid unbounded reliable TLS timeout - -Avoid an unbounded TLS retransmit timeout, which could potentially -trigger an integer overflow. - -The maximum initial timeout is defined in reliable.h and used to -constrain --tls-timeout, so that the relation between the option range -and RELIABLE_MAX_TIMEOUT_SHIFT is explicit and checked at compile time. - -Github: OpenVPN/openvpn-private-issues#161 -Reported-By: Mark Bregman (Fox-IT) -CVE: 2026-84732 -Change-Id: Id8ac9c48a8f751b0df95c6436ad3fbff3c4ae4a6 -Signed-off-by: Arne Schwabe -Signed-off-by: Razvan Cojocaru -Acked-by: MaxF - ---- -Upstream: https://github.com/OpenVPN/openvpn/commit/207ac5f47e46565881dcec385020ebdcb682caa4 -CVE: CVE-2026-84732 -Signed-off-by: Titouan Christophe ---- - src/openvpn/options.c | 9 ++++++++- - src/openvpn/reliable.c | 13 ++++++++++++- - src/openvpn/reliable.h | 41 ++++++++++++++++++++++++++--------------- - 3 files changed, 46 insertions(+), 17 deletions(-) - -diff --git a/src/openvpn/options.c b/src/openvpn/options.c -index 5f3f4e96028..7a649de8822 100644 ---- a/src/openvpn/options.c -+++ b/src/openvpn/options.c -@@ -7548,7 +7548,14 @@ add_option(struct options *options, char *p[], bool is_inline, const char *file, - else if (streq(p[0], "tls-timeout") && p[1] && !p[2]) - { - VERIFY_PERMISSION(OPT_P_TLS_PARMS); -- options->tls_timeout = positive_atoi(p[1], msglevel); -+ /* Constrain the timeout to not have problems with -+ * RELIABLE_MAX_TIMEOUT_SHIFT creating an overflow. 65k seconds -+ * timeout is already way too much anyway */ -+ if (!atoi_constrained(p[1], &options->tls_timeout, "tls-timeout", 1, -+ RELIABLE_MAX_INITIAL_TIMEOUT, msglevel)) -+ { -+ goto err; -+ } - } - else if (streq(p[0], "reneg-bytes") && p[1] && !p[2]) - { -diff --git a/src/openvpn/reliable.c b/src/openvpn/reliable.c -index 690e50d6d95..230d6aca47e 100644 ---- a/src/openvpn/reliable.c -+++ b/src/openvpn/reliable.c -@@ -655,11 +655,22 @@ reliable_send(struct reliable *rel, int *opcode) - } - } - } -+ - if (best) - { -+ /* The initial timeout is bounded by RELIABLE_MAX_INITIAL_TIMEOUT, so -+ * shifting it cannot overflow. */ -+ static_assert(RELIABLE_MAX_INITIAL_TIMEOUT <= (INT_MAX >> RELIABLE_MAX_TIMEOUT_SHIFT), -+ "initial reliable timeout overflows when shifted"); -+ const interval_t max_timeout = rel->initial_timeout << RELIABLE_MAX_TIMEOUT_SHIFT; -+ - /* exponential backoff */ - best->next_try = local_now + best->timeout; -- best->timeout *= 2; -+ if (best->timeout < max_timeout) -+ { -+ best->timeout *= 2; -+ } -+ - best->n_acks = 0; - *opcode = best->opcode; - dmsg(D_REL_DEBUG, "ACK reliable_send ID " packet_id_format " (size=%d to=%d)", -diff --git a/src/openvpn/reliable.h b/src/openvpn/reliable.h -index a5ed75cf0d0..af95bbc17a1 100644 ---- a/src/openvpn/reliable.h -+++ b/src/openvpn/reliable.h -@@ -40,21 +40,32 @@ - * @{ */ - - --#define RELIABLE_ACK_SIZE \ -- 8 /**< The maximum number of packet IDs \ -- * waiting to be acknowledged which can \ -- * be stored in one \c reliable_ack \ -- * structure. */ -- --#define RELIABLE_CAPACITY \ -- 12 /**< The maximum number of packets that \ -- * the reliability layer for one VPN \ -- * tunnel in one direction can store. */ -- --#define N_ACK_RETRANSMIT \ -- 3 /**< We retry sending a packet early if \ -- * this many later packets have been \ -- * ACKed. */ -+#define RELIABLE_ACK_SIZE 8 -+/**< The maximum number of packet IDs -+ * waiting to be acknowledged which can -+ * be stored in one \c reliable_ack -+ * structure. */ -+ -+#define RELIABLE_CAPACITY 12 -+/**< The maximum number of packets that -+ * the reliability layer for one VPN -+ * tunnel in one direction can store. */ -+ -+#define N_ACK_RETRANSMIT 3 -+/**< We retry sending a packet early if -+ * this many later packets have been -+ * ACKed. */ -+ -+#define RELIABLE_MAX_TIMEOUT_SHIFT 6 -+/**< Maximum shift or doubling in exponential backoff -+ * we allow. This is a safeguard against an unbounded -+ * exponential backoff. With the default timeout of 2s this -+ * equals 128s */ -+ -+#define RELIABLE_MAX_INITIAL_TIMEOUT (1 << 16) -+/**< Maximum initial timeout (--tls-timeout) we accept. -+ * Bounded so that shifting it by RELIABLE_MAX_TIMEOUT_SHIFT -+ * cannot overflow an int. */ - - /** - * The acknowledgment structure in which packet IDs are stored for later diff --git a/package/openvpn/0002-ignore-acks-for-packets-that-cannot-be-outstanding.patch b/package/openvpn/0002-ignore-acks-for-packets-that-cannot-be-outstanding.patch deleted file mode 100644 index 0b97582965..0000000000 --- a/package/openvpn/0002-ignore-acks-for-packets-that-cannot-be-outstanding.patch +++ /dev/null @@ -1,206 +0,0 @@ -From: Arne Schwabe -Date: Tue, 1 Sep 2026 13:35:09 +0200 -Subject: Ignore acks for packets that cannot be outstanding - -This ignores acks for pids outside the send window, i.e. for packets -that have either not been sent out yet or already left the window. -Nothing outside that window can be outstanding, so such acks can only -be used to manipulate the state of the send buffer. - -Comparing the pid of an outstanding packet against the acked pid needs -to be wraparound aware as well. Otherwise a peer can ack a pid from the -lower half of the id space, which passes the window check above, and -still increment n_acks on every outstanding packet, forcing an early -retransmit after N_ACK_RETRANSMIT such acks. - -Github: OpenVPN/openvpn-private-issues#161 -Reported-By: Mark Bregman (Fox-IT) -CVE: 2026-84732 -Change-Id: I944478767b52a1b9bf6a65373ce0544c69cb1012 -Signed-off-by: Arne Schwabe -Signed-off-by: Razvan Cojocaru -Acked-by: MaxF - ---- -Upstream: https://github.com/OpenVPN/openvpn/commit/d988ef4508e63b28c8e3efcb9f62eb8c836907fe -CVE: CVE-2026-84732 -Signed-off-by: Titouan Christophe ---- - src/openvpn/reliable.c | 37 ++++++++++++++++- - src/openvpn/reliable.h | 17 ++++++-- - tests/unit_tests/openvpn/test_packet_id.c | 50 ++++++++++++++++++++++- - 3 files changed, 98 insertions(+), 6 deletions(-) - -diff --git a/src/openvpn/reliable.c b/src/openvpn/reliable.c -index 230d6aca47e..ced438e481d 100644 ---- a/src/openvpn/reliable.c -+++ b/src/openvpn/reliable.c -@@ -390,13 +390,35 @@ reliable_empty(const struct reliable *rel) - return true; - } - -+int -+validate_packet_id_window(struct reliable *rel, packet_id_type pid) -+{ -+ return reliable_pid_min(pid, rel->packet_id) -+ && reliable_pid_min(subtract_pid(rel->packet_id, RELIABLE_CAPACITY), pid); -+} -+ - /* del acknowledged items from send buf */ - void - reliable_send_purge(struct reliable *rel, const struct reliable_ack *ack) - { -+ unsigned int out_of_window = 0; -+ packet_id_type first_out_of_window = 0; -+ - for (int i = 0; i < ack->len; ++i) - { - packet_id_type pid = ack->packet_id[i]; -+ -+ -+ if (!validate_packet_id_window(rel, pid)) -+ { -+ if (out_of_window == 0) -+ { -+ first_out_of_window = pid; -+ } -+ out_of_window++; -+ continue; -+ } -+ - for (int j = 0; j < rel->size; ++j) - { - struct reliable_entry *e = &rel->array[j]; -@@ -417,16 +439,27 @@ reliable_send_purge(struct reliable *rel, const struct reliable_ack *ack) - #endif - e->active = false; - } -- else if (e->active && e->packet_id < pid) -+ -+ if (e->active && reliable_pid_min(e->packet_id, pid)) - { - /* We have received an ACK for a packet with a higher PID. Either - * we have received ACKs out of or order or the packet has been - * lost. We count the number of ACKs to determine if we should -- * resend it early. */ -+ * resend it early. The comparison needs to be wraparound aware, -+ * otherwise a peer can inflate n_acks with an ACK for a pid from -+ * the lower half of the id space and force a retransmit. */ - e->n_acks++; - } - } - } -+ -+ if (out_of_window > 0) -+ { -+ (void)first_out_of_window; /* dmsg might not generate code */ -+ dmsg(D_REL_LOW, "ACK contained %u ids outside the send window, " -+ "first was " packet_id_format, -+ out_of_window, (packet_id_print_type)first_out_of_window); -+ } - } - - #ifdef ENABLE_DEBUG -diff --git a/src/openvpn/reliable.h b/src/openvpn/reliable.h -index af95bbc17a1..a85f2e97807 100644 ---- a/src/openvpn/reliable.h -+++ b/src/openvpn/reliable.h -@@ -105,9 +105,9 @@ struct reliable - { - int size; - interval_t initial_timeout; -- packet_id_type packet_id; -- int offset; /**< Offset of the bufs in the reliable_entry array */ -- bool hold; /* don't xmit until reliable_schedule_now is called */ -+ packet_id_type packet_id; /**< Packet ID for the next packet to be sent out. */ -+ int offset; /**< Offset of the bufs in the reliable_entry array */ -+ bool hold; /* don't xmit until reliable_schedule_now is called */ - struct reliable_entry array[RELIABLE_CAPACITY]; - }; - -@@ -189,6 +189,17 @@ reliable_ack_empty(struct reliable_ack *ack) - return !ack->len; - } - -+/** -+ * check that pid is inside the window of possible outstanding packets -+ * of size RELIABLE_CAPACITY, ie inside the range -+ * [rel->packet_id - RELIABLE_CAPACITY, rel->packet_id). -+ * -+ * rel->packet is the *next* packet id to be sent out, so it is not -+ * included in the valid range. -+ */ -+int -+validate_packet_id_window(struct reliable *rel, packet_id_type pid); -+ - /** - * Returns the number of packets that need to be acked. - * -diff --git a/tests/unit_tests/openvpn/test_packet_id.c b/tests/unit_tests/openvpn/test_packet_id.c -index 5dfd319ab9a..a5d50de4ae7 100644 ---- a/tests/unit_tests/openvpn/test_packet_id.c -+++ b/tests/unit_tests/openvpn/test_packet_id.c -@@ -325,6 +325,53 @@ test_copy_acks_to_lru(void **state) - assert_memory_equal(mru_ack.packet_id, expected_ack.packet_id, sizeof(expected_ack.packet_id)); - } - -+static void -+test_packet_id_window(void **state) -+{ -+ struct reliable rel = { 0 }; -+ rel.packet_id = 1; -+ -+ assert_true(validate_packet_id_window(&rel, 0)); -+ -+ /* packet id 1 is outside the window as it is the *next* packet id */ -+ assert_false(validate_packet_id_window(&rel, 1)); -+ -+ /* wrapped around packet id, "-2" */ -+ assert_true(validate_packet_id_window(&rel, 0xFFFFFFFD)); -+ -+ /* wrapped around packet id, "-10" */ -+ assert_true(validate_packet_id_window(&rel, 0xFFFFFFF6)); -+ -+ /* wrapped around packet id, "-11" */ -+ assert_false(validate_packet_id_window(&rel, 0xFFFFFFF5)); -+ assert_false(validate_packet_id_window(&rel, 0x80000000)); -+ -+ rel.packet_id = 0x80000000; -+ -+ /* near the signed/usigned integer area */ -+ assert_false(validate_packet_id_window(&rel, 0x80000001)); -+ assert_true(validate_packet_id_window(&rel, 0x7fffffff)); -+ assert_true(validate_packet_id_window(&rel, 0x7ffffff5)); -+ assert_false(validate_packet_id_window(&rel, 0x7ffffff4)); -+ -+ rel.packet_id = 0xFFFFFFFD; -+ assert_false(validate_packet_id_window(&rel, 0xFFFFFFFD)); -+ assert_false(validate_packet_id_window(&rel, 0)); -+ assert_false(validate_packet_id_window(&rel, 1)); -+ assert_false(validate_packet_id_window(&rel, 0xFFFFFFFE)); -+ assert_false(validate_packet_id_window(&rel, 0xFFFFFFFF)); -+ assert_true(validate_packet_id_window(&rel, 0xFFFFFFF3)); -+ assert_true(validate_packet_id_window(&rel, 0xFFFFFFF2)); -+ assert_false(validate_packet_id_window(&rel, 0xFFFFFFF1)); -+ -+ rel.packet_id = 500; -+ assert_false(validate_packet_id_window(&rel, 501)); -+ assert_true(validate_packet_id_window(&rel, 497)); -+ assert_true(validate_packet_id_window(&rel, 500 - (RELIABLE_CAPACITY - 1))); -+ assert_false(validate_packet_id_window(&rel, 500 - RELIABLE_CAPACITY)); -+} -+ -+ - int - main(void) - { -@@ -346,7 +393,8 @@ main(void) - test_packet_id_write_teardown), - - cmocka_unit_test(test_get_num_output_sequenced_available), -- cmocka_unit_test(test_copy_acks_to_lru) -+ cmocka_unit_test(test_copy_acks_to_lru), -+ cmocka_unit_test(test_packet_id_window) - - }; - diff --git a/package/openvpn/openvpn.mk b/package/openvpn/openvpn.mk index e6c36ef904..2b24c1524d 100644 --- a/package/openvpn/openvpn.mk +++ b/package/openvpn/openvpn.mk @@ -16,10 +16,6 @@ OPENVPN_CONF_OPTS = \ $(if $(BR2_STATIC_LIBS),--disable-plugins) OPENVPN_CONF_ENV = NETSTAT=/bin/netstat -# 0001-avoid-unbounded-reliable-tls-timeout.patch -# 0002-ignore-acks-for-packets-that-cannot-be-outstanding.patch -OPENVPN_IGNORE_CVES += CVE-2026-84732 - ifeq ($(BR2_PACKAGE_LIBNL)$(BR2_TOOLCHAIN_HEADERS_AT_LEAST_4_16),yy) OPENVPN_CONF_OPTS += --enable-dco OPENVPN_DEPENDENCIES += libnl