xref: /linux/tools/testing/selftests/net/af_unix/unix_connect.c (revision 8eb060e10185cfc97ef0200d197ec246ba0f9f8c)
1  // SPDX-License-Identifier: GPL-2.0
2  
3  #define _GNU_SOURCE
4  #include <sched.h>
5  
6  #include <stddef.h>
7  #include <stdio.h>
8  #include <unistd.h>
9  
10  #include <sys/socket.h>
11  #include <sys/un.h>
12  
13  #include "../../kselftest_harness.h"
14  
15  FIXTURE(unix_connect)
16  {
17  	int server, client;
18  	int family;
19  };
20  
21  FIXTURE_VARIANT(unix_connect)
22  {
23  	int type;
24  	char sun_path[8];
25  	int len;
26  	int flags;
27  	int err;
28  };
29  
30  FIXTURE_VARIANT_ADD(unix_connect, stream_pathname)
31  {
32  	.type = SOCK_STREAM,
33  	.sun_path = "test",
34  	.len = 4 + 1,
35  	.flags = 0,
36  	.err = 0,
37  };
38  
39  FIXTURE_VARIANT_ADD(unix_connect, stream_abstract)
40  {
41  	.type = SOCK_STREAM,
42  	.sun_path = "\0test",
43  	.len = 5,
44  	.flags = 0,
45  	.err = 0,
46  };
47  
48  FIXTURE_VARIANT_ADD(unix_connect, stream_pathname_netns)
49  {
50  	.type = SOCK_STREAM,
51  	.sun_path = "test",
52  	.len = 4 + 1,
53  	.flags = CLONE_NEWNET,
54  	.err = 0,
55  };
56  
57  FIXTURE_VARIANT_ADD(unix_connect, stream_abstract_netns)
58  {
59  	.type = SOCK_STREAM,
60  	.sun_path = "\0test",
61  	.len = 5,
62  	.flags = CLONE_NEWNET,
63  	.err = ECONNREFUSED,
64  };
65  
66  FIXTURE_VARIANT_ADD(unix_connect, dgram_pathname)
67  {
68  	.type = SOCK_DGRAM,
69  	.sun_path = "test",
70  	.len = 4 + 1,
71  	.flags = 0,
72  	.err = 0,
73  };
74  
75  FIXTURE_VARIANT_ADD(unix_connect, dgram_abstract)
76  {
77  	.type = SOCK_DGRAM,
78  	.sun_path = "\0test",
79  	.len = 5,
80  	.flags = 0,
81  	.err = 0,
82  };
83  
84  FIXTURE_VARIANT_ADD(unix_connect, dgram_pathname_netns)
85  {
86  	.type = SOCK_DGRAM,
87  	.sun_path = "test",
88  	.len = 4 + 1,
89  	.flags = CLONE_NEWNET,
90  	.err = 0,
91  };
92  
93  FIXTURE_VARIANT_ADD(unix_connect, dgram_abstract_netns)
94  {
95  	.type = SOCK_DGRAM,
96  	.sun_path = "\0test",
97  	.len = 5,
98  	.flags = CLONE_NEWNET,
99  	.err = ECONNREFUSED,
100  };
101  
102  FIXTURE_SETUP(unix_connect)
103  {
104  	self->family = AF_UNIX;
105  }
106  
107  FIXTURE_TEARDOWN(unix_connect)
108  {
109  	close(self->server);
110  	close(self->client);
111  
112  	if (variant->sun_path[0])
113  		remove("test");
114  }
115  
116  TEST_F(unix_connect, test)
117  {
118  	socklen_t addrlen;
119  	struct sockaddr_un addr = {
120  		.sun_family = self->family,
121  	};
122  	int err;
123  
124  	self->server = socket(self->family, variant->type, 0);
125  	ASSERT_NE(-1, self->server);
126  
127  	addrlen = offsetof(struct sockaddr_un, sun_path) + variant->len;
128  	memcpy(&addr.sun_path, variant->sun_path, variant->len);
129  
130  	err = bind(self->server, (struct sockaddr *)&addr, addrlen);
131  	ASSERT_EQ(0, err);
132  
133  	if (variant->type == SOCK_STREAM) {
134  		err = listen(self->server, 32);
135  		ASSERT_EQ(0, err);
136  	}
137  
138  	err = unshare(variant->flags);
139  	ASSERT_EQ(0, err);
140  
141  	self->client = socket(self->family, variant->type, 0);
142  	ASSERT_LT(0, self->client);
143  
144  	err = connect(self->client, (struct sockaddr *)&addr, addrlen);
145  	ASSERT_EQ(variant->err, err == -1 ? errno : 0);
146  }
147  
148  TEST_HARNESS_MAIN
149