[lldb] Fix DomainSocket::GetSocketName for unnamed sockets
authorPavel Labath <pavel@labath.sk>
Thu, 23 Sep 2021 09:31:33 +0000 (11:31 +0200)
committerPavel Labath <pavel@labath.sk>
Thu, 23 Sep 2021 10:30:18 +0000 (12:30 +0200)
getpeername will return addrlen = 2 (sizeof sa_family_t) for unnamed
sockets (those not assigned a name with bind(2)). This is typically true
for client sockets as well as those created by socketpair(2).

This GetSocketName used to crash for sockets which were connected to
these kinds of sockets. Now it returns an empty string.

lldb/source/Host/posix/DomainSocket.cpp
lldb/unittests/Host/SocketTest.cpp

index 7322b15..790458e 100644 (file)
@@ -127,29 +127,34 @@ void DomainSocket::DeleteSocketFile(llvm::StringRef name) {
 }
 
 std::string DomainSocket::GetSocketName() const {
-  if (m_socket != kInvalidSocketValue) {
-    struct sockaddr_un saddr_un;
-    saddr_un.sun_family = AF_UNIX;
-    socklen_t sock_addr_len = sizeof(struct sockaddr_un);
-    if (::getpeername(m_socket, (struct sockaddr *)&saddr_un, &sock_addr_len) ==
-        0) {
-      std::string name(saddr_un.sun_path + GetNameOffset(),
-                       sock_addr_len -
-                           offsetof(struct sockaddr_un, sun_path) -
+  if (m_socket == kInvalidSocketValue)
+    return "";
+
+  struct sockaddr_un saddr_un;
+  saddr_un.sun_family = AF_UNIX;
+  socklen_t sock_addr_len = sizeof(struct sockaddr_un);
+  if (::getpeername(m_socket, (struct sockaddr *)&saddr_un, &sock_addr_len) !=
+      0)
+    return "";
+
+  if (sock_addr_len <= offsetof(struct sockaddr_un, sun_path))
+    return ""; // Unnamed domain socket
+
+  llvm::StringRef name(saddr_un.sun_path + GetNameOffset(),
+                       sock_addr_len - offsetof(struct sockaddr_un, sun_path) -
                            GetNameOffset());
-      if (name.back() == '\0') name.pop_back();
-      return name;
-    }
-  }
-  return "";
+  if (name.back() == '\0')
+    name = name.drop_back();
+
+  return name.str();
 }
 
 std::string DomainSocket::GetRemoteConnectionURI() const {
-  if (m_socket != kInvalidSocketValue) {
-    return std::string(llvm::formatv(
-        "{0}://{1}",
-        GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect",
-        GetSocketName()));
-  }
-  return "";
+  std::string name = GetSocketName();
+  if (name.empty())
+    return name;
+
+  return llvm::formatv(
+      "{0}://{1}",
+      GetNameOffset() == 0 ? "unix-connect" : "unix-abstract-connect", name);
 }
index 27d42f8..5593b77 100644 (file)
@@ -225,6 +225,8 @@ TEST_P(SocketTest, DomainGetConnectURI) {
   EXPECT_TRUE(UriParser::Parse(uri, scheme, hostname, port, path));
   EXPECT_EQ(scheme, "unix-connect");
   EXPECT_EQ(path, domain_path);
+
+  EXPECT_EQ(socket_b_up->GetRemoteConnectionURI(), "");
 }
 #endif