1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * AppArmor security module 4 * 5 * This file contains AppArmor inet fine grained mediation 6 * 7 * Copyright 2024 Canonical Ltd. 8 * 9 */ 10 11 #include <net/tcp_states.h> 12 13 #include "include/audit.h" 14 #include "include/af_inet.h" 15 #include "include/apparmor.h" 16 #include "include/file.h" 17 #include "include/label.h" 18 #include "include/net.h" 19 #include "include/path.h" 20 #include "include/policy.h" 21 #include "include/cred.h" 22 23 24 static inline aa_state_t RULE_MEDIATES_SK(struct aa_ruleset *rules, 25 const struct sock *sk) 26 { 27 return RULE_MEDIATES_NET(rules); 28 } 29 30 31 enum addr_type { 32 ADDR_LOCAL = 0, 33 ADDR_LOCAL_PRIV = 1, 34 ADDR_REMOTE = 2, 35 }; 36 37 struct match_addr { 38 const char *addrp; 39 enum addr_type addrtype; 40 int len; 41 __be16 port; 42 }; 43 44 struct stored_match_addr { 45 union { 46 struct sockaddr addr; 47 struct sockaddr_in addr4; 48 struct sockaddr_in6 addr6; 49 }; 50 int addrlen; 51 struct match_addr maddr; 52 }; 53 54 static void set_ad_create(struct apparmor_audit_data *ad, 55 int family, int type, int protocol) 56 { 57 ad->common.u.net->family = family; 58 ad->net.type = type; 59 ad->net.protocol = protocol; 60 } 61 62 static int set_ad_addr(struct apparmor_audit_data *ad, 63 u16 family, bool source, struct match_addr *maddr) 64 { 65 ad->common.u.net->family = family; 66 67 if (source) { 68 ad->common.u.net->sport = maddr->port; 69 if (maddr->addrp) { 70 if (family == AF_INET) 71 /* ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; */ 72 ad->common.u.net->v4info.saddr = *(__be32 *)maddr->addrp; 73 else 74 /* ad.u.net->v4info.saddr = addr6->sin6_addr.s6_addr; */ 75 ad->common.u.net->v6info.saddr = *(struct in6_addr *)maddr->addrp; 76 } 77 } else { 78 ad->common.u.net->dport = maddr->port; 79 if (maddr->addrp) { 80 if (family == AF_INET) 81 /* ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; */ 82 ad->common.u.net->v4info.daddr = *(__be32 *)maddr->addrp; 83 else 84 /* ad.u.net->v4info.saddr = addr6->sin6_addr.s6_addr; */ 85 ad->common.u.net->v6info.daddr = *(struct in6_addr *)maddr->addrp; 86 } 87 } 88 return 0; 89 } 90 91 /* returns 0 on success 92 * raw_port - if set raw_port (protocol) when SOCK_RAW */ 93 static int map_addr(struct sockaddr *addr, int addrlen, u16 raw_port, 94 enum addr_type addrtype, struct match_addr *maddr, 95 struct apparmor_audit_data *ad) 96 { 97 struct sockaddr_in *addr4 = NULL; 98 struct sockaddr_in6 *addr6 = NULL; 99 100 AA_BUG(!addr); 101 AA_BUG(!maddr); 102 103 maddr->addrtype = addrtype; 104 if (!addr || addrlen < offsetofend(struct sockaddr, sa_family)) { 105 maddr->addrp = NULL; 106 maddr->port = 0; 107 maddr->len = 0; 108 return 0; 109 } 110 111 /* 112 * its possibly to have sk->sk_family == PF_INET6 and 113 * addr->sa_family == AF_INET. sk_family is used for socket 114 * mediation, sa_family for when we have address ... 115 */ 116 switch (addr->sa_family) { 117 case AF_INET: 118 addr4 = (struct sockaddr_in *)addr; 119 if (addrlen < sizeof(struct sockaddr_in)) 120 return -EINVAL; 121 maddr->port = addr4->sin_port; 122 maddr->addrp = (char *)&addr4->sin_addr.s_addr; 123 maddr->len = 4; 124 break; 125 case AF_INET6: 126 addr6 = (struct sockaddr_in6 *)addr; 127 if (addrlen < SIN6_LEN_RFC2133) 128 return -EINVAL; 129 maddr->port = addr6->sin6_port; 130 maddr->addrp = (char *)&addr6->sin6_addr.s6_addr; 131 maddr->len = 16; 132 break; 133 default: 134 return -EAFNOSUPPORT; 135 } 136 /* per ip spec, && sk->sk_type == SOCK_RAW*/ 137 if (raw_port && addrtype != ADDR_REMOTE) 138 maddr->port = htons(raw_port); 139 if (ad) 140 set_ad_addr(ad, addr->sa_family, addrtype != ADDR_REMOTE, maddr); 141 142 return 0; 143 } 144 145 /* -ENOTCONN if not connected */ 146 static int map_sock_addr(struct socket *sock, enum addr_type addrtype, 147 struct stored_match_addr *maddr, 148 struct apparmor_audit_data *ad) 149 { 150 /* do we need early bailout for !family ... */ 151 maddr->addrlen = sock->ops->getname(sock, (struct sockaddr *) &maddr->addr, addrtype != ADDR_REMOTE ? 0 : 1); 152 if (maddr->addrlen == -ENOTCONN) { 153 maddr->addrlen = 0; 154 return map_addr(NULL, 0, 0, addrtype, &maddr->maddr, ad); 155 } else if (maddr->addrlen < 0) 156 return maddr->addrlen; 157 return map_addr(&maddr->addr, maddr->addrlen, 0, addrtype, 158 &maddr->maddr, ad); 159 } 160 161 /* TODO: combine with connect map addr */ 162 /* TODO: raw_port */ 163 static int bind_map_addr(const struct sock *sk, struct sockaddr *addr, 164 int addrlen, 165 struct match_addr *maddr, 166 struct apparmor_audit_data *ad) 167 { 168 struct sockaddr_in *addr4 = NULL; 169 struct sockaddr_in6 *addr6 = NULL; 170 u16 family; 171 172 AA_BUG(!sk); 173 AA_BUG(!addr); 174 AA_BUG(!maddr); 175 176 if (addrlen < offsetofend(struct sockaddr, sa_family)) 177 return -EINVAL; 178 179 maddr->addrtype = ADDR_LOCAL; 180 /* 181 * its possibly to have sk->sk_family == PF_INET6 and 182 * addr->sa_family == AF_INET. sk_family is used for socket 183 * mediation, sa_family for when we have address ... 184 */ 185 family = addr->sa_family; 186 switch (addr->sa_family) { 187 case AF_UNSPEC: 188 if (sk->sk_family == PF_INET6) { 189 /* Length check from inet6_bind_sk() */ 190 if (addrlen < SIN6_LEN_RFC2133) 191 return -EINVAL; 192 /* Family check from __inet6_bind() */ 193 return -EAFNOSUPPORT; 194 } 195 /* see __inet_bind(), we only want to allow 196 * AF_UNSPEC if the address is INADDR_ANY 197 */ 198 addr4 = (struct sockaddr_in *)addr; 199 if (addr4->sin_addr.s_addr != htonl(INADDR_ANY)) 200 return -EAFNOSUPPORT; 201 family = AF_INET; 202 fallthrough; 203 case AF_INET: 204 addr4 = (struct sockaddr_in *)addr; 205 if (addrlen < sizeof(struct sockaddr_in)) 206 return -EINVAL; 207 maddr->port = addr4->sin_port; 208 maddr->addrp = (char *)&addr4->sin_addr.s_addr; 209 maddr->len = 4; 210 break; 211 case AF_INET6: 212 addr6 = (struct sockaddr_in6 *)addr; 213 if (addrlen < SIN6_LEN_RFC2133) 214 return -EINVAL; 215 maddr->port = addr6->sin6_port; 216 maddr->addrp = (char *)&addr6->sin6_addr.s6_addr; 217 maddr->len = 16; 218 break; 219 default: 220 return -EAFNOSUPPORT; 221 } 222 223 if (ad) 224 set_ad_addr(ad, family, true, maddr); 225 226 return 0; 227 } 228 229 230 static inline int profile_sk_perm(struct aa_profile *profile, u32 request, 231 const struct sock *sk, 232 struct match_addr *maddr, 233 struct apparmor_audit_data *ad) 234 { 235 AA_BUG(!profile); 236 AA_BUG(!sk); 237 238 return aa_profile_af_sk_perm(profile, ad, request, sk); 239 } 240 241 /* no kernel_t bailout */ 242 static int profile_create_perm(struct aa_profile *profile, int family, 243 int type, int protocol, 244 struct apparmor_audit_data *ad) 245 { 246 AA_BUG(!profile); 247 248 return aa_profile_af_perm(profile, ad, AA_MAY_CREATE, family, type, 249 protocol); 250 } 251 252 253 /* sendmsg/rcvmsg/connect */ 254 static int profile_remote_perm(struct aa_profile *profile, 255 const struct sock *sk, 256 u32 request, struct match_addr *raddr, 257 struct match_addr *laddr, 258 struct apparmor_audit_data *ad) 259 { 260 AA_BUG(!profile); 261 AA_BUG(!sk); 262 AA_BUG(!raddr); 263 AA_BUG(!laddr); 264 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6, 265 "family=%d", sk->sk_family); 266 267 return aa_profile_af_sk_perm(profile, ad, request, sk); 268 } 269 270 static int profile_bind_perm(struct aa_profile *profile, 271 const struct sock *sk, 272 struct match_addr *maddr, 273 struct apparmor_audit_data *ad) 274 { 275 return aa_profile_af_sk_perm(profile, ad, AA_MAY_BIND, sk); 276 277 } 278 279 static int profile_listen_perm(struct aa_profile *profile, 280 const struct sock *sk, 281 struct match_addr *maddr, int backlog, 282 struct apparmor_audit_data *ad) 283 { 284 AA_BUG(!profile); 285 AA_BUG(!sk); 286 AA_BUG(!maddr); 287 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6, 288 "family=%d", sk->sk_family); 289 290 return aa_profile_af_sk_perm(profile, ad, AA_MAY_LISTEN, sk); 291 } 292 293 static inline int profile_accept_perm(struct aa_profile *profile, 294 const struct sock *sk, 295 struct match_addr *maddr, 296 const struct sock *newsk, 297 struct apparmor_audit_data *ad) 298 { 299 AA_BUG(!profile); 300 AA_BUG(!sk); 301 /* AA_BUG(!newsk); newsk can be null here, since not using atm ... */ 302 AA_BUG(!maddr); 303 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6, 304 "family=%d", sk->sk_family); 305 306 return aa_profile_af_sk_perm(profile, ad, AA_MAY_ACCEPT, sk); 307 } 308 309 /* getopt/setopt */ 310 static int profile_opt_perm(struct aa_profile *profile, u32 request, 311 const struct sock *sk, struct match_addr *maddr, 312 int level, int optname, 313 struct apparmor_audit_data *ad) 314 { 315 AA_BUG(!profile); 316 AA_BUG(!sk); 317 AA_BUG(!maddr); 318 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6, 319 "family=%d", sk->sk_family); 320 321 return aa_profile_af_sk_perm(profile, ad, request, sk); 322 } 323 324 /* ---------------------------------------------------------------------- */ 325 326 // TODO: cleanup init to use recursion, so we can have N init fns, in 1 macro 327 // TODO: lift DEFINE_AUDIT out of macro into init fn??? 328 329 /* no kernel_t bailout */ 330 #define label_sk_has_perm2(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, XXXX, YYYY, CALLBACKFN) \ 331 ({ \ 332 int __EERROR = 0; \ 333 if (label_mediates(LABEL, AA_CLASS_NET)) { \ 334 struct aa_profile *PROFILE; \ 335 DEFINE_AUDIT_SK(AAD, OP, CRED, SOCKSK); \ 336 (AAD).subj_cred = (CRED); \ 337 (AAD).request = (REQUEST); \ 338 __EERROR = (XXXX); \ 339 if (__EERROR == 0) { \ 340 __EERROR = (YYYY); \ 341 if (__EERROR == 0) { \ 342 __EERROR = fn_for_each(LABEL, PROFILE, \ 343 (CALLBACKFN)); \ 344 } \ 345 } \ 346 } \ 347 __EERROR; \ 348 }) 349 350 /* no kernel_t bailout */ 351 #define label_sk_has_perm(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, CALLBACKFN) \ 352 label_sk_has_perm2(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, \ 353 0, 0, CALLBACKFN) 354 355 /* no kernel_t bailout */ 356 #define label_sk_has_perm1(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, XXXX, CALLBACKFN) \ 357 label_sk_has_perm2(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, \ 358 XXXX, 0, CALLBACKFN) 359 360 361 /* Early bailout for kernel_t - 2 init args before callback */ 362 #define sk_has_perm2(SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, YYYYX, CALLBACKFN) \ 363 ({ \ 364 struct aa_label *__label; \ 365 struct aa_sk_ctx *__ctx = aa_sock(SOCKSK); \ 366 int __ERROR = 0; \ 367 bool __needput; \ 368 if (rcu_access_pointer(__ctx->label) != kernel_t) { \ 369 \ 370 __label = begin_current_label_crit_section(&__needput); \ 371 __ERROR = label_sk_has_perm2(current_cred(), __label, SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, YYYYX, CALLBACKFN); \ 372 end_current_label_crit_section(__label, __needput); \ 373 } \ 374 __ERROR; \ 375 }) 376 377 /* Early bailout for kernel_t - no init args before callback */ 378 #define sk_has_perm(SOCKSK, OP, REQUEST, PROFILE, AAD, CALLBACKFN) \ 379 sk_has_perm2(SOCKSK, OP, REQUEST, PROFILE, AAD, 0, 0, CALLBACKFN) 380 381 382 /* Early bailout for kernel_t - 1 init arg before callback */ 383 #define sk_has_perm1(SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, CALLBACKFN) \ 384 sk_has_perm2(SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, 0, CALLBACKFN) 385 386 387 388 /* no kernel_t early bailout */ 389 /* NOTE: already lifted label_mediates into lsm.c */ 390 int aa_inet_create_perm(struct aa_label *label, int family, int type, 391 int protocol) 392 { 393 struct aa_profile *profile; 394 int error = 0; 395 DEFINE_AUDIT_NET(ad, OP_CREATE, current_cred(), NULL, family, type, 396 protocol); 397 398 ad.subj_cred = current_cred(); 399 set_ad_create(&ad, family, type, protocol); 400 error = fn_for_each(label, profile, 401 profile_create_perm(profile, family, type, 402 protocol, &ad)); 403 404 return error; 405 } 406 407 int aa_inet_bind_perm(struct socket *sock, struct sockaddr *addr, 408 int addrlen) 409 { 410 struct match_addr maddr; 411 412 return sk_has_perm1(sock->sk, OP_BIND, AA_MAY_BIND, profile, ad, 413 bind_map_addr(sock->sk, addr, addrlen, &maddr, 414 &ad), 415 profile_bind_perm(profile, sock->sk, &maddr, &ad)); 416 } 417 418 int aa_inet_connect_perm(struct socket *sock, struct sockaddr *addr, 419 int addrlen) 420 { 421 struct stored_match_addr laddr; 422 struct match_addr raddr; 423 424 /* disconnect socket */ 425 if (addrlen < offsetofend(struct sockaddr, sa_family)) 426 return -EINVAL; 427 if (addr->sa_family == AF_UNSPEC) 428 return 0; 429 430 /* do we need early bailout for !family ... */ 431 return sk_has_perm2(sock->sk, OP_CONNECT, AA_MAY_CONNECT, profile, ad, 432 map_sock_addr(sock, ADDR_LOCAL, &laddr, &ad), 433 map_addr(addr, addrlen, 0, ADDR_REMOTE, &raddr, 434 &ad), 435 profile_remote_perm(profile, sock->sk, 436 AA_MAY_CONNECT, &raddr, 437 &laddr.maddr, &ad)); 438 } 439 440 int aa_inet_listen_perm(struct socket *sock, int backlog) 441 { 442 struct stored_match_addr maddr; 443 444 /* do we need early bailout for !family ... */ 445 return sk_has_perm1(sock->sk, OP_LISTEN, AA_MAY_LISTEN, profile, ad, 446 map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad), 447 profile_listen_perm(profile, sock->sk, &maddr.maddr, 448 backlog, &ad)); 449 } 450 451 /* ability of sock to connect, not peer address binding */ 452 int aa_inet_accept_perm(struct socket *sock, struct socket *newsock) 453 { 454 struct stored_match_addr maddr; 455 int error; 456 457 error = sk_has_perm1(sock->sk, OP_ACCEPT, AA_MAY_ACCEPT, profile, ad, 458 map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad), 459 profile_accept_perm(profile, sock->sk, 460 &maddr.maddr, 461 newsock->sk, &ad)); 462 463 /* selinux updates inode - need to investigate this more */ 464 return error; 465 } 466 467 /* sendmsg, recvmsg. */ 468 int aa_inet_msg_perm(const char *op, u32 request, struct socket *sock, 469 struct msghdr *msg, int size) 470 { 471 struct stored_match_addr laddr; 472 struct match_addr raddr; 473 474 /* do we need early bailout for !family ... */ 475 return sk_has_perm2(sock->sk, op, request, profile, ad, 476 map_sock_addr(sock, ADDR_LOCAL, &laddr, &ad), 477 map_addr(msg->msg_name, msg->msg_namelen, 0, 478 ADDR_REMOTE, &raddr, &ad), 479 profile_remote_perm(profile, sock->sk, request, 480 &raddr, &laddr.maddr, &ad)); 481 } 482 483 /* getopt, setopt */ 484 int aa_inet_opt_perm(const char *op, u32 request, struct socket *sock, 485 int level, int optname) 486 { 487 struct stored_match_addr maddr; 488 489 return sk_has_perm1(sock->sk, op, request, profile, ad, 490 map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad), 491 profile_opt_perm(profile, request, sock->sk, 492 &maddr.maddr, level, optname, &ad)); 493 } 494 495 static int inet_label_sock_perm(const struct cred *cred, struct aa_label *label, 496 const char *op, u32 request, 497 struct socket *sock) 498 { 499 struct stored_match_addr maddr; 500 501 return label_sk_has_perm1(cred, label, sock->sk, op, request, profile, 502 ad, 503 map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad), 504 profile_sk_perm(profile, request, sock->sk, 505 &maddr.maddr, &ad)); 506 } 507 508 /* revalidation, get/set attr/getsockname/peername */ 509 int aa_inet_sock_perm(const char *op, u32 request, struct socket *sock) 510 { 511 struct aa_sk_ctx *ctx = aa_sock(sock->sk); 512 struct aa_label *label; 513 bool needput; 514 int error; 515 516 if (rcu_access_pointer(ctx->label) == kernel_t) 517 return 0; 518 519 label = begin_current_label_crit_section(&needput); 520 error = inet_label_sock_perm(current_cred(), label, op, request, sock); 521 end_current_label_crit_section(label, needput); 522 523 return error; 524 } 525 526 int aa_inet_file_perm(const struct cred *subj_cred, struct aa_label *label, 527 const char *op, u32 request, struct socket *sock) 528 { 529 u32 sk_req = request & ~NET_PEER_MASK; 530 struct stored_match_addr laddr; 531 const struct sock *sk = sock->sk; 532 int error = 0; 533 534 AA_BUG(!label); 535 AA_BUG(!sock); 536 AA_BUG(!sock->sk); 537 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6, 538 "family=%d", sk->sk_family); 539 540 /* access to the local sock */ 541 error = label_sk_has_perm1(subj_cred, label, sock->sk, op, request, 542 profile, ad, 543 map_sock_addr(sock, ADDR_LOCAL, &laddr, &ad), 544 profile_sk_perm(profile, sk_req, sock->sk, &laddr.maddr, 545 &ad)); 546 547 if (!error) { 548 struct stored_match_addr raddr; 549 550 /* TODO: have ad here: instead of in CB so we do have to redo */ 551 error = map_sock_addr(sock, ADDR_REMOTE, &raddr, NULL); 552 if (!error && raddr.maddr.addrp) { 553 error = label_sk_has_perm1(subj_cred, label, sock->sk, 554 op, request, profile, ad, 555 set_ad_addr(&ad, raddr.addr.sa_family, 556 false, &raddr.maddr), 557 profile_remote_perm(profile, sock->sk, 558 request, 559 &raddr.maddr, 560 &laddr.maddr, &ad)); 561 } 562 } 563 564 return error; 565 } 566