• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "net/base/sockaddr_util_posix.h"
11 
12 #include <string.h>
13 
14 #include <sys/socket.h>
15 #include <sys/un.h>
16 
17 #include "net/base/sockaddr_storage.h"
18 #include "testing/gmock/include/gmock/gmock-matchers.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 
21 namespace net {
22 
23 namespace {
24 
MaxPathLength(SockaddrStorage * storage)25 size_t MaxPathLength(SockaddrStorage* storage) {
26   // |storage.addr_len| is initialized to the largest possible platform-
27   // dependent value. Subtracting the size of the initial fields in
28   // sockaddr_un gives us the longest permissible path value including space
29   // for an extra NUL character at the front or back.
30   return storage->addr_len - offsetof(struct sockaddr_un, sun_path) - 1;
31 }
32 
33 }  // namespace
34 
TEST(FillUnixAddressTest,SimpleAddress)35 TEST(FillUnixAddressTest, SimpleAddress) {
36   SockaddrStorage storage;
37   std::string path = "/tmp/socket/path";
38 
39   EXPECT_TRUE(
40       FillUnixAddress(path, /*use_abstract_namespace=*/false, &storage));
41 
42   // |storage.addr_len| indicates the full size of the data in sockaddr_un.
43   // The size is increased by one byte to include the string NUL terminator.
44   EXPECT_EQ(path.size() + 1U + offsetof(struct sockaddr_un, sun_path),
45             (unsigned int)storage.addr_len);
46 
47   struct sockaddr_un* socket_addr =
48       reinterpret_cast<struct sockaddr_un*>(storage.addr);
49   EXPECT_EQ(socket_addr->sun_family, AF_UNIX);
50 
51   // Implicit conversion to std::string for comparison is fine since the path
52   // is always NUL terminated.
53   EXPECT_EQ(socket_addr->sun_path, path);
54 }
55 
TEST(FillUnixAddressTest,PathEmpty)56 TEST(FillUnixAddressTest, PathEmpty) {
57   SockaddrStorage storage;
58   std::string path = "";
59   EXPECT_FALSE(
60       FillUnixAddress(path, /*use_abstract_namespace=*/false, &storage));
61 }
62 
TEST(FillUnixAddressTest,AddressMaxLength)63 TEST(FillUnixAddressTest, AddressMaxLength) {
64   SockaddrStorage storage;
65   size_t path_max = MaxPathLength(&storage);
66   std::string path(path_max, '0');
67 
68   EXPECT_TRUE(
69       FillUnixAddress(path, /*use_abstract_namespace=*/false, &storage));
70 
71   struct sockaddr_un* socket_addr =
72       reinterpret_cast<struct sockaddr_un*>(storage.addr);
73   EXPECT_EQ(socket_addr->sun_family, AF_UNIX);
74   EXPECT_EQ(socket_addr->sun_path, path);
75 }
76 
TEST(FillUnixAddressTest,AddressTooLong)77 TEST(FillUnixAddressTest, AddressTooLong) {
78   SockaddrStorage storage;
79   size_t path_max = MaxPathLength(&storage);
80   std::string path(path_max + 1, '0');
81 
82   EXPECT_FALSE(
83       FillUnixAddress(path, /*use_abstract_namespace=*/false, &storage));
84 }
85 
TEST(FillUnixAddressTest,AbstractLinuxAddress)86 TEST(FillUnixAddressTest, AbstractLinuxAddress) {
87   SockaddrStorage storage;
88   size_t path_max = MaxPathLength(&storage);
89   std::string path(path_max, '0');
90 
91 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
92   EXPECT_TRUE(FillUnixAddress(path, /*use_abstract_namespace=*/true, &storage));
93 
94   EXPECT_EQ(path.size() + 1U + offsetof(struct sockaddr_un, sun_path),
95             (unsigned int)storage.addr_len);
96 
97   struct sockaddr_un* socket_addr =
98       reinterpret_cast<struct sockaddr_un*>(storage.addr);
99   EXPECT_EQ(socket_addr->sun_family, AF_UNIX);
100 
101   // The path buffer is preceded by a NUL character for abstract Linux
102   // addresses.
103   EXPECT_EQ(socket_addr->sun_path[0], '\0');
104 
105   // The path string may not be NUL terminated, so do a buffer copy when
106   // converting to std::string.
107   std::string unix_path(reinterpret_cast<char*>(socket_addr->sun_path + 1),
108                         path.size());
109   EXPECT_EQ(unix_path, path);
110 #else
111   // Other platforms don't support the abstract Linux namespace.
112   EXPECT_FALSE(
113       FillUnixAddress(path, /*use_abstract_namespace=*/true, &storage));
114 #endif
115 }
116 
117 }  // namespace net
118