1 // SPDX-License-Identifier: GPL-2.0 2 #define _GNU_SOURCE 3 #include <sched.h> 4 #include <stdlib.h> 5 #include <sys/types.h> 6 #include <sys/socket.h> 7 8 #include "test_progs.h" 9 #include "cap_helpers.h" 10 #include "bind_perm.skel.h" 11 12 static int duration; 13 14 static int create_netns(void) 15 { 16 if (!ASSERT_OK(unshare(CLONE_NEWNET), "create netns")) 17 return -1; 18 19 return 0; 20 } 21 22 void try_bind(int family, int port, int expected_errno) 23 { 24 struct sockaddr_storage addr = {}; 25 struct sockaddr_in6 *sin6; 26 struct sockaddr_in *sin; 27 int fd = -1; 28 29 fd = socket(family, SOCK_STREAM, 0); 30 if (CHECK(fd < 0, "fd", "errno %d", errno)) 31 goto close_socket; 32 33 if (family == AF_INET) { 34 sin = (struct sockaddr_in *)&addr; 35 sin->sin_family = family; 36 sin->sin_port = htons(port); 37 } else { 38 sin6 = (struct sockaddr_in6 *)&addr; 39 sin6->sin6_family = family; 40 sin6->sin6_port = htons(port); 41 } 42 43 errno = 0; 44 bind(fd, (struct sockaddr *)&addr, sizeof(addr)); 45 ASSERT_EQ(errno, expected_errno, "bind"); 46 47 close_socket: 48 if (fd >= 0) 49 close(fd); 50 } 51 52 void test_bind_perm(void) 53 { 54 const __u64 net_bind_svc_cap = 1ULL << CAP_NET_BIND_SERVICE; 55 struct bind_perm *skel; 56 __u64 old_caps = 0; 57 int cgroup_fd; 58 59 if (create_netns()) 60 return; 61 62 cgroup_fd = test__join_cgroup("/bind_perm"); 63 if (CHECK(cgroup_fd < 0, "cg-join", "errno %d", errno)) 64 return; 65 66 skel = bind_perm__open_and_load(); 67 if (!ASSERT_OK_PTR(skel, "skel")) 68 goto close_cgroup_fd; 69 70 skel->links.bind_v4_prog = bpf_program__attach_cgroup(skel->progs.bind_v4_prog, cgroup_fd); 71 if (!ASSERT_OK_PTR(skel, "bind_v4_prog")) 72 goto close_skeleton; 73 74 skel->links.bind_v6_prog = bpf_program__attach_cgroup(skel->progs.bind_v6_prog, cgroup_fd); 75 if (!ASSERT_OK_PTR(skel, "bind_v6_prog")) 76 goto close_skeleton; 77 78 ASSERT_OK(cap_disable_effective(net_bind_svc_cap, &old_caps), 79 "cap_disable_effective"); 80 81 try_bind(AF_INET, 110, EACCES); 82 try_bind(AF_INET6, 110, EACCES); 83 84 try_bind(AF_INET, 111, 0); 85 try_bind(AF_INET6, 111, 0); 86 87 if (old_caps & net_bind_svc_cap) 88 ASSERT_OK(cap_enable_effective(net_bind_svc_cap, NULL), 89 "cap_enable_effective"); 90 91 close_skeleton: 92 bind_perm__destroy(skel); 93 close_cgroup_fd: 94 close(cgroup_fd); 95 } 96