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