[llvm] [orc-rt] SimpleRemoteCAOverSocket: require a stream socket. (PR #226676)
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 26 03:41:35 PDT 2026
https://github.com/lhames created https://github.com/llvm/llvm-project/pull/226676
SimpleRemote framing reads each message in as many parts as the socket delivers it, which a socket that preserves message boundaries (datagram, seqpacket) would truncate. Check SO_TYPE up front and reject anything but SOCK_STREAM; the socket is owned by then, so it is closed on failure.
Assisted-by: Claude
>From e51f6717f6d50982204c8dc7b2efb0bcef8c338e Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at gmail.com>
Date: Sat, 26 Sep 2026 20:23:43 +1000
Subject: [PATCH] [orc-rt] SimpleRemoteCAOverSocket: require a stream socket.
SimpleRemote framing reads each message in as many parts as the socket
delivers it, which a socket that preserves message boundaries (datagram,
seqpacket) would truncate. Check SO_TYPE up front and reject anything
but SOCK_STREAM; the socket is owned by then, so it is closed on
failure.
Assisted-by: Claude
---
.../bedrock/sps/SimpleRemoteCAOverSocket.h | 3 ++-
.../sys/posix/sps/SimpleRemoteCAOverSocket.cpp | 10 ++++++++++
.../bedrock/sps/SimpleRemoteCAOverSocketTest.cpp | 16 ++++++++++++++++
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/orc-rt/include/orc-rt/bedrock/sps/SimpleRemoteCAOverSocket.h b/orc-rt/include/orc-rt/bedrock/sps/SimpleRemoteCAOverSocket.h
index e523933e5cd48..afd2bbfc851d2 100644
--- a/orc-rt/include/orc-rt/bedrock/sps/SimpleRemoteCAOverSocket.h
+++ b/orc-rt/include/orc-rt/bedrock/sps/SimpleRemoteCAOverSocket.h
@@ -23,7 +23,8 @@
namespace orc_rt {
/// Creates a ControllerAccess that carries SimpleRemote messages over Sock,
-/// taking ownership of it. Sock must be a connected stream socket.
+/// taking ownership of it. Fails if Sock is not a stream socket. Sock must be
+/// connected.
///
/// The result is ready to hand to Session::attach, which is what starts the
/// conversation; nothing is sent before then.
diff --git a/orc-rt/lib/bedrock/sys/posix/sps/SimpleRemoteCAOverSocket.cpp b/orc-rt/lib/bedrock/sys/posix/sps/SimpleRemoteCAOverSocket.cpp
index d70ec224b546b..739aa580bf3b5 100644
--- a/orc-rt/lib/bedrock/sys/posix/sps/SimpleRemoteCAOverSocket.cpp
+++ b/orc-rt/lib/bedrock/sys/posix/sps/SimpleRemoteCAOverSocket.cpp
@@ -234,6 +234,16 @@ WrapperFunctionBuffer SocketSimpleRemoteCA::IncomingMessage::take() {
Expected<std::shared_ptr<SocketSimpleRemoteCA>>
SocketSimpleRemoteCA::Create(Session &S, SocketHandle Sock) {
// Sock is owned here, so every early return below closes it.
+
+ // This class assumes a byte stream, so check that this is a SOCK_STREAM.
+ int Type;
+ socklen_t TypeLen = sizeof(Type);
+ if (::getsockopt(Sock.get(), SOL_SOCKET, SO_TYPE, &Type, &TypeLen) != 0)
+ return makeError("getsockopt(SO_TYPE)", errno);
+ if (Type != SOCK_STREAM)
+ return make_error<StringError>(
+ "SimpleRemote over a socket requires a stream socket");
+
if (auto Err = setNonBlocking(Sock.get()))
return std::move(Err);
diff --git a/orc-rt/test/unit/bedrock/sps/SimpleRemoteCAOverSocketTest.cpp b/orc-rt/test/unit/bedrock/sps/SimpleRemoteCAOverSocketTest.cpp
index 4878c98137ed9..9a51eb7a58c2b 100644
--- a/orc-rt/test/unit/bedrock/sps/SimpleRemoteCAOverSocketTest.cpp
+++ b/orc-rt/test/unit/bedrock/sps/SimpleRemoteCAOverSocketTest.cpp
@@ -27,6 +27,7 @@
#include "BedrockTestUtils.h"
#include "CommonTestUtils.h"
+#include "ErrorMatchers.h"
#include "bedrock/SocketTestUtils.h"
#include "orc-rt-internal/support/Endian.h"
@@ -44,6 +45,8 @@
using namespace orc_rt;
using namespace orc_rt::test;
+using ::testing::HasSubstr;
+
namespace orc_rt {
/// Plays the controller against a SimpleRemote CA running over a socket.
@@ -281,6 +284,19 @@ void outOfBandErrorWrapper(orc_rt_SessionRef S,
} // namespace
+TEST_F(SimpleRemoteCAOverSocketTest, RejectsANonStreamSocket) {
+ // The framing reads a message in as many parts as the stream delivers it, so
+ // a socket that preserves message boundaries would truncate one.
+ auto H = makeNativeNonStreamSocket();
+ ASSERT_TRUE(H.has_value()) << "could not create a socket for the test";
+
+ EXPECT_THAT_EXPECTED(
+ createSimpleRemoteCAOverSocket(S, SocketHandle(*H)),
+ FailedWithMessage(HasSubstr("requires a stream socket")));
+ EXPECT_FALSE(isNativeSocketOpen(*H))
+ << "a rejected socket is still owned, and must be closed";
+}
+
TEST_F(SimpleRemoteCAOverSocketTest, SetupIsSentOnConnect) {
ASSERT_FALSE(!!attachOverSocket());
More information about the llvm-commits
mailing list