[llvm] [llvm][SupportTests] Fix a race condition in temporary socket construction (PR #190404)

Jon Roelofs via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 3 14:04:27 PDT 2026


https://github.com/jroelofs created https://github.com/llvm/llvm-project/pull/190404

createUniquePath doesn't make an exclusive lock on the filename until the socket is created, and thus the removal step in these tests was creating a TOCTOU race. Instead, arrange for the file to be cleaned up *after* we're done with it.

rdar://142847430

>From 6f6312d30dcf5bffdda6ff5ea2e84eb99d5f13fd Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Fri, 3 Apr 2026 13:59:38 -0700
Subject: [PATCH] [llvm][SupportTests] Fix a race condition in temporary socket
 construction

createUniquePath doesn't make an exclusive lock on the filename until the socket
is created, and thus the removal step in these tests was creating a TOCTOU race.
Instead, arrange for the file to be cleaned up *after* we're done with it.

rdar://142847430
---
 .../Support/raw_socket_stream_test.cpp          | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/llvm/unittests/Support/raw_socket_stream_test.cpp b/llvm/unittests/Support/raw_socket_stream_test.cpp
index fd4d7f1e28030..0a95d22993f79 100644
--- a/llvm/unittests/Support/raw_socket_stream_test.cpp
+++ b/llvm/unittests/Support/raw_socket_stream_test.cpp
@@ -1,4 +1,5 @@
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/FileSystem.h"
@@ -34,9 +35,7 @@ TEST(raw_socket_streamTest, CLIENT_TO_SERVER_AND_SERVER_TO_CLIENT) {
   SmallString<100> SocketPath;
   llvm::sys::fs::createUniquePath("client_server_comms-%%%%%%.sock", SocketPath,
                                   true);
-
-  // Make sure socket file does not exist. May still be there from the last test
-  std::remove(SocketPath.c_str());
+  auto Cleanup = llvm::scope_exit([&] { std::remove(SocketPath.c_str()); });
 
   Expected<ListeningSocket> MaybeServerListener =
       ListeningSocket::createUnix(SocketPath);
@@ -76,9 +75,7 @@ TEST(raw_socket_streamTest, READ_WITH_TIMEOUT) {
   SmallString<100> SocketPath;
   llvm::sys::fs::createUniquePath("read_with_timeout-%%%%%%.sock", SocketPath,
                                   true);
-
-  // Make sure socket file does not exist. May still be there from the last test
-  std::remove(SocketPath.c_str());
+  auto Cleanup = llvm::scope_exit([&] { std::remove(SocketPath.c_str()); });
 
   Expected<ListeningSocket> MaybeServerListener =
       ListeningSocket::createUnix(SocketPath);
@@ -109,9 +106,7 @@ TEST(raw_socket_streamTest, ACCEPT_WITH_TIMEOUT) {
   SmallString<100> SocketPath;
   llvm::sys::fs::createUniquePath("accept_with_timeout-%%%%%%.sock", SocketPath,
                                   true);
-
-  // Make sure socket file does not exist. May still be there from the last test
-  std::remove(SocketPath.c_str());
+  auto Cleanup = llvm::scope_exit([&] { std::remove(SocketPath.c_str()); });
 
   Expected<ListeningSocket> MaybeServerListener =
       ListeningSocket::createUnix(SocketPath);
@@ -131,9 +126,7 @@ TEST(raw_socket_streamTest, ACCEPT_WITH_SHUTDOWN) {
   SmallString<100> SocketPath;
   llvm::sys::fs::createUniquePath("accept_with_shutdown-%%%%%%.sock",
                                   SocketPath, true);
-
-  // Make sure socket file does not exist. May still be there from the last test
-  std::remove(SocketPath.c_str());
+  auto Cleanup = llvm::scope_exit([&] { std::remove(SocketPath.c_str()); });
 
   Expected<ListeningSocket> MaybeServerListener =
       ListeningSocket::createUnix(SocketPath);



More information about the llvm-commits mailing list