1 // SPDX-License-Identifier: GPL-2.0 2 3 #define _GNU_SOURCE 4 #include <errno.h> 5 #include <fcntl.h> 6 #include <linux/netlink.h> 7 #include <signal.h> 8 #include <stdbool.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <sys/prctl.h> 13 #include <sys/socket.h> 14 #include <sched.h> 15 #include <sys/eventfd.h> 16 #include <sys/stat.h> 17 #include <sys/syscall.h> 18 #include <sys/types.h> 19 #include <sys/wait.h> 20 #include <unistd.h> 21 22 #include "../kselftest_harness.h" 23 24 #define __DEV_FULL "/sys/devices/virtual/mem/full/uevent" 25 #define __UEVENT_BUFFER_SIZE (2048 * 2) 26 #define __UEVENT_HEADER "add@/devices/virtual/mem/full" 27 #define __UEVENT_HEADER_LEN sizeof("add@/devices/virtual/mem/full") 28 #define __UEVENT_LISTEN_ALL -1 29 30 ssize_t read_nointr(int fd, void *buf, size_t count) 31 { 32 ssize_t ret; 33 34 again: 35 ret = read(fd, buf, count); 36 if (ret < 0 && errno == EINTR) 37 goto again; 38 39 return ret; 40 } 41 42 ssize_t write_nointr(int fd, const void *buf, size_t count) 43 { 44 ssize_t ret; 45 46 again: 47 ret = write(fd, buf, count); 48 if (ret < 0 && errno == EINTR) 49 goto again; 50 51 return ret; 52 } 53 54 int wait_for_pid(pid_t pid) 55 { 56 int status, ret; 57 58 again: 59 ret = waitpid(pid, &status, 0); 60 if (ret == -1) { 61 if (errno == EINTR) 62 goto again; 63 64 return -1; 65 } 66 67 if (ret != pid) 68 goto again; 69 70 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) 71 return -1; 72 73 return 0; 74 } 75 76 static int uevent_listener(unsigned long post_flags, bool expect_uevent, 77 int sync_fd) 78 { 79 int sk_fd, ret; 80 socklen_t sk_addr_len; 81 int fret = -1, rcv_buf_sz = __UEVENT_BUFFER_SIZE; 82 uint64_t sync_add = 1; 83 struct sockaddr_nl sk_addr = { 0 }, rcv_addr = { 0 }; 84 char buf[__UEVENT_BUFFER_SIZE] = { 0 }; 85 struct iovec iov = { buf, __UEVENT_BUFFER_SIZE }; 86 char control[CMSG_SPACE(sizeof(struct ucred))]; 87 struct msghdr hdr = { 88 &rcv_addr, sizeof(rcv_addr), &iov, 1, 89 control, sizeof(control), 0, 90 }; 91 92 sk_fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, 93 NETLINK_KOBJECT_UEVENT); 94 if (sk_fd < 0) { 95 fprintf(stderr, "%s - Failed to open uevent socket\n", strerror(errno)); 96 return -1; 97 } 98 99 ret = setsockopt(sk_fd, SOL_SOCKET, SO_RCVBUF, &rcv_buf_sz, 100 sizeof(rcv_buf_sz)); 101 if (ret < 0) { 102 fprintf(stderr, "%s - Failed to set socket options\n", strerror(errno)); 103 goto on_error; 104 } 105 106 sk_addr.nl_family = AF_NETLINK; 107 sk_addr.nl_groups = __UEVENT_LISTEN_ALL; 108 109 sk_addr_len = sizeof(sk_addr); 110 ret = bind(sk_fd, (struct sockaddr *)&sk_addr, sk_addr_len); 111 if (ret < 0) { 112 fprintf(stderr, "%s - Failed to bind socket\n", strerror(errno)); 113 goto on_error; 114 } 115 116 ret = getsockname(sk_fd, (struct sockaddr *)&sk_addr, &sk_addr_len); 117 if (ret < 0) { 118 fprintf(stderr, "%s - Failed to retrieve socket name\n", strerror(errno)); 119 goto on_error; 120 } 121 122 if ((size_t)sk_addr_len != sizeof(sk_addr)) { 123 fprintf(stderr, "Invalid socket address size\n"); 124 goto on_error; 125 } 126 127 if (post_flags & CLONE_NEWUSER) { 128 ret = unshare(CLONE_NEWUSER); 129 if (ret < 0) { 130 fprintf(stderr, 131 "%s - Failed to unshare user namespace\n", 132 strerror(errno)); 133 goto on_error; 134 } 135 } 136 137 if (post_flags & CLONE_NEWNET) { 138 ret = unshare(CLONE_NEWNET); 139 if (ret < 0) { 140 fprintf(stderr, 141 "%s - Failed to unshare network namespace\n", 142 strerror(errno)); 143 goto on_error; 144 } 145 } 146 147 ret = write_nointr(sync_fd, &sync_add, sizeof(sync_add)); 148 close(sync_fd); 149 if (ret != sizeof(sync_add)) { 150 fprintf(stderr, "Failed to synchronize with parent process\n"); 151 goto on_error; 152 } 153 154 fret = 0; 155 for (;;) { 156 ssize_t r; 157 158 r = recvmsg(sk_fd, &hdr, 0); 159 if (r <= 0) { 160 fprintf(stderr, "%s - Failed to receive uevent\n", strerror(errno)); 161 ret = -1; 162 break; 163 } 164 165 /* ignore libudev messages */ 166 if (memcmp(buf, "libudev", 8) == 0) 167 continue; 168 169 /* ignore uevents we didn't trigger */ 170 if (memcmp(buf, __UEVENT_HEADER, __UEVENT_HEADER_LEN) != 0) 171 continue; 172 173 if (!expect_uevent) { 174 fprintf(stderr, "Received unexpected uevent:\n"); 175 ret = -1; 176 } 177 178 if (TH_LOG_ENABLED) { 179 /* If logging is enabled dump the received uevent. */ 180 (void)write_nointr(STDERR_FILENO, buf, r); 181 (void)write_nointr(STDERR_FILENO, "\n", 1); 182 } 183 184 break; 185 } 186 187 on_error: 188 close(sk_fd); 189 190 return fret; 191 } 192 193 int trigger_uevent(unsigned int times) 194 { 195 int fd, ret; 196 unsigned int i; 197 198 fd = open(__DEV_FULL, O_RDWR | O_CLOEXEC); 199 if (fd < 0) { 200 if (errno != ENOENT) 201 return -EINVAL; 202 203 return -1; 204 } 205 206 for (i = 0; i < times; i++) { 207 ret = write_nointr(fd, "add\n", sizeof("add\n") - 1); 208 if (ret < 0) { 209 fprintf(stderr, "Failed to trigger uevent\n"); 210 break; 211 } 212 } 213 close(fd); 214 215 return ret; 216 } 217 218 int set_death_signal(void) 219 { 220 int ret; 221 pid_t ppid; 222 223 ret = prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); 224 225 /* Check whether we have been orphaned. */ 226 ppid = getppid(); 227 if (ppid == 1) { 228 pid_t self; 229 230 self = getpid(); 231 ret = kill(self, SIGKILL); 232 } 233 234 if (ret < 0) 235 return -1; 236 237 return 0; 238 } 239 240 static int do_test(unsigned long pre_flags, unsigned long post_flags, 241 bool expect_uevent, int sync_fd) 242 { 243 int ret; 244 uint64_t wait_val; 245 pid_t pid; 246 sigset_t mask; 247 sigset_t orig_mask; 248 struct timespec timeout; 249 250 sigemptyset(&mask); 251 sigaddset(&mask, SIGCHLD); 252 253 ret = sigprocmask(SIG_BLOCK, &mask, &orig_mask); 254 if (ret < 0) { 255 fprintf(stderr, "%s- Failed to block SIGCHLD\n", strerror(errno)); 256 return -1; 257 } 258 259 pid = fork(); 260 if (pid < 0) { 261 fprintf(stderr, "%s - Failed to fork() new process\n", strerror(errno)); 262 return -1; 263 } 264 265 if (pid == 0) { 266 /* Make sure that we go away when our parent dies. */ 267 ret = set_death_signal(); 268 if (ret < 0) { 269 fprintf(stderr, "Failed to set PR_SET_PDEATHSIG to SIGKILL\n"); 270 _exit(EXIT_FAILURE); 271 } 272 273 if (pre_flags & CLONE_NEWUSER) { 274 ret = unshare(CLONE_NEWUSER); 275 if (ret < 0) { 276 fprintf(stderr, 277 "%s - Failed to unshare user namespace\n", 278 strerror(errno)); 279 _exit(EXIT_FAILURE); 280 } 281 } 282 283 if (pre_flags & CLONE_NEWNET) { 284 ret = unshare(CLONE_NEWNET); 285 if (ret < 0) { 286 fprintf(stderr, 287 "%s - Failed to unshare network namespace\n", 288 strerror(errno)); 289 _exit(EXIT_FAILURE); 290 } 291 } 292 293 if (uevent_listener(post_flags, expect_uevent, sync_fd) < 0) 294 _exit(EXIT_FAILURE); 295 296 _exit(EXIT_SUCCESS); 297 } 298 299 ret = read_nointr(sync_fd, &wait_val, sizeof(wait_val)); 300 if (ret != sizeof(wait_val)) { 301 fprintf(stderr, "Failed to synchronize with child process\n"); 302 _exit(EXIT_FAILURE); 303 } 304 305 /* Trigger 10 uevents to account for the case where the kernel might 306 * drop some. 307 */ 308 ret = trigger_uevent(10); 309 if (ret < 0) 310 fprintf(stderr, "Failed triggering uevents\n"); 311 312 /* Wait for 2 seconds before considering this failed. This should be 313 * plenty of time for the kernel to deliver the uevent even under heavy 314 * load. 315 */ 316 timeout.tv_sec = 2; 317 timeout.tv_nsec = 0; 318 319 again: 320 ret = sigtimedwait(&mask, NULL, &timeout); 321 if (ret < 0) { 322 if (errno == EINTR) 323 goto again; 324 325 if (!expect_uevent) 326 ret = kill(pid, SIGTERM); /* success */ 327 else 328 ret = kill(pid, SIGUSR1); /* error */ 329 if (ret < 0) 330 return -1; 331 } 332 333 ret = wait_for_pid(pid); 334 if (ret < 0) 335 return -1; 336 337 return ret; 338 } 339 340 static void signal_handler(int sig) 341 { 342 if (sig == SIGTERM) 343 _exit(EXIT_SUCCESS); 344 345 _exit(EXIT_FAILURE); 346 } 347 348 TEST(uevent_filtering) 349 { 350 int ret, sync_fd; 351 struct sigaction act; 352 353 if (geteuid()) { 354 TH_LOG("Uevent filtering tests require root privileges. Skipping test"); 355 _exit(KSFT_SKIP); 356 } 357 358 ret = access(__DEV_FULL, F_OK); 359 EXPECT_EQ(0, ret) { 360 if (errno == ENOENT) { 361 TH_LOG(__DEV_FULL " does not exist. Skipping test"); 362 _exit(KSFT_SKIP); 363 } 364 365 _exit(KSFT_FAIL); 366 } 367 368 act.sa_handler = signal_handler; 369 act.sa_flags = 0; 370 sigemptyset(&act.sa_mask); 371 372 ret = sigaction(SIGTERM, &act, NULL); 373 ASSERT_EQ(0, ret); 374 375 sync_fd = eventfd(0, EFD_CLOEXEC); 376 ASSERT_GE(sync_fd, 0); 377 378 /* 379 * Setup: 380 * - Open uevent listening socket in initial network namespace owned by 381 * initial user namespace. 382 * - Trigger uevent in initial network namespace owned by initial user 383 * namespace. 384 * Expected Result: 385 * - uevent listening socket receives uevent 386 */ 387 ret = do_test(0, 0, true, sync_fd); 388 ASSERT_EQ(0, ret) { 389 goto do_cleanup; 390 } 391 392 /* 393 * Setup: 394 * - Open uevent listening socket in non-initial network namespace 395 * owned by initial user namespace. 396 * - Trigger uevent in initial network namespace owned by initial user 397 * namespace. 398 * Expected Result: 399 * - uevent listening socket receives uevent 400 */ 401 ret = do_test(CLONE_NEWNET, 0, true, sync_fd); 402 ASSERT_EQ(0, ret) { 403 goto do_cleanup; 404 } 405 406 /* 407 * Setup: 408 * - unshare user namespace 409 * - Open uevent listening socket in initial network namespace 410 * owned by initial user namespace. 411 * - Trigger uevent in initial network namespace owned by initial user 412 * namespace. 413 * Expected Result: 414 * - uevent listening socket receives uevent 415 */ 416 ret = do_test(CLONE_NEWUSER, 0, true, sync_fd); 417 ASSERT_EQ(0, ret) { 418 goto do_cleanup; 419 } 420 421 /* 422 * Setup: 423 * - Open uevent listening socket in non-initial network namespace 424 * owned by non-initial user namespace. 425 * - Trigger uevent in initial network namespace owned by initial user 426 * namespace. 427 * Expected Result: 428 * - uevent listening socket receives no uevent 429 */ 430 ret = do_test(CLONE_NEWUSER | CLONE_NEWNET, 0, false, sync_fd); 431 ASSERT_EQ(0, ret) { 432 goto do_cleanup; 433 } 434 435 /* 436 * Setup: 437 * - Open uevent listening socket in initial network namespace 438 * owned by initial user namespace. 439 * - unshare network namespace 440 * - Trigger uevent in initial network namespace owned by initial user 441 * namespace. 442 * Expected Result: 443 * - uevent listening socket receives uevent 444 */ 445 ret = do_test(0, CLONE_NEWNET, true, sync_fd); 446 ASSERT_EQ(0, ret) { 447 goto do_cleanup; 448 } 449 450 /* 451 * Setup: 452 * - Open uevent listening socket in initial network namespace 453 * owned by initial user namespace. 454 * - unshare user namespace 455 * - Trigger uevent in initial network namespace owned by initial user 456 * namespace. 457 * Expected Result: 458 * - uevent listening socket receives uevent 459 */ 460 ret = do_test(0, CLONE_NEWUSER, true, sync_fd); 461 ASSERT_EQ(0, ret) { 462 goto do_cleanup; 463 } 464 465 /* 466 * Setup: 467 * - Open uevent listening socket in initial network namespace 468 * owned by initial user namespace. 469 * - unshare user namespace 470 * - unshare network namespace 471 * - Trigger uevent in initial network namespace owned by initial user 472 * namespace. 473 * Expected Result: 474 * - uevent listening socket receives uevent 475 */ 476 ret = do_test(0, CLONE_NEWUSER | CLONE_NEWNET, true, sync_fd); 477 ASSERT_EQ(0, ret) { 478 goto do_cleanup; 479 } 480 481 do_cleanup: 482 close(sync_fd); 483 } 484 485 TEST_HARNESS_MAIN 486