xref: /aosp_15_r20/external/cronet/net/socket/unix_domain_server_socket_posix_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 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 #include "net/socket/unix_domain_server_socket_posix.h"
6 
7 #include <memory>
8 #include <vector>
9 
10 #include "base/files/file_path.h"
11 #include "base/files/scoped_temp_dir.h"
12 #include "base/functional/bind.h"
13 #include "base/run_loop.h"
14 #include "base/test/task_environment.h"
15 #include "build/build_config.h"
16 #include "net/base/io_buffer.h"
17 #include "net/base/ip_endpoint.h"
18 #include "net/base/net_errors.h"
19 #include "net/base/test_completion_callback.h"
20 #include "net/socket/unix_domain_client_socket_posix.h"
21 #include "net/test/gtest_util.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 
25 using net::test::IsError;
26 using net::test::IsOk;
27 
28 namespace net {
29 namespace {
30 
31 const char kSocketFilename[] = "socket_for_testing";
32 const char kInvalidSocketPath[] = "/invalid/path";
33 
UserCanConnectCallback(bool allow_user,const UnixDomainServerSocket::Credentials & credentials)34 bool UserCanConnectCallback(bool allow_user,
35     const UnixDomainServerSocket::Credentials& credentials) {
36   // Here peers are running in same process.
37 #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
38   EXPECT_EQ(getpid(), credentials.process_id);
39 #endif
40   EXPECT_EQ(getuid(), credentials.user_id);
41   EXPECT_EQ(getgid(), credentials.group_id);
42   return allow_user;
43 }
44 
CreateAuthCallback(bool allow_user)45 UnixDomainServerSocket::AuthCallback CreateAuthCallback(bool allow_user) {
46   return base::BindRepeating(&UserCanConnectCallback, allow_user);
47 }
48 
49 class UnixDomainServerSocketTest : public testing::Test {
50  protected:
UnixDomainServerSocketTest()51   UnixDomainServerSocketTest() {
52     EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
53     socket_path_ = temp_dir_.GetPath().Append(kSocketFilename).value();
54   }
55 
56   base::ScopedTempDir temp_dir_;
57   std::string socket_path_;
58 };
59 
TEST_F(UnixDomainServerSocketTest,ListenWithInvalidPath)60 TEST_F(UnixDomainServerSocketTest, ListenWithInvalidPath) {
61   const bool kUseAbstractNamespace = false;
62   UnixDomainServerSocket server_socket(CreateAuthCallback(true),
63                                        kUseAbstractNamespace);
64   EXPECT_EQ(ERR_FILE_NOT_FOUND,
65             server_socket.BindAndListen(kInvalidSocketPath, /*backlog=*/1));
66 }
67 
TEST_F(UnixDomainServerSocketTest,ListenWithInvalidPathWithAbstractNamespace)68 TEST_F(UnixDomainServerSocketTest, ListenWithInvalidPathWithAbstractNamespace) {
69   const bool kUseAbstractNamespace = true;
70   UnixDomainServerSocket server_socket(CreateAuthCallback(true),
71                                        kUseAbstractNamespace);
72 #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
73   EXPECT_THAT(server_socket.BindAndListen(kInvalidSocketPath, /*backlog=*/1),
74               IsOk());
75 #else
76   EXPECT_EQ(ERR_ADDRESS_INVALID,
77             server_socket.BindAndListen(kInvalidSocketPath, /*backlog=*/1));
78 #endif
79 }
80 
TEST_F(UnixDomainServerSocketTest,ListenAgainAfterFailureWithInvalidPath)81 TEST_F(UnixDomainServerSocketTest, ListenAgainAfterFailureWithInvalidPath) {
82   const bool kUseAbstractNamespace = false;
83   UnixDomainServerSocket server_socket(CreateAuthCallback(true),
84                                        kUseAbstractNamespace);
85   EXPECT_EQ(ERR_FILE_NOT_FOUND,
86             server_socket.BindAndListen(kInvalidSocketPath, /*backlog=*/1));
87   EXPECT_THAT(server_socket.BindAndListen(socket_path_, /*backlog=*/1), IsOk());
88 }
89 
TEST_F(UnixDomainServerSocketTest,AcceptWithForbiddenUser)90 TEST_F(UnixDomainServerSocketTest, AcceptWithForbiddenUser) {
91   base::test::TaskEnvironment task_environment(
92       base::test::TaskEnvironment::MainThreadType::IO);
93 
94   const bool kUseAbstractNamespace = false;
95 
96   UnixDomainServerSocket server_socket(CreateAuthCallback(false),
97                                        kUseAbstractNamespace);
98   EXPECT_THAT(server_socket.BindAndListen(socket_path_, /*backlog=*/1), IsOk());
99 
100   std::unique_ptr<StreamSocket> accepted_socket;
101   TestCompletionCallback accept_callback;
102   EXPECT_EQ(ERR_IO_PENDING,
103             server_socket.Accept(&accepted_socket, accept_callback.callback()));
104   EXPECT_FALSE(accepted_socket);
105 
106   UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
107   EXPECT_FALSE(client_socket.IsConnected());
108 
109   // Connect() will return OK before the server rejects the connection.
110   TestCompletionCallback connect_callback;
111   int rv = connect_callback.GetResult(
112       client_socket.Connect(connect_callback.callback()));
113   ASSERT_THAT(rv, IsOk());
114 
115   // Try to read from the socket.
116   const int read_buffer_size = 10;
117   auto read_buffer = base::MakeRefCounted<IOBufferWithSize>(read_buffer_size);
118   TestCompletionCallback read_callback;
119   rv = read_callback.GetResult(client_socket.Read(
120       read_buffer.get(), read_buffer_size, read_callback.callback()));
121 
122   // The server should have disconnected gracefully, without sending any data.
123   ASSERT_EQ(0, rv);
124   EXPECT_FALSE(client_socket.IsConnected());
125 
126   // The server socket should not have called |accept_callback| or modified
127   // |accepted_socket|.
128   EXPECT_FALSE(accept_callback.have_result());
129   EXPECT_FALSE(accepted_socket);
130 }
131 
TEST_F(UnixDomainServerSocketTest,UnimplementedMethodsFail)132 TEST_F(UnixDomainServerSocketTest, UnimplementedMethodsFail) {
133   const bool kUseAbstractNamespace = false;
134   UnixDomainServerSocket server_socket(CreateAuthCallback(true),
135                                        kUseAbstractNamespace);
136 
137   IPEndPoint ep;
138   EXPECT_THAT(server_socket.Listen(ep, 0, /*ipv6_only=*/std::nullopt),
139               IsError(ERR_NOT_IMPLEMENTED));
140   EXPECT_EQ(ERR_NOT_IMPLEMENTED,
141       server_socket.ListenWithAddressAndPort(kInvalidSocketPath,
142                                              0,
143                                              /*backlog=*/1));
144 
145   EXPECT_THAT(server_socket.GetLocalAddress(&ep), IsError(ERR_ADDRESS_INVALID));
146 }
147 
148 // Normal cases including read/write are tested by UnixDomainClientSocketTest.
149 
150 }  // namespace
151 }  // namespace net
152