When reading message from the pipe, we first peek the pipe to get the size of the message waiting to be read and then read the message. A compromised OpenVPN process could send an excessively large message, which would result in a stack-allocated message buffer overflow.
To address this, we terminate the misbehaving process if the peeked message size exceeds the maximum allowable size. This commit is backported from 9b2693f in release/2.6 branch, fixing merge conflicts around &ring_buffer_handles and wins_cfg_message_t. CVE: 2024-27459 Microsoft case number: 85932 Reported-by: Vladimir Tokarev <vtoka...@microsoft.com> Change-Id: Ib5743cba0741ea11f9ee62c4978b2c6789b81ada Signed-off-by: Lev Stipakov <l...@openvpn.net> Acked-by: Heiko Hund <he...@openvpn.net> --- src/openvpnserv/interactive.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c index 5e3ff125..933b5c8c 100644 --- a/src/openvpnserv/interactive.c +++ b/src/openvpnserv/interactive.c @@ -111,6 +111,17 @@ typedef struct { HANDLE device; } ring_buffer_handles_t; +typedef union { + message_header_t header; + address_message_t address; + route_message_t route; + flush_neighbors_message_t flush_neighbors; + block_dns_message_t block_dns; + dns_cfg_message_t dns; + enable_dhcp_message_t dhcp; + register_ring_buffers_message_t rrb; + set_mtu_message_t mtu; +} pipe_message_t; static DWORD AddListItem(list_item_t **pfirst, LPVOID data) @@ -1444,18 +1455,7 @@ static VOID HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_handles, DWORD bytes, DWORD count, LPHANDLE events, undo_lists_t *lists) { - DWORD read; - union { - message_header_t header; - address_message_t address; - route_message_t route; - flush_neighbors_message_t flush_neighbors; - block_dns_message_t block_dns; - dns_cfg_message_t dns; - enable_dhcp_message_t dhcp; - register_ring_buffers_message_t rrb; - set_mtu_message_t mtu; - } msg; + pipe_message_t msg; ack_message_t ack = { .header = { .type = msg_acknowledgement, @@ -1465,7 +1465,7 @@ HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_ .error_number = ERROR_MESSAGE_DATA }; - read = ReadPipeAsync(pipe, &msg, bytes, count, events); + DWORD read = ReadPipeAsync(pipe, &msg, bytes, count, events); if (read != bytes || read < sizeof(msg.header) || read != msg.header.size) { goto out; @@ -1884,6 +1884,13 @@ RunOpenvpn(LPVOID p) break; } + if (bytes > sizeof(pipe_message_t)) + { + /* process at the other side of the pipe is misbehaving, shut it down */ + MsgToEventLog(MSG_FLAGS_ERROR, TEXT("OpenVPN process sent too large payload length to the pipe (%lu bytes), it will be terminated"), bytes); + break; + } + HandleMessage(ovpn_pipe, proc_info.hProcess, &ring_buffer_handles, bytes, 1, &exit_event, &undo_lists); } -- 2.42.0.windows.2 _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel