mirror of
https://gitlab.com/buildroot.org/buildroot.git
synced 2026-10-01 06:21:56 -09:00
Revert "package/openvpn: add patches for CVE-2026-84732"
Commit 1afe223d4c 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 <thomas.perale@mind.be>
This commit is contained in:
@@ -1,129 +0,0 @@
|
||||
From: Arne Schwabe <arne@rfc2549.org>
|
||||
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) <mark.bregman@fox-it.com>
|
||||
CVE: 2026-84732
|
||||
Change-Id: Id8ac9c48a8f751b0df95c6436ad3fbff3c4ae4a6
|
||||
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
|
||||
Signed-off-by: Razvan Cojocaru <razvanc@mailbox.org>
|
||||
Acked-by: MaxF <max@max-fillinger.net>
|
||||
|
||||
---
|
||||
Upstream: https://github.com/OpenVPN/openvpn/commit/207ac5f47e46565881dcec385020ebdcb682caa4
|
||||
CVE: CVE-2026-84732
|
||||
Signed-off-by: Titouan Christophe <titouan.christophe@mind.be>
|
||||
---
|
||||
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
|
||||
@@ -1,206 +0,0 @@
|
||||
From: Arne Schwabe <arne@rfc2549.org>
|
||||
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) <mark.bregman@fox-it.com>
|
||||
CVE: 2026-84732
|
||||
Change-Id: I944478767b52a1b9bf6a65373ce0544c69cb1012
|
||||
Signed-off-by: Arne Schwabe <arne@rfc2549.org>
|
||||
Signed-off-by: Razvan Cojocaru <razvanc@mailbox.org>
|
||||
Acked-by: MaxF <max@max-fillinger.net>
|
||||
|
||||
---
|
||||
Upstream: https://github.com/OpenVPN/openvpn/commit/d988ef4508e63b28c8e3efcb9f62eb8c836907fe
|
||||
CVE: CVE-2026-84732
|
||||
Signed-off-by: Titouan Christophe <titouan.christophe@mind.be>
|
||||
---
|
||||
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)
|
||||
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user