[Openvpn-devel,v2] Harden interactive service pipe

Message ID 20251124165311.14859-1-gert@greenie.muc.de
State New
Headers show
Series [Openvpn-devel,v2] Harden interactive service pipe | expand

Commit Message

Gert Doering Nov. 24, 2025, 4:53 p.m. UTC
From: Selva Nair <selva.nair@gmail.com>

- Append a version 4 uuid to ovpn_pipe_name to make it less
  predictable
- Do not allow remote access to the pipe

This greatly reduces the possibility of a rogue process racing to
open the pipe before CreateFile() is called in the worker thread.

Reported-by: Marc Heuse <marc@srlabs.de>
Change-Id: Ie66a142751354e421d48b273784fc79bcb9f7208
Signed-off-by: Selva Nair <selva.nair@gmail.com>
Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1396
---

This change was reviewed on Gerrit and approved by at least one
developer. I request to merge it to master.

Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1396
This mail reflects revision 2 of this Change.

Acked-by according to Gerrit (reflected above):

Comments

Gert Doering Nov. 24, 2025, 5:51 p.m. UTC | #1
Thanks for taking this on.

I've stared lightly at the code and it looks good.  Lev has tested it
and it does what it says on the lid - make the pipe name nearly impossible
to guess.  Path name length is also not a problem (max 256, plenty of
room to grow).

Your patch has been applied to the master branch.

I think the release/2.6 branch would also benefit from this one (at
least) but it does not want to get in - TEXT() vs. L() changes, at least.


commit 05d0808ee65d68691b0133f5fc3c09bfdba5259d (master)
Author: Selva Nair
Date:   Mon Nov 24 17:53:06 2025 +0100

     Harden interactive service pipe

     Signed-off-by: Selva Nair <selva.nair@gmail.com>
     Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/1396
     Message-Id: <20251124165311.14859-1-gert@greenie.muc.de>
     URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg34638.html
     Signed-off-by: Gert Doering <gert@greenie.muc.de>


--
kind regards,

Gert Doering

Patch

diff --git a/src/openvpnserv/interactive.c b/src/openvpnserv/interactive.c
index 0712986..7a0a075 100644
--- a/src/openvpnserv/interactive.c
+++ b/src/openvpnserv/interactive.c
@@ -3398,12 +3398,29 @@ 
         goto out;
     }
 
+    UUID pipe_uuid;
+    RPC_STATUS rpc_stat = UuidCreate(&pipe_uuid);
+    if (rpc_stat != RPC_S_OK)
+    {
+        ReturnError(pipe, rpc_stat, L"UuidCreate", 1, &exit_event);
+        goto out;
+    }
+
+    RPC_WSTR pipe_uuid_str = NULL;
+    rpc_stat = UuidToStringW(&pipe_uuid, &pipe_uuid_str);
+    if (rpc_stat != RPC_S_OK)
+    {
+        ReturnError(pipe, rpc_stat, L"UuidToString", 1, &exit_event);
+        goto out;
+    }
     swprintf(ovpn_pipe_name, _countof(ovpn_pipe_name),
-             L"\\\\.\\pipe\\" _L(PACKAGE) L"%ls\\service_%lu", service_instance,
-             GetCurrentThreadId());
+             L"\\\\.\\pipe\\" _L(PACKAGE) L"%ls\\service_%lu_%ls", service_instance,
+             GetCurrentThreadId(), pipe_uuid_str);
+    RpcStringFree(&pipe_uuid_str);
+
     ovpn_pipe = CreateNamedPipe(
         ovpn_pipe_name, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
-        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 128, 128, 0, NULL);
+        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, 1, 128, 128, 0, NULL);
     if (ovpn_pipe == INVALID_HANDLE_VALUE)
     {
         ReturnLastError(pipe, L"CreateNamedPipe");