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