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