1 // SPDX-License-Identifier: GPL-2.0 2 3 #include "vmlinux.h" 4 #include "bpf_tracing_net.h" 5 #include <bpf/bpf_helpers.h> 6 #include <bpf/bpf_tracing.h> 7 8 char _license[] SEC("license") = "GPL"; 9 10 extern bool CONFIG_SECURITY_SELINUX __kconfig __weak; 11 extern bool CONFIG_SECURITY_SMACK __kconfig __weak; 12 extern bool CONFIG_SECURITY_APPARMOR __kconfig __weak; 13 14 #ifndef AF_PACKET 15 #define AF_PACKET 17 16 #endif 17 18 #ifndef AF_UNIX 19 #define AF_UNIX 1 20 #endif 21 22 #ifndef EPERM 23 #define EPERM 1 24 #endif 25 26 struct { 27 __uint(type, BPF_MAP_TYPE_CGROUP_STORAGE); 28 __type(key, __u64); 29 __type(value, __u64); 30 } cgroup_storage SEC(".maps"); 31 32 int called_socket_post_create; 33 int called_socket_post_create2; 34 int called_socket_bind; 35 int called_socket_bind2; 36 int called_socket_alloc; 37 int called_socket_clone; 38 int skipcap_retval = -4095; 39 int socket_retval = -4095; 40 41 static __always_inline int test_local_storage(void) 42 { 43 __u64 *val; 44 45 val = bpf_get_local_storage(&cgroup_storage, 0); 46 if (!val) 47 return 0; 48 *val += 1; 49 50 return 1; 51 } 52 53 static __always_inline int real_create(struct socket *sock, int family, 54 int protocol) 55 { 56 struct sock *sk; 57 int prio = 123; 58 59 /* Reject non-tx-only AF_PACKET. */ 60 if (family == AF_PACKET && protocol != 0) 61 return 0; /* EPERM */ 62 63 sk = sock->sk; 64 if (!sk) 65 return 1; 66 67 /* The rest of the sockets get default policy. */ 68 if (bpf_setsockopt(sk, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio))) 69 return 0; /* EPERM */ 70 71 /* Make sure bpf_getsockopt is allowed and works. */ 72 prio = 0; 73 if (bpf_getsockopt(sk, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio))) 74 return 0; /* EPERM */ 75 if (prio != 123) 76 return 0; /* EPERM */ 77 78 /* Can access cgroup local storage. */ 79 if (!test_local_storage()) 80 return 0; /* EPERM */ 81 82 return 1; 83 } 84 85 /* __cgroup_bpf_run_lsm_socket */ 86 SEC("lsm_cgroup/socket_post_create") 87 int BPF_PROG(socket_post_create, struct socket *sock, int family, 88 int type, int protocol, int kern) 89 { 90 called_socket_post_create++; 91 return real_create(sock, family, protocol); 92 } 93 94 /* __cgroup_bpf_run_lsm_socket */ 95 SEC("lsm_cgroup/socket_post_create") 96 int BPF_PROG(socket_post_create2, struct socket *sock, int family, 97 int type, int protocol, int kern) 98 { 99 called_socket_post_create2++; 100 return real_create(sock, family, protocol); 101 } 102 103 static __always_inline int real_bind(struct socket *sock, 104 struct sockaddr *address, 105 int addrlen) 106 { 107 struct sockaddr_ll sa = {}; 108 struct sock *sk = sock->sk; 109 110 if (!sk) 111 return 1; 112 113 if (sk->__sk_common.skc_family != AF_PACKET) 114 return 1; 115 116 if (sk->sk_kern_sock) 117 return 1; 118 119 bpf_probe_read_kernel(&sa, sizeof(sa), address); 120 if (sa.sll_protocol) 121 return 0; /* EPERM */ 122 123 /* Can access cgroup local storage. */ 124 if (!test_local_storage()) 125 return 0; /* EPERM */ 126 127 return 1; 128 } 129 130 /* __cgroup_bpf_run_lsm_socket */ 131 SEC("lsm_cgroup/socket_bind") 132 int BPF_PROG(socket_bind, struct socket *sock, struct sockaddr *address, 133 int addrlen) 134 { 135 called_socket_bind++; 136 return real_bind(sock, address, addrlen); 137 } 138 139 /* __cgroup_bpf_run_lsm_socket */ 140 SEC("lsm_cgroup/socket_bind") 141 int BPF_PROG(socket_bind2, struct socket *sock, struct sockaddr *address, 142 int addrlen) 143 { 144 called_socket_bind2++; 145 return real_bind(sock, address, addrlen); 146 } 147 148 /* __cgroup_bpf_run_lsm_current (via bpf_lsm_current_hooks) */ 149 SEC("lsm_cgroup/sk_alloc_security") 150 int BPF_PROG(socket_alloc, struct sock *sk, int family, gfp_t priority) 151 { 152 called_socket_alloc++; 153 /* if already have non-bpf lsms installed, EPERM will cause memory leak of non-bpf lsms */ 154 if (CONFIG_SECURITY_SELINUX || CONFIG_SECURITY_SMACK || CONFIG_SECURITY_APPARMOR) 155 return 1; 156 157 if (family == AF_UNIX) 158 return 0; /* EPERM */ 159 160 /* Can access cgroup local storage. */ 161 if (!test_local_storage()) 162 return 0; /* EPERM */ 163 164 return 1; 165 } 166 167 /* __cgroup_bpf_run_lsm_sock */ 168 SEC("lsm_cgroup/inet_csk_clone") 169 int BPF_PROG(socket_clone, struct sock *newsk, const struct request_sock *req) 170 { 171 int prio = 234; 172 173 if (!newsk) 174 return 1; 175 176 /* Accepted request sockets get a different priority. */ 177 if (bpf_setsockopt(newsk, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio))) 178 return 1; 179 180 /* Make sure bpf_getsockopt is allowed and works. */ 181 prio = 0; 182 if (bpf_getsockopt(newsk, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio))) 183 return 1; 184 if (prio != 234) 185 return 1; 186 187 /* Can access cgroup local storage. */ 188 if (!test_local_storage()) 189 return 1; 190 191 called_socket_clone++; 192 193 return 1; 194 } 195 196 SEC("lsm_cgroup/inode_xattr_skipcap") 197 int BPF_PROG(skipcap_first, const char *name) 198 { 199 return 0; 200 } 201 202 SEC("lsm_cgroup/inode_xattr_skipcap") 203 int BPF_PROG(skipcap_second, const char *name) 204 { 205 skipcap_retval = bpf_get_retval(); 206 bpf_set_retval(0); 207 return 1; 208 } 209 210 SEC("lsm_cgroup/socket_create") 211 int BPF_PROG(socket_first, int family, int type, int protocol, int kern) 212 { 213 return 0; 214 } 215 216 SEC("lsm_cgroup/socket_create") 217 int BPF_PROG(socket_second, int family, int type, int protocol, int kern) 218 { 219 socket_retval = bpf_get_retval(); 220 bpf_set_retval(0); 221 return 1; 222 } 223