1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * AppArmor security module 4 * 5 * This file contains AppArmor af_unix fine grained mediation 6 * 7 * Copyright 2023 Canonical Ltd. 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License as 11 * published by the Free Software Foundation, version 2 of the 12 * License. 13 */ 14 15 #include <net/tcp_states.h> 16 17 #include "include/audit.h" 18 #include "include/af_unix.h" 19 #include "include/apparmor.h" 20 #include "include/file.h" 21 #include "include/label.h" 22 #include "include/path.h" 23 #include "include/policy.h" 24 #include "include/cred.h" 25 26 27 static inline struct sock *aa_unix_sk(struct unix_sock *u) 28 { 29 return &u->sk; 30 } 31 32 static int unix_fs_perm(const char *op, u32 mask, const struct cred *subj_cred, 33 struct aa_label *label, struct path *path) 34 { 35 AA_BUG(!label); 36 AA_BUG(!path); 37 38 if (unconfined(label) || !label_mediates(label, AA_CLASS_FILE)) 39 return 0; 40 41 mask &= NET_FS_PERMS; 42 /* if !u->path.dentry socket is being shutdown - implicit delegation 43 * until obj delegation is supported 44 */ 45 if (path->dentry) { 46 /* the sunpath may not be valid for this ns so use the path */ 47 struct path_cond cond = { path->dentry->d_inode->i_uid, 48 path->dentry->d_inode->i_mode 49 }; 50 51 return aa_path_perm(op, subj_cred, label, path, 52 PATH_SOCK_COND, mask, &cond); 53 } /* else implicitly delegated */ 54 55 return 0; 56 } 57 58 /* match_addr special constants */ 59 #define ABSTRACT_ADDR "\x00" /* abstract socket addr */ 60 #define ANONYMOUS_ADDR "\x01" /* anonymous endpoint, no addr */ 61 #define DISCONNECTED_ADDR "\x02" /* addr is another namespace */ 62 #define SHUTDOWN_ADDR "\x03" /* path addr is shutdown and cleared */ 63 #define FS_ADDR "/" /* path addr in fs */ 64 65 static aa_state_t match_addr(struct aa_dfa *dfa, aa_state_t state, 66 struct sockaddr_un *addr, int addrlen) 67 { 68 if (addr) 69 /* include leading \0 */ 70 state = aa_dfa_match_len(dfa, state, addr->sun_path, 71 unix_addr_len(addrlen)); 72 else 73 state = aa_dfa_match_len(dfa, state, ANONYMOUS_ADDR, 1); 74 /* todo: could change to out of band for cleaner separation */ 75 state = aa_dfa_null_transition(dfa, state); 76 77 return state; 78 } 79 80 static aa_state_t match_to_local(struct aa_policydb *policy, 81 aa_state_t state, u32 request, 82 int type, int protocol, 83 struct sockaddr_un *addr, int addrlen, 84 struct aa_perms **p, 85 const char **info) 86 { 87 state = aa_match_to_prot(policy, state, request, PF_UNIX, type, 88 protocol, NULL, info); 89 if (state) { 90 state = match_addr(policy->dfa, state, addr, addrlen); 91 if (state) { 92 /* todo: local label matching */ 93 state = aa_dfa_null_transition(policy->dfa, state); 94 if (!state) 95 *info = "failed local label match"; 96 } else { 97 *info = "failed local address match"; 98 } 99 } 100 101 return state; 102 } 103 104 struct sockaddr_un *aa_sunaddr(const struct unix_sock *u, int *addrlen) 105 { 106 struct unix_address *addr; 107 108 /* memory barrier is sufficient see note in net/unix/af_unix.c */ 109 addr = smp_load_acquire(&u->addr); 110 if (addr) { 111 *addrlen = addr->len; 112 return addr->name; 113 } 114 *addrlen = 0; 115 return NULL; 116 } 117 118 static aa_state_t match_to_sk(struct aa_policydb *policy, 119 aa_state_t state, u32 request, 120 struct unix_sock *u, struct aa_perms **p, 121 const char **info) 122 { 123 int addrlen; 124 struct sockaddr_un *addr = aa_sunaddr(u, &addrlen); 125 126 return match_to_local(policy, state, request, u->sk.sk_type, 127 u->sk.sk_protocol, addr, addrlen, p, info); 128 } 129 130 #define CMD_ADDR 1 131 #define CMD_LISTEN 2 132 #define CMD_OPT 4 133 134 static aa_state_t match_to_cmd(struct aa_policydb *policy, aa_state_t state, 135 u32 request, struct unix_sock *u, 136 char cmd, struct aa_perms **p, 137 const char **info) 138 { 139 AA_BUG(!p); 140 141 state = match_to_sk(policy, state, request, u, p, info); 142 if (state && !*p) { 143 state = aa_dfa_match_len(policy->dfa, state, &cmd, 1); 144 if (!state) 145 *info = "failed cmd selection match"; 146 } 147 148 return state; 149 } 150 151 static aa_state_t match_to_peer(struct aa_policydb *policy, aa_state_t state, 152 u32 request, struct unix_sock *u, 153 struct sockaddr_un *peer_addr, int peer_addrlen, 154 struct aa_perms **p, const char **info) 155 { 156 AA_BUG(!p); 157 158 state = match_to_cmd(policy, state, request, u, CMD_ADDR, p, info); 159 if (state && !*p) { 160 state = match_addr(policy->dfa, state, peer_addr, peer_addrlen); 161 if (!state) 162 *info = "failed peer address match"; 163 } 164 165 return state; 166 } 167 168 static aa_state_t match_label(struct aa_profile *profile, 169 struct aa_ruleset *rule, aa_state_t state, 170 u32 request, struct aa_profile *peer, 171 struct aa_perms *p, 172 struct apparmor_audit_data *ad) 173 { 174 AA_BUG(!profile); 175 AA_BUG(!peer); 176 177 ad->peer = &peer->label; 178 179 if (state && !p) { 180 state = aa_dfa_match(rule->policy->dfa, state, 181 peer->base.hname); 182 if (!state) 183 ad->info = "failed peer label match"; 184 185 } 186 187 return aa_do_perms(profile, rule->policy, state, request, p, ad); 188 } 189 190 191 /* unix sock creation comes before we know if the socket will be an fs 192 * socket 193 * v6 - semantics are handled by mapping in profile load 194 * v7 - semantics require sock create for tasks creating an fs socket. 195 * v8 - same as v7 196 */ 197 static int profile_create_perm(struct aa_profile *profile, int family, 198 int type, int protocol, 199 struct apparmor_audit_data *ad) 200 { 201 struct aa_ruleset *rules = list_first_entry(&profile->rules, 202 typeof(*rules), list); 203 aa_state_t state; 204 205 AA_BUG(!profile); 206 AA_BUG(profile_unconfined(profile)); 207 208 state = RULE_MEDIATES_v9NET(rules); 209 if (state) { 210 state = aa_match_to_prot(rules->policy, state, AA_MAY_CREATE, 211 PF_UNIX, type, protocol, NULL, 212 &ad->info); 213 214 return aa_do_perms(profile, rules->policy, state, AA_MAY_CREATE, 215 NULL, ad); 216 } 217 218 return aa_profile_af_perm(profile, ad, AA_MAY_CREATE, family, type, 219 protocol); 220 } 221 222 static int profile_sk_perm(struct aa_profile *profile, 223 struct apparmor_audit_data *ad, 224 u32 request, struct sock *sk, struct path *path) 225 { 226 struct aa_ruleset *rules = list_first_entry(&profile->rules, 227 typeof(*rules), 228 list); 229 struct aa_perms *p = NULL; 230 aa_state_t state; 231 232 AA_BUG(!profile); 233 AA_BUG(!sk); 234 AA_BUG(profile_unconfined(profile)); 235 236 state = RULE_MEDIATES_v9NET(rules); 237 if (state) { 238 if (is_unix_fs(sk)) 239 return unix_fs_perm(ad->op, request, ad->subj_cred, 240 &profile->label, 241 &unix_sk(sk)->path); 242 243 state = match_to_sk(rules->policy, state, request, unix_sk(sk), 244 &p, &ad->info); 245 246 return aa_do_perms(profile, rules->policy, state, request, p, 247 ad); 248 } 249 250 return aa_profile_af_sk_perm(profile, ad, request, sk); 251 } 252 253 static int profile_bind_perm(struct aa_profile *profile, struct sock *sk, 254 struct apparmor_audit_data *ad) 255 { 256 struct aa_ruleset *rules = list_first_entry(&profile->rules, 257 typeof(*rules), list); 258 struct aa_perms *p = NULL; 259 aa_state_t state; 260 261 AA_BUG(!profile); 262 AA_BUG(!sk); 263 AA_BUG(!ad); 264 AA_BUG(profile_unconfined(profile)); 265 266 state = RULE_MEDIATES_v9NET(rules); 267 if (state) { 268 if (is_unix_addr_fs(ad->net.addr, ad->net.addrlen)) 269 /* under v7-9 fs hook handles bind */ 270 return 0; 271 /* bind for abstract socket */ 272 state = match_to_local(rules->policy, state, AA_MAY_BIND, 273 sk->sk_type, sk->sk_protocol, 274 unix_addr(ad->net.addr), 275 ad->net.addrlen, 276 &p, &ad->info); 277 278 return aa_do_perms(profile, rules->policy, state, AA_MAY_BIND, 279 p, ad); 280 } 281 282 return aa_profile_af_sk_perm(profile, ad, AA_MAY_BIND, sk); 283 } 284 285 static int profile_listen_perm(struct aa_profile *profile, struct sock *sk, 286 int backlog, struct apparmor_audit_data *ad) 287 { 288 struct aa_ruleset *rules = list_first_entry(&profile->rules, 289 typeof(*rules), list); 290 struct aa_perms *p = NULL; 291 aa_state_t state; 292 293 AA_BUG(!profile); 294 AA_BUG(!sk); 295 AA_BUG(!ad); 296 AA_BUG(profile_unconfined(profile)); 297 298 state = RULE_MEDIATES_v9NET(rules); 299 if (state) { 300 __be16 b = cpu_to_be16(backlog); 301 302 if (is_unix_fs(sk)) 303 return unix_fs_perm(ad->op, AA_MAY_LISTEN, 304 ad->subj_cred, &profile->label, 305 &unix_sk(sk)->path); 306 307 state = match_to_cmd(rules->policy, state, AA_MAY_LISTEN, 308 unix_sk(sk), CMD_LISTEN, &p, &ad->info); 309 if (state && !p) { 310 state = aa_dfa_match_len(rules->policy->dfa, state, 311 (char *) &b, 2); 312 if (!state) 313 ad->info = "failed listen backlog match"; 314 } 315 return aa_do_perms(profile, rules->policy, state, AA_MAY_LISTEN, 316 p, ad); 317 } 318 319 return aa_profile_af_sk_perm(profile, ad, AA_MAY_LISTEN, sk); 320 } 321 322 static int profile_accept_perm(struct aa_profile *profile, 323 struct sock *sk, 324 struct apparmor_audit_data *ad) 325 { 326 struct aa_ruleset *rules = list_first_entry(&profile->rules, 327 typeof(*rules), list); 328 struct aa_perms *p = NULL; 329 aa_state_t state; 330 331 AA_BUG(!profile); 332 AA_BUG(!sk); 333 AA_BUG(!ad); 334 AA_BUG(profile_unconfined(profile)); 335 336 state = RULE_MEDIATES_v9NET(rules); 337 if (state) { 338 if (is_unix_fs(sk)) 339 return unix_fs_perm(ad->op, AA_MAY_ACCEPT, 340 ad->subj_cred, &profile->label, 341 &unix_sk(sk)->path); 342 343 state = match_to_sk(rules->policy, state, AA_MAY_ACCEPT, 344 unix_sk(sk), &p, &ad->info); 345 346 return aa_do_perms(profile, rules->policy, state, AA_MAY_ACCEPT, 347 p, ad); 348 } 349 350 return aa_profile_af_sk_perm(profile, ad, AA_MAY_ACCEPT, sk); 351 } 352 353 static int profile_opt_perm(struct aa_profile *profile, u32 request, 354 struct sock *sk, int optname, 355 struct apparmor_audit_data *ad) 356 { 357 struct aa_ruleset *rules = list_first_entry(&profile->rules, 358 typeof(*rules), list); 359 struct aa_perms *p = NULL; 360 aa_state_t state; 361 362 AA_BUG(!profile); 363 AA_BUG(!sk); 364 AA_BUG(!ad); 365 AA_BUG(profile_unconfined(profile)); 366 367 state = RULE_MEDIATES_v9NET(rules); 368 if (state) { 369 __be16 b = cpu_to_be16(optname); 370 if (is_unix_fs(sk)) 371 return unix_fs_perm(ad->op, request, 372 ad->subj_cred, &profile->label, 373 &unix_sk(sk)->path); 374 375 state = match_to_cmd(rules->policy, state, request, unix_sk(sk), 376 CMD_OPT, &p, &ad->info); 377 if (state && !p) { 378 state = aa_dfa_match_len(rules->policy->dfa, state, 379 (char *) &b, 2); 380 if (!state) 381 ad->info = "failed sockopt match"; 382 } 383 return aa_do_perms(profile, rules->policy, state, request, p, 384 ad); 385 } 386 387 return aa_profile_af_sk_perm(profile, ad, request, sk); 388 } 389 390 /* null peer_label is allowed, in which case the peer_sk label is used */ 391 static int profile_peer_perm(struct aa_profile *profile, u32 request, 392 struct sock *sk, struct path *path, 393 struct sockaddr_un *peer_addr, 394 int peer_addrlen, struct path *peer_path, 395 struct aa_label *peer_label, 396 struct apparmor_audit_data *ad) 397 { 398 struct aa_ruleset *rules = list_first_entry(&profile->rules, 399 typeof(*rules), list); 400 struct aa_perms *p = NULL; 401 aa_state_t state; 402 403 AA_BUG(!profile); 404 AA_BUG(profile_unconfined(profile)); 405 AA_BUG(!sk); 406 AA_BUG(!peer_label); 407 AA_BUG(!ad); 408 409 state = RULE_MEDIATES_v9NET(rules); 410 if (state) { 411 struct aa_profile *peerp; 412 413 if (peer_path) 414 return unix_fs_perm(ad->op, request, ad->subj_cred, 415 &profile->label, peer_path); 416 else if (path) 417 return unix_fs_perm(ad->op, request, ad->subj_cred, 418 &profile->label, path); 419 state = match_to_peer(rules->policy, state, request, 420 unix_sk(sk), 421 peer_addr, peer_addrlen, &p, &ad->info); 422 423 return fn_for_each_in_ns(peer_label, peerp, 424 match_label(profile, rules, state, request, 425 peerp, p, ad)); 426 } 427 428 return aa_profile_af_sk_perm(profile, ad, request, sk); 429 } 430 431 /* -------------------------------- */ 432 433 int aa_unix_create_perm(struct aa_label *label, int family, int type, 434 int protocol) 435 { 436 if (!unconfined(label)) { 437 struct aa_profile *profile; 438 DEFINE_AUDIT_NET(ad, OP_CREATE, current_cred(), NULL, family, 439 type, protocol); 440 441 return fn_for_each_confined(label, profile, 442 profile_create_perm(profile, family, type, 443 protocol, &ad)); 444 } 445 446 return 0; 447 } 448 449 static int aa_unix_label_sk_perm(const struct cred *subj_cred, 450 struct aa_label *label, 451 const char *op, u32 request, struct sock *sk, 452 struct path *path) 453 { 454 if (!unconfined(label)) { 455 struct aa_profile *profile; 456 DEFINE_AUDIT_SK(ad, op, subj_cred, sk); 457 458 return fn_for_each_confined(label, profile, 459 profile_sk_perm(profile, &ad, request, sk, 460 path)); 461 } 462 return 0; 463 } 464 465 /* revalidation, get/set attr, shutdown */ 466 int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock) 467 { 468 struct aa_label *label; 469 int error; 470 471 label = begin_current_label_crit_section(); 472 error = aa_unix_label_sk_perm(current_cred(), label, op, 473 request, sock->sk, 474 is_unix_fs(sock->sk) ? &unix_sk(sock->sk)->path : NULL); 475 end_current_label_crit_section(label); 476 477 return error; 478 } 479 480 static int valid_addr(struct sockaddr *addr, int addr_len) 481 { 482 struct sockaddr_un *sunaddr = unix_addr(addr); 483 484 /* addr_len == offsetof(struct sockaddr_un, sun_path) is autobind */ 485 if (addr_len < offsetof(struct sockaddr_un, sun_path) || 486 addr_len > sizeof(*sunaddr)) 487 return -EINVAL; 488 return 0; 489 } 490 491 int aa_unix_bind_perm(struct socket *sock, struct sockaddr *addr, 492 int addrlen) 493 { 494 struct aa_profile *profile; 495 struct aa_label *label; 496 int error = 0; 497 498 error = valid_addr(addr, addrlen); 499 if (error) 500 return error; 501 502 label = begin_current_label_crit_section(); 503 /* fs bind is handled by mknod */ 504 if (!unconfined(label)) { 505 DEFINE_AUDIT_SK(ad, OP_BIND, current_cred(), sock->sk); 506 507 ad.net.addr = unix_addr(addr); 508 ad.net.addrlen = addrlen; 509 510 error = fn_for_each_confined(label, profile, 511 profile_bind_perm(profile, sock->sk, &ad)); 512 } 513 end_current_label_crit_section(label); 514 515 return error; 516 } 517 518 /* 519 * unix connections are covered by the 520 * - unix_stream_connect (stream) and unix_may_send hooks (dgram) 521 * - fs connect is handled by open 522 * This is just here to document this is not needed for af_unix 523 * 524 int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address, 525 int addrlen) 526 { 527 return 0; 528 } 529 */ 530 531 int aa_unix_listen_perm(struct socket *sock, int backlog) 532 { 533 struct aa_profile *profile; 534 struct aa_label *label; 535 int error = 0; 536 537 label = begin_current_label_crit_section(); 538 if (!unconfined(label)) { 539 DEFINE_AUDIT_SK(ad, OP_LISTEN, current_cred(), sock->sk); 540 541 error = fn_for_each_confined(label, profile, 542 profile_listen_perm(profile, sock->sk, 543 backlog, &ad)); 544 } 545 end_current_label_crit_section(label); 546 547 return error; 548 } 549 550 551 /* ability of sock to connect, not peer address binding */ 552 int aa_unix_accept_perm(struct socket *sock, struct socket *newsock) 553 { 554 struct aa_profile *profile; 555 struct aa_label *label; 556 int error = 0; 557 558 label = begin_current_label_crit_section(); 559 if (!unconfined(label)) { 560 DEFINE_AUDIT_SK(ad, OP_ACCEPT, current_cred(), sock->sk); 561 562 error = fn_for_each_confined(label, profile, 563 profile_accept_perm(profile, sock->sk, &ad)); 564 } 565 end_current_label_crit_section(label); 566 567 return error; 568 } 569 570 571 /* 572 * dgram handled by unix_may_sendmsg, right to send on stream done at connect 573 * could do per msg unix_stream here, but connect + socket transfer is 574 * sufficient. This is just here to document this is not needed for af_unix 575 * 576 * sendmsg, recvmsg 577 int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock, 578 struct msghdr *msg, int size) 579 { 580 return 0; 581 } 582 */ 583 584 int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, 585 int level, int optname) 586 { 587 struct aa_profile *profile; 588 struct aa_label *label; 589 int error = 0; 590 591 label = begin_current_label_crit_section(); 592 if (!unconfined(label)) { 593 DEFINE_AUDIT_SK(ad, op, current_cred(), sock->sk); 594 595 error = fn_for_each_confined(label, profile, 596 profile_opt_perm(profile, request, sock->sk, 597 optname, &ad)); 598 } 599 end_current_label_crit_section(label); 600 601 return error; 602 } 603 604 static int unix_peer_perm(const struct cred *subj_cred, 605 struct aa_label *label, const char *op, u32 request, 606 struct sock *sk, struct path *path, 607 struct sockaddr_un *peer_addr, int peer_addrlen, 608 struct path *peer_path, struct aa_label *peer_label) 609 { 610 struct aa_profile *profile; 611 DEFINE_AUDIT_SK(ad, op, subj_cred, sk); 612 613 ad.net.peer.addr = peer_addr; 614 ad.net.peer.addrlen = peer_addrlen; 615 616 return fn_for_each_confined(label, profile, 617 profile_peer_perm(profile, request, sk, path, 618 peer_addr, peer_addrlen, peer_path, 619 peer_label, &ad)); 620 } 621 622 /** 623 * 624 * Requires: lock held on both @sk and @peer_sk 625 * called by unix_stream_connect, unix_may_send 626 */ 627 int aa_unix_peer_perm(const struct cred *subj_cred, 628 struct aa_label *label, const char *op, u32 request, 629 struct sock *sk, struct sock *peer_sk, 630 struct aa_label *peer_label) 631 { 632 struct unix_sock *peeru = unix_sk(peer_sk); 633 struct unix_sock *u = unix_sk(sk); 634 int plen; 635 struct sockaddr_un *paddr = aa_sunaddr(unix_sk(peer_sk), &plen); 636 637 AA_BUG(!label); 638 AA_BUG(!sk); 639 AA_BUG(!peer_sk); 640 AA_BUG(!peer_label); 641 642 return unix_peer_perm(subj_cred, label, op, request, sk, 643 is_unix_fs(sk) ? &u->path : NULL, 644 paddr, plen, 645 is_unix_fs(peer_sk) ? &peeru->path : NULL, 646 peer_label); 647 } 648 649 /* sk_plabel for comparison only */ 650 static void update_sk_ctx(struct sock *sk, struct aa_label *label, 651 struct aa_label *plabel) 652 { 653 struct aa_label *l, *old; 654 struct aa_sk_ctx *ctx = aa_sock(sk); 655 bool update_sk; 656 657 rcu_read_lock(); 658 update_sk = (plabel && 659 (plabel != rcu_access_pointer(ctx->peer_lastupdate) || 660 !aa_label_is_subset(plabel, rcu_dereference(ctx->peer)))) || 661 !__aa_subj_label_is_cached(label, rcu_dereference(ctx->label)); 662 rcu_read_unlock(); 663 if (!update_sk) 664 return; 665 666 spin_lock(&unix_sk(sk)->lock); 667 old = rcu_dereference_protected(ctx->label, 668 lockdep_is_held(&unix_sk(sk)->lock)); 669 l = aa_label_merge(old, label, GFP_ATOMIC); 670 if (l) { 671 if (l != old) { 672 rcu_assign_pointer(ctx->label, l); 673 aa_put_label(old); 674 } else 675 aa_put_label(l); 676 } 677 if (plabel && rcu_access_pointer(ctx->peer_lastupdate) != plabel) { 678 old = rcu_dereference_protected(ctx->peer, lockdep_is_held(&unix_sk(sk)->lock)); 679 680 if (old == plabel) { 681 rcu_assign_pointer(ctx->peer_lastupdate, plabel); 682 } else if (aa_label_is_subset(plabel, old)) { 683 rcu_assign_pointer(ctx->peer_lastupdate, plabel); 684 rcu_assign_pointer(ctx->peer, aa_get_label(plabel)); 685 aa_put_label(old); 686 } /* else race or a subset - don't update */ 687 } 688 spin_unlock(&unix_sk(sk)->lock); 689 } 690 691 static void update_peer_ctx(struct sock *sk, struct aa_sk_ctx *ctx, 692 struct aa_label *label) 693 { 694 struct aa_label *l, *old; 695 696 spin_lock(&unix_sk(sk)->lock); 697 old = rcu_dereference_protected(ctx->peer, 698 lockdep_is_held(&unix_sk(sk)->lock)); 699 l = aa_label_merge(old, label, GFP_ATOMIC); 700 if (l) { 701 if (l != old) { 702 rcu_assign_pointer(ctx->peer, l); 703 aa_put_label(old); 704 } else 705 aa_put_label(l); 706 } 707 spin_unlock(&unix_sk(sk)->lock); 708 } 709 710 /* This fn is only checked if something has changed in the security 711 * boundaries. Otherwise cached info off file is sufficient 712 */ 713 int aa_unix_file_perm(const struct cred *subj_cred, struct aa_label *label, 714 const char *op, u32 request, struct file *file) 715 { 716 struct socket *sock = (struct socket *) file->private_data; 717 struct sockaddr_un *addr, *peer_addr; 718 int addrlen, peer_addrlen; 719 struct aa_label *plabel = NULL; 720 struct sock *peer_sk = NULL; 721 u32 sk_req = request & ~NET_PEER_MASK; 722 struct path path; 723 bool is_sk_fs; 724 int error = 0; 725 726 AA_BUG(!label); 727 AA_BUG(!sock); 728 AA_BUG(!sock->sk); 729 AA_BUG(sock->sk->sk_family != PF_UNIX); 730 731 /* investigate only using lock via unix_peer_get() 732 * addr only needs the memory barrier, but need to investigate 733 * path 734 */ 735 unix_state_lock(sock->sk); 736 peer_sk = unix_peer(sock->sk); 737 if (peer_sk) 738 sock_hold(peer_sk); 739 740 is_sk_fs = is_unix_fs(sock->sk); 741 addr = aa_sunaddr(unix_sk(sock->sk), &addrlen); 742 path = unix_sk(sock->sk)->path; 743 unix_state_unlock(sock->sk); 744 745 if (is_sk_fs && peer_sk) 746 sk_req = request; 747 if (sk_req) { 748 error = aa_unix_label_sk_perm(subj_cred, label, op, 749 sk_req, sock->sk, 750 is_sk_fs ? &path : NULL); 751 } 752 if (!peer_sk) 753 goto out; 754 755 peer_addr = aa_sunaddr(unix_sk(peer_sk), &peer_addrlen); 756 757 struct path peer_path; 758 759 peer_path = unix_sk(peer_sk)->path; 760 if (!is_sk_fs && is_unix_fs(peer_sk)) { 761 last_error(error, 762 unix_fs_perm(op, request, subj_cred, label, 763 is_unix_fs(peer_sk) ? &peer_path : NULL)); 764 } else if (!is_sk_fs) { 765 struct aa_label *plabel; 766 struct aa_sk_ctx *pctx = aa_sock(peer_sk); 767 768 rcu_read_lock(); 769 plabel = aa_get_label_rcu(&pctx->label); 770 rcu_read_unlock(); 771 /* no fs check of aa_unix_peer_perm because conditions above 772 * ensure they will never be done 773 */ 774 last_error(error, 775 xcheck(unix_peer_perm(subj_cred, label, op, 776 MAY_READ | MAY_WRITE, sock->sk, 777 is_sk_fs ? &path : NULL, 778 peer_addr, peer_addrlen, 779 is_unix_fs(peer_sk) ? 780 &peer_path : NULL, 781 plabel), 782 unix_peer_perm(file->f_cred, plabel, op, 783 MAY_READ | MAY_WRITE, peer_sk, 784 is_unix_fs(peer_sk) ? 785 &peer_path : NULL, 786 addr, addrlen, 787 is_sk_fs ? &path : NULL, 788 label))); 789 if (!error && !__aa_subj_label_is_cached(plabel, label)) 790 update_peer_ctx(peer_sk, pctx, label); 791 } 792 sock_put(peer_sk); 793 794 out: 795 796 /* update peer cache to latest successful perm check */ 797 if (error == 0) 798 update_sk_ctx(sock->sk, label, plabel); 799 aa_put_label(plabel); 800 801 return error; 802 } 803 804