39 40#include "opt_mac.h" 41 42#include <sys/param.h> 43#include <sys/kernel.h> 44#include <sys/lock.h> 45#include <sys/malloc.h> 46#include <sys/mutex.h> 47#include <sys/mac.h> 48#include <sys/sbuf.h> 49#include <sys/systm.h> 50#include <sys/mount.h> 51#include <sys/file.h> 52#include <sys/namei.h> 53#include <sys/socket.h> 54#include <sys/socketvar.h> 55#include <sys/sysctl.h> 56 57#include <sys/mac_policy.h> 58 59#include <net/bpfdesc.h> 60#include <net/if.h> 61#include <net/if_var.h> 62 63#include <netinet/in.h> 64#include <netinet/ip_var.h> 65 66#include <security/mac/mac_internal.h> 67 68static int mac_enforce_network = 1; 69SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 70 &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 71TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 72 73static int mac_enforce_socket = 1; 74SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 75 &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 76TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 77 78#ifdef MAC_DEBUG 79static unsigned int nmacmbufs, nmacifnets, nmacbpfdescs, nmacsockets, 80 nmacipqs; 81 82SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 83 &nmacmbufs, 0, "number of mbufs in use"); 84SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 85 &nmacifnets, 0, "number of ifnets in use"); 86SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 87 &nmacipqs, 0, "number of ipqs in use"); 88SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 89 &nmacbpfdescs, 0, "number of bpfdescs in use"); 90SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 91 &nmacsockets, 0, "number of sockets in use"); 92#endif 93 94static void mac_socket_label_free(struct label *label); 95 96 97static struct label * 98mbuf_to_label(struct mbuf *mbuf) 99{ 100 struct m_tag *tag; 101 struct label *label; 102 103 tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL); 104 label = (struct label *)(tag+1); 105 106 return (label); 107} 108 109static struct label * 110mac_bpfdesc_label_alloc(void) 111{ 112 struct label *label; 113 114 label = mac_labelzone_alloc(M_WAITOK); 115 MAC_PERFORM(init_bpfdesc_label, label); 116 MAC_DEBUG_COUNTER_INC(&nmacbpfdescs); 117 return (label); 118} 119 120void 121mac_init_bpfdesc(struct bpf_d *bpf_d) 122{ 123 124 bpf_d->bd_label = mac_bpfdesc_label_alloc(); 125} 126 127static struct label * 128mac_ifnet_label_alloc(void) 129{ 130 struct label *label; 131 132 label = mac_labelzone_alloc(M_WAITOK); 133 MAC_PERFORM(init_ifnet_label, label); 134 MAC_DEBUG_COUNTER_INC(&nmacifnets); 135 return (label); 136} 137 138void 139mac_init_ifnet(struct ifnet *ifp) 140{ 141 142 ifp->if_label = mac_ifnet_label_alloc(); 143} 144 145static struct label * 146mac_ipq_label_alloc(int flag) 147{ 148 struct label *label; 149 int error; 150 151 label = mac_labelzone_alloc(flag); 152 if (label == NULL) 153 return (NULL); 154 155 MAC_CHECK(init_ipq_label, label, flag); 156 if (error) { 157 MAC_PERFORM(destroy_ipq_label, label); 158 mac_labelzone_free(label); 159 return (NULL); 160 } 161 MAC_DEBUG_COUNTER_INC(&nmacipqs); 162 return (label); 163} 164 165int 166mac_init_ipq(struct ipq *ipq, int flag) 167{ 168 169 ipq->ipq_label = mac_ipq_label_alloc(flag); 170 if (ipq->ipq_label == NULL) 171 return (ENOMEM); 172 return (0); 173} 174 175int 176mac_init_mbuf_tag(struct m_tag *tag, int flag) 177{ 178 struct label *label; 179 int error; 180 181 label = (struct label *) (tag + 1); 182 mac_init_label(label); 183 184 MAC_CHECK(init_mbuf_label, label, flag); 185 if (error) { 186 MAC_PERFORM(destroy_mbuf_label, label); 187 mac_destroy_label(label); 188 } else { 189 MAC_DEBUG_COUNTER_INC(&nmacmbufs); 190 } 191 return (error); 192} 193 194int 195mac_init_mbuf(struct mbuf *m, int flag) 196{ 197 struct m_tag *tag; 198 int error; 199 200 M_ASSERTPKTHDR(m); 201 202#ifndef MAC_ALWAYS_LABEL_MBUF 203 /* 204 * If conditionally allocating mbuf labels, don't allocate unless 205 * they are required. 206 */ 207 if (!mac_labelmbufs) 208 return (0); 209#endif 210 tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 211 flag); 212 if (tag == NULL) 213 return (ENOMEM); 214 error = mac_init_mbuf_tag(tag, flag); 215 if (error) { 216 m_tag_free(tag); 217 return (error); 218 } 219 m_tag_prepend(m, tag); 220 return (0); 221} 222 223static struct label * 224mac_socket_label_alloc(int flag) 225{ 226 struct label *label; 227 int error; 228 229 label = mac_labelzone_alloc(flag); 230 if (label == NULL) 231 return (NULL); 232 233 MAC_CHECK(init_socket_label, label, flag); 234 if (error) { 235 MAC_PERFORM(destroy_socket_label, label); 236 mac_labelzone_free(label); 237 return (NULL); 238 } 239 MAC_DEBUG_COUNTER_INC(&nmacsockets); 240 return (label); 241} 242 243static struct label * 244mac_socket_peer_label_alloc(int flag) 245{ 246 struct label *label; 247 int error; 248 249 label = mac_labelzone_alloc(flag); 250 if (label == NULL) 251 return (NULL); 252 253 MAC_CHECK(init_socket_peer_label, label, flag); 254 if (error) { 255 MAC_PERFORM(destroy_socket_peer_label, label); 256 mac_labelzone_free(label); 257 return (NULL); 258 } 259 MAC_DEBUG_COUNTER_INC(&nmacsockets); 260 return (label); 261} 262 263int 264mac_init_socket(struct socket *so, int flag) 265{ 266 267 so->so_label = mac_socket_label_alloc(flag); 268 if (so->so_label == NULL) 269 return (ENOMEM); 270 so->so_peerlabel = mac_socket_peer_label_alloc(flag); 271 if (so->so_peerlabel == NULL) { 272 mac_socket_label_free(so->so_label); 273 so->so_label = NULL; 274 return (ENOMEM); 275 } 276 return (0); 277} 278 279static void 280mac_bpfdesc_label_free(struct label *label) 281{ 282 283 MAC_PERFORM(destroy_bpfdesc_label, label); 284 mac_labelzone_free(label); 285 MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs); 286} 287 288void 289mac_destroy_bpfdesc(struct bpf_d *bpf_d) 290{ 291 292 mac_bpfdesc_label_free(bpf_d->bd_label); 293 bpf_d->bd_label = NULL; 294} 295 296static void 297mac_ifnet_label_free(struct label *label) 298{ 299 300 MAC_PERFORM(destroy_ifnet_label, label); 301 mac_labelzone_free(label); 302 MAC_DEBUG_COUNTER_DEC(&nmacifnets); 303} 304 305void 306mac_destroy_ifnet(struct ifnet *ifp) 307{ 308 309 mac_ifnet_label_free(ifp->if_label); 310 ifp->if_label = NULL; 311} 312 313static void 314mac_ipq_label_free(struct label *label) 315{ 316 317 MAC_PERFORM(destroy_ipq_label, label); 318 mac_labelzone_free(label); 319 MAC_DEBUG_COUNTER_DEC(&nmacipqs); 320} 321 322void 323mac_destroy_ipq(struct ipq *ipq) 324{ 325 326 mac_ipq_label_free(ipq->ipq_label); 327 ipq->ipq_label = NULL; 328} 329 330void 331mac_destroy_mbuf_tag(struct m_tag *tag) 332{ 333 struct label *label; 334 335 label = (struct label *)(tag+1); 336 337 MAC_PERFORM(destroy_mbuf_label, label); 338 mac_destroy_label(label); 339 MAC_DEBUG_COUNTER_DEC(&nmacmbufs); 340} 341 342static void 343mac_socket_label_free(struct label *label) 344{ 345 346 MAC_PERFORM(destroy_socket_label, label); 347 mac_labelzone_free(label); 348 MAC_DEBUG_COUNTER_DEC(&nmacsockets); 349} 350 351static void 352mac_socket_peer_label_free(struct label *label) 353{ 354 355 MAC_PERFORM(destroy_socket_peer_label, label); 356 mac_labelzone_free(label); 357 MAC_DEBUG_COUNTER_DEC(&nmacsockets); 358} 359 360void 361mac_destroy_socket(struct socket *socket) 362{ 363 364 mac_socket_label_free(socket->so_label); 365 socket->so_label = NULL; 366 mac_socket_peer_label_free(socket->so_peerlabel); 367 socket->so_peerlabel = NULL; 368} 369 370void 371mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 372{ 373 struct label *src_label, *dest_label; 374 375 src_label = (struct label *)(src+1); 376 dest_label = (struct label *)(dest+1); 377 378 /* 379 * mac_init_mbuf_tag() is called on the target tag in 380 * m_tag_copy(), so we don't need to call it here. 381 */ 382 MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 383} 384 385static int 386mac_externalize_ifnet_label(struct label *label, char *elements, 387 char *outbuf, size_t outbuflen) 388{ 389 int error; 390 391 MAC_EXTERNALIZE(ifnet, label, elements, outbuf, outbuflen); 392 393 return (error); 394} 395 396static int 397mac_externalize_socket_label(struct label *label, char *elements, 398 char *outbuf, size_t outbuflen) 399{ 400 int error; 401 402 MAC_EXTERNALIZE(socket, label, elements, outbuf, outbuflen); 403 404 return (error); 405} 406 407static int 408mac_externalize_socket_peer_label(struct label *label, char *elements, 409 char *outbuf, size_t outbuflen) 410{ 411 int error; 412 413 MAC_EXTERNALIZE(socket_peer, label, elements, outbuf, outbuflen); 414 415 return (error); 416} 417 418static int 419mac_internalize_ifnet_label(struct label *label, char *string) 420{ 421 int error; 422 423 MAC_INTERNALIZE(ifnet, label, string); 424 425 return (error); 426} 427 428static int 429mac_internalize_socket_label(struct label *label, char *string) 430{ 431 int error; 432 433 MAC_INTERNALIZE(socket, label, string); 434 435 return (error); 436} 437 438void 439mac_create_ifnet(struct ifnet *ifnet) 440{ 441 442 MAC_PERFORM(create_ifnet, ifnet, ifnet->if_label); 443} 444 445void 446mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 447{ 448 449 MAC_PERFORM(create_bpfdesc, cred, bpf_d, bpf_d->bd_label); 450} 451 452void 453mac_create_socket(struct ucred *cred, struct socket *socket) 454{ 455 456 MAC_PERFORM(create_socket, cred, socket, socket->so_label); 457} 458 459void 460mac_create_socket_from_socket(struct socket *oldsocket, 461 struct socket *newsocket) 462{ 463 464 MAC_PERFORM(create_socket_from_socket, oldsocket, oldsocket->so_label, 465 newsocket, newsocket->so_label); 466} 467 468static void 469mac_relabel_socket(struct ucred *cred, struct socket *socket, 470 struct label *newlabel) 471{ 472 473 MAC_PERFORM(relabel_socket, cred, socket, socket->so_label, newlabel); 474} 475 476void 477mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 478{ 479 struct label *label; 480 481 label = mbuf_to_label(mbuf); 482 483 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 484 socket->so_peerlabel); 485} 486 487void 488mac_set_socket_peer_from_socket(struct socket *oldsocket, 489 struct socket *newsocket) 490{ 491 492 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 493 oldsocket->so_label, newsocket, newsocket->so_peerlabel); 494} 495 496void 497mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 498{ 499 struct label *label; 500 501 label = mbuf_to_label(datagram); 502 503 MAC_PERFORM(create_datagram_from_ipq, ipq, ipq->ipq_label, 504 datagram, label); 505} 506 507void 508mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 509{ 510 struct label *datagramlabel, *fragmentlabel; 511 512 datagramlabel = mbuf_to_label(datagram); 513 fragmentlabel = mbuf_to_label(fragment); 514 515 MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 516 fragmentlabel); 517} 518 519void 520mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 521{ 522 struct label *label; 523 524 label = mbuf_to_label(fragment); 525 526 MAC_PERFORM(create_ipq, fragment, label, ipq, ipq->ipq_label); 527} 528 529void 530mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 531{ 532 struct label *oldmbuflabel, *newmbuflabel; 533 534 oldmbuflabel = mbuf_to_label(oldmbuf); 535 newmbuflabel = mbuf_to_label(newmbuf); 536 537 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 538 newmbuflabel); 539} 540 541void 542mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 543{ 544 struct label *label; 545 546 label = mbuf_to_label(mbuf); 547 548 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, bpf_d->bd_label, mbuf, 549 label); 550} 551 552void 553mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 554{ 555 struct label *label; 556 557 label = mbuf_to_label(mbuf); 558 559 MAC_PERFORM(create_mbuf_linklayer, ifnet, ifnet->if_label, mbuf, 560 label); 561} 562 563void 564mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 565{ 566 struct label *label; 567 568 label = mbuf_to_label(mbuf); 569 570 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, ifnet->if_label, mbuf, 571 label); 572} 573 574void 575mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 576 struct mbuf *newmbuf) 577{ 578 struct label *oldmbuflabel, *newmbuflabel; 579 580 oldmbuflabel = mbuf_to_label(oldmbuf); 581 newmbuflabel = mbuf_to_label(newmbuf); 582 583 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 584 ifnet, ifnet->if_label, newmbuf, newmbuflabel); 585} 586 587void 588mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 589{ 590 struct label *oldmbuflabel, *newmbuflabel; 591 592 oldmbuflabel = mbuf_to_label(oldmbuf); 593 newmbuflabel = mbuf_to_label(newmbuf); 594 595 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 596 newmbuflabel); 597} 598 599int 600mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 601{ 602 struct label *label; 603 int result; 604 605 label = mbuf_to_label(fragment); 606 607 result = 1; 608 MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 609 ipq->ipq_label); 610 611 return (result); 612} 613 614void 615mac_reflect_mbuf_icmp(struct mbuf *m) 616{ 617 struct label *label; 618 619 label = mbuf_to_label(m); 620 621 MAC_PERFORM(reflect_mbuf_icmp, m, label); 622} 623void 624mac_reflect_mbuf_tcp(struct mbuf *m) 625{ 626 struct label *label; 627 628 label = mbuf_to_label(m); 629 630 MAC_PERFORM(reflect_mbuf_tcp, m, label); 631} 632 633void 634mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 635{ 636 struct label *label; 637 638 label = mbuf_to_label(fragment); 639 640 MAC_PERFORM(update_ipq, fragment, label, ipq, ipq->ipq_label); 641} 642 643void 644mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 645{ 646 struct label *label; 647 648 label = mbuf_to_label(mbuf); 649 650 MAC_PERFORM(create_mbuf_from_socket, socket, socket->so_label, mbuf, 651 label); 652} 653 654int 655mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 656{ 657 int error; 658 659 if (!mac_enforce_network) 660 return (0); 661 662 MAC_CHECK(check_bpfdesc_receive, bpf_d, bpf_d->bd_label, ifnet, 663 ifnet->if_label); 664 665 return (error); 666} 667 668int 669mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 670{ 671 struct label *label; 672 int error; 673 674 M_ASSERTPKTHDR(mbuf); 675 676 if (!mac_enforce_network) 677 return (0); 678 679 label = mbuf_to_label(mbuf); 680 681 MAC_CHECK(check_ifnet_transmit, ifnet, ifnet->if_label, mbuf, 682 label); 683 684 return (error); 685} 686 687int 688mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 689 struct sockaddr *sockaddr) 690{ 691 int error; 692 693 if (!mac_enforce_socket) 694 return (0); 695 696 MAC_CHECK(check_socket_bind, ucred, socket, socket->so_label, 697 sockaddr); 698 699 return (error); 700} 701 702int 703mac_check_socket_connect(struct ucred *cred, struct socket *socket, 704 struct sockaddr *sockaddr) 705{ 706 int error; 707 708 if (!mac_enforce_socket) 709 return (0); 710 711 MAC_CHECK(check_socket_connect, cred, socket, socket->so_label, 712 sockaddr); 713 714 return (error); 715} 716 717int 718mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 719{ 720 struct label *label; 721 int error; 722 723 if (!mac_enforce_socket) 724 return (0); 725 726 label = mbuf_to_label(mbuf); 727 728 MAC_CHECK(check_socket_deliver, socket, socket->so_label, mbuf, 729 label); 730 731 return (error); 732} 733 734int 735mac_check_socket_listen(struct ucred *cred, struct socket *socket) 736{ 737 int error; 738 739 if (!mac_enforce_socket) 740 return (0); 741 742 MAC_CHECK(check_socket_listen, cred, socket, socket->so_label); 743 return (error); 744} 745 746int 747mac_check_socket_receive(struct ucred *cred, struct socket *so) 748{ 749 int error; 750 751 if (!mac_enforce_socket) 752 return (0); 753 754 MAC_CHECK(check_socket_receive, cred, so, so->so_label); 755 756 return (error); 757} 758 759static int 760mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 761 struct label *newlabel) 762{ 763 int error; 764 765 MAC_CHECK(check_socket_relabel, cred, socket, socket->so_label, 766 newlabel); 767 768 return (error); 769} 770 771int 772mac_check_socket_send(struct ucred *cred, struct socket *so) 773{ 774 int error; 775 776 if (!mac_enforce_socket) 777 return (0); 778 779 MAC_CHECK(check_socket_send, cred, so, so->so_label); 780 781 return (error); 782} 783 784int 785mac_check_socket_visible(struct ucred *cred, struct socket *socket) 786{ 787 int error; 788 789 if (!mac_enforce_socket) 790 return (0); 791 792 MAC_CHECK(check_socket_visible, cred, socket, socket->so_label); 793 794 return (error); 795} 796 797int 798mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 799 struct ifnet *ifnet) 800{ 801 char *elements, *buffer; 802 struct mac mac; 803 int error; 804 805 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 806 if (error) 807 return (error); 808 809 error = mac_check_structmac_consistent(&mac); 810 if (error) 811 return (error); 812 813 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 814 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 815 if (error) { 816 free(elements, M_MACTEMP); 817 return (error); 818 } 819 820 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 821 error = mac_externalize_ifnet_label(ifnet->if_label, elements, 822 buffer, mac.m_buflen); 823 if (error == 0) 824 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 825 826 free(buffer, M_MACTEMP); 827 free(elements, M_MACTEMP); 828 829 return (error); 830} 831 832int 833mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 834 struct ifnet *ifnet) 835{ 836 struct label *intlabel; 837 struct mac mac; 838 char *buffer; 839 int error; 840 841 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 842 if (error) 843 return (error); 844 845 error = mac_check_structmac_consistent(&mac); 846 if (error) 847 return (error); 848 849 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 850 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 851 if (error) { 852 free(buffer, M_MACTEMP); 853 return (error); 854 } 855 856 intlabel = mac_ifnet_label_alloc(); 857 error = mac_internalize_ifnet_label(intlabel, buffer); 858 free(buffer, M_MACTEMP); 859 if (error) { 860 mac_ifnet_label_free(intlabel); 861 return (error); 862 } 863 864 /* 865 * XXX: Note that this is a redundant privilege check, since 866 * policies impose this check themselves if required by the 867 * policy. Eventually, this should go away. 868 */ 869 error = suser_cred(cred, 0); 870 if (error) { 871 mac_ifnet_label_free(intlabel); 872 return (error); 873 } 874 875 MAC_CHECK(check_ifnet_relabel, cred, ifnet, ifnet->if_label, 876 intlabel); 877 if (error) { 878 mac_ifnet_label_free(intlabel); 879 return (error); 880 } 881 882 MAC_PERFORM(relabel_ifnet, cred, ifnet, ifnet->if_label, intlabel); 883 884 mac_ifnet_label_free(intlabel); 885 return (0); 886} 887 888int
| 39 40#include "opt_mac.h" 41 42#include <sys/param.h> 43#include <sys/kernel.h> 44#include <sys/lock.h> 45#include <sys/malloc.h> 46#include <sys/mutex.h> 47#include <sys/mac.h> 48#include <sys/sbuf.h> 49#include <sys/systm.h> 50#include <sys/mount.h> 51#include <sys/file.h> 52#include <sys/namei.h> 53#include <sys/socket.h> 54#include <sys/socketvar.h> 55#include <sys/sysctl.h> 56 57#include <sys/mac_policy.h> 58 59#include <net/bpfdesc.h> 60#include <net/if.h> 61#include <net/if_var.h> 62 63#include <netinet/in.h> 64#include <netinet/ip_var.h> 65 66#include <security/mac/mac_internal.h> 67 68static int mac_enforce_network = 1; 69SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 70 &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 71TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 72 73static int mac_enforce_socket = 1; 74SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 75 &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 76TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 77 78#ifdef MAC_DEBUG 79static unsigned int nmacmbufs, nmacifnets, nmacbpfdescs, nmacsockets, 80 nmacipqs; 81 82SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 83 &nmacmbufs, 0, "number of mbufs in use"); 84SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 85 &nmacifnets, 0, "number of ifnets in use"); 86SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 87 &nmacipqs, 0, "number of ipqs in use"); 88SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 89 &nmacbpfdescs, 0, "number of bpfdescs in use"); 90SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 91 &nmacsockets, 0, "number of sockets in use"); 92#endif 93 94static void mac_socket_label_free(struct label *label); 95 96 97static struct label * 98mbuf_to_label(struct mbuf *mbuf) 99{ 100 struct m_tag *tag; 101 struct label *label; 102 103 tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL); 104 label = (struct label *)(tag+1); 105 106 return (label); 107} 108 109static struct label * 110mac_bpfdesc_label_alloc(void) 111{ 112 struct label *label; 113 114 label = mac_labelzone_alloc(M_WAITOK); 115 MAC_PERFORM(init_bpfdesc_label, label); 116 MAC_DEBUG_COUNTER_INC(&nmacbpfdescs); 117 return (label); 118} 119 120void 121mac_init_bpfdesc(struct bpf_d *bpf_d) 122{ 123 124 bpf_d->bd_label = mac_bpfdesc_label_alloc(); 125} 126 127static struct label * 128mac_ifnet_label_alloc(void) 129{ 130 struct label *label; 131 132 label = mac_labelzone_alloc(M_WAITOK); 133 MAC_PERFORM(init_ifnet_label, label); 134 MAC_DEBUG_COUNTER_INC(&nmacifnets); 135 return (label); 136} 137 138void 139mac_init_ifnet(struct ifnet *ifp) 140{ 141 142 ifp->if_label = mac_ifnet_label_alloc(); 143} 144 145static struct label * 146mac_ipq_label_alloc(int flag) 147{ 148 struct label *label; 149 int error; 150 151 label = mac_labelzone_alloc(flag); 152 if (label == NULL) 153 return (NULL); 154 155 MAC_CHECK(init_ipq_label, label, flag); 156 if (error) { 157 MAC_PERFORM(destroy_ipq_label, label); 158 mac_labelzone_free(label); 159 return (NULL); 160 } 161 MAC_DEBUG_COUNTER_INC(&nmacipqs); 162 return (label); 163} 164 165int 166mac_init_ipq(struct ipq *ipq, int flag) 167{ 168 169 ipq->ipq_label = mac_ipq_label_alloc(flag); 170 if (ipq->ipq_label == NULL) 171 return (ENOMEM); 172 return (0); 173} 174 175int 176mac_init_mbuf_tag(struct m_tag *tag, int flag) 177{ 178 struct label *label; 179 int error; 180 181 label = (struct label *) (tag + 1); 182 mac_init_label(label); 183 184 MAC_CHECK(init_mbuf_label, label, flag); 185 if (error) { 186 MAC_PERFORM(destroy_mbuf_label, label); 187 mac_destroy_label(label); 188 } else { 189 MAC_DEBUG_COUNTER_INC(&nmacmbufs); 190 } 191 return (error); 192} 193 194int 195mac_init_mbuf(struct mbuf *m, int flag) 196{ 197 struct m_tag *tag; 198 int error; 199 200 M_ASSERTPKTHDR(m); 201 202#ifndef MAC_ALWAYS_LABEL_MBUF 203 /* 204 * If conditionally allocating mbuf labels, don't allocate unless 205 * they are required. 206 */ 207 if (!mac_labelmbufs) 208 return (0); 209#endif 210 tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 211 flag); 212 if (tag == NULL) 213 return (ENOMEM); 214 error = mac_init_mbuf_tag(tag, flag); 215 if (error) { 216 m_tag_free(tag); 217 return (error); 218 } 219 m_tag_prepend(m, tag); 220 return (0); 221} 222 223static struct label * 224mac_socket_label_alloc(int flag) 225{ 226 struct label *label; 227 int error; 228 229 label = mac_labelzone_alloc(flag); 230 if (label == NULL) 231 return (NULL); 232 233 MAC_CHECK(init_socket_label, label, flag); 234 if (error) { 235 MAC_PERFORM(destroy_socket_label, label); 236 mac_labelzone_free(label); 237 return (NULL); 238 } 239 MAC_DEBUG_COUNTER_INC(&nmacsockets); 240 return (label); 241} 242 243static struct label * 244mac_socket_peer_label_alloc(int flag) 245{ 246 struct label *label; 247 int error; 248 249 label = mac_labelzone_alloc(flag); 250 if (label == NULL) 251 return (NULL); 252 253 MAC_CHECK(init_socket_peer_label, label, flag); 254 if (error) { 255 MAC_PERFORM(destroy_socket_peer_label, label); 256 mac_labelzone_free(label); 257 return (NULL); 258 } 259 MAC_DEBUG_COUNTER_INC(&nmacsockets); 260 return (label); 261} 262 263int 264mac_init_socket(struct socket *so, int flag) 265{ 266 267 so->so_label = mac_socket_label_alloc(flag); 268 if (so->so_label == NULL) 269 return (ENOMEM); 270 so->so_peerlabel = mac_socket_peer_label_alloc(flag); 271 if (so->so_peerlabel == NULL) { 272 mac_socket_label_free(so->so_label); 273 so->so_label = NULL; 274 return (ENOMEM); 275 } 276 return (0); 277} 278 279static void 280mac_bpfdesc_label_free(struct label *label) 281{ 282 283 MAC_PERFORM(destroy_bpfdesc_label, label); 284 mac_labelzone_free(label); 285 MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs); 286} 287 288void 289mac_destroy_bpfdesc(struct bpf_d *bpf_d) 290{ 291 292 mac_bpfdesc_label_free(bpf_d->bd_label); 293 bpf_d->bd_label = NULL; 294} 295 296static void 297mac_ifnet_label_free(struct label *label) 298{ 299 300 MAC_PERFORM(destroy_ifnet_label, label); 301 mac_labelzone_free(label); 302 MAC_DEBUG_COUNTER_DEC(&nmacifnets); 303} 304 305void 306mac_destroy_ifnet(struct ifnet *ifp) 307{ 308 309 mac_ifnet_label_free(ifp->if_label); 310 ifp->if_label = NULL; 311} 312 313static void 314mac_ipq_label_free(struct label *label) 315{ 316 317 MAC_PERFORM(destroy_ipq_label, label); 318 mac_labelzone_free(label); 319 MAC_DEBUG_COUNTER_DEC(&nmacipqs); 320} 321 322void 323mac_destroy_ipq(struct ipq *ipq) 324{ 325 326 mac_ipq_label_free(ipq->ipq_label); 327 ipq->ipq_label = NULL; 328} 329 330void 331mac_destroy_mbuf_tag(struct m_tag *tag) 332{ 333 struct label *label; 334 335 label = (struct label *)(tag+1); 336 337 MAC_PERFORM(destroy_mbuf_label, label); 338 mac_destroy_label(label); 339 MAC_DEBUG_COUNTER_DEC(&nmacmbufs); 340} 341 342static void 343mac_socket_label_free(struct label *label) 344{ 345 346 MAC_PERFORM(destroy_socket_label, label); 347 mac_labelzone_free(label); 348 MAC_DEBUG_COUNTER_DEC(&nmacsockets); 349} 350 351static void 352mac_socket_peer_label_free(struct label *label) 353{ 354 355 MAC_PERFORM(destroy_socket_peer_label, label); 356 mac_labelzone_free(label); 357 MAC_DEBUG_COUNTER_DEC(&nmacsockets); 358} 359 360void 361mac_destroy_socket(struct socket *socket) 362{ 363 364 mac_socket_label_free(socket->so_label); 365 socket->so_label = NULL; 366 mac_socket_peer_label_free(socket->so_peerlabel); 367 socket->so_peerlabel = NULL; 368} 369 370void 371mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 372{ 373 struct label *src_label, *dest_label; 374 375 src_label = (struct label *)(src+1); 376 dest_label = (struct label *)(dest+1); 377 378 /* 379 * mac_init_mbuf_tag() is called on the target tag in 380 * m_tag_copy(), so we don't need to call it here. 381 */ 382 MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 383} 384 385static int 386mac_externalize_ifnet_label(struct label *label, char *elements, 387 char *outbuf, size_t outbuflen) 388{ 389 int error; 390 391 MAC_EXTERNALIZE(ifnet, label, elements, outbuf, outbuflen); 392 393 return (error); 394} 395 396static int 397mac_externalize_socket_label(struct label *label, char *elements, 398 char *outbuf, size_t outbuflen) 399{ 400 int error; 401 402 MAC_EXTERNALIZE(socket, label, elements, outbuf, outbuflen); 403 404 return (error); 405} 406 407static int 408mac_externalize_socket_peer_label(struct label *label, char *elements, 409 char *outbuf, size_t outbuflen) 410{ 411 int error; 412 413 MAC_EXTERNALIZE(socket_peer, label, elements, outbuf, outbuflen); 414 415 return (error); 416} 417 418static int 419mac_internalize_ifnet_label(struct label *label, char *string) 420{ 421 int error; 422 423 MAC_INTERNALIZE(ifnet, label, string); 424 425 return (error); 426} 427 428static int 429mac_internalize_socket_label(struct label *label, char *string) 430{ 431 int error; 432 433 MAC_INTERNALIZE(socket, label, string); 434 435 return (error); 436} 437 438void 439mac_create_ifnet(struct ifnet *ifnet) 440{ 441 442 MAC_PERFORM(create_ifnet, ifnet, ifnet->if_label); 443} 444 445void 446mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 447{ 448 449 MAC_PERFORM(create_bpfdesc, cred, bpf_d, bpf_d->bd_label); 450} 451 452void 453mac_create_socket(struct ucred *cred, struct socket *socket) 454{ 455 456 MAC_PERFORM(create_socket, cred, socket, socket->so_label); 457} 458 459void 460mac_create_socket_from_socket(struct socket *oldsocket, 461 struct socket *newsocket) 462{ 463 464 MAC_PERFORM(create_socket_from_socket, oldsocket, oldsocket->so_label, 465 newsocket, newsocket->so_label); 466} 467 468static void 469mac_relabel_socket(struct ucred *cred, struct socket *socket, 470 struct label *newlabel) 471{ 472 473 MAC_PERFORM(relabel_socket, cred, socket, socket->so_label, newlabel); 474} 475 476void 477mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 478{ 479 struct label *label; 480 481 label = mbuf_to_label(mbuf); 482 483 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 484 socket->so_peerlabel); 485} 486 487void 488mac_set_socket_peer_from_socket(struct socket *oldsocket, 489 struct socket *newsocket) 490{ 491 492 MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 493 oldsocket->so_label, newsocket, newsocket->so_peerlabel); 494} 495 496void 497mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 498{ 499 struct label *label; 500 501 label = mbuf_to_label(datagram); 502 503 MAC_PERFORM(create_datagram_from_ipq, ipq, ipq->ipq_label, 504 datagram, label); 505} 506 507void 508mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 509{ 510 struct label *datagramlabel, *fragmentlabel; 511 512 datagramlabel = mbuf_to_label(datagram); 513 fragmentlabel = mbuf_to_label(fragment); 514 515 MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 516 fragmentlabel); 517} 518 519void 520mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 521{ 522 struct label *label; 523 524 label = mbuf_to_label(fragment); 525 526 MAC_PERFORM(create_ipq, fragment, label, ipq, ipq->ipq_label); 527} 528 529void 530mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 531{ 532 struct label *oldmbuflabel, *newmbuflabel; 533 534 oldmbuflabel = mbuf_to_label(oldmbuf); 535 newmbuflabel = mbuf_to_label(newmbuf); 536 537 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 538 newmbuflabel); 539} 540 541void 542mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 543{ 544 struct label *label; 545 546 label = mbuf_to_label(mbuf); 547 548 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, bpf_d->bd_label, mbuf, 549 label); 550} 551 552void 553mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 554{ 555 struct label *label; 556 557 label = mbuf_to_label(mbuf); 558 559 MAC_PERFORM(create_mbuf_linklayer, ifnet, ifnet->if_label, mbuf, 560 label); 561} 562 563void 564mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 565{ 566 struct label *label; 567 568 label = mbuf_to_label(mbuf); 569 570 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, ifnet->if_label, mbuf, 571 label); 572} 573 574void 575mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 576 struct mbuf *newmbuf) 577{ 578 struct label *oldmbuflabel, *newmbuflabel; 579 580 oldmbuflabel = mbuf_to_label(oldmbuf); 581 newmbuflabel = mbuf_to_label(newmbuf); 582 583 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 584 ifnet, ifnet->if_label, newmbuf, newmbuflabel); 585} 586 587void 588mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 589{ 590 struct label *oldmbuflabel, *newmbuflabel; 591 592 oldmbuflabel = mbuf_to_label(oldmbuf); 593 newmbuflabel = mbuf_to_label(newmbuf); 594 595 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 596 newmbuflabel); 597} 598 599int 600mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 601{ 602 struct label *label; 603 int result; 604 605 label = mbuf_to_label(fragment); 606 607 result = 1; 608 MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 609 ipq->ipq_label); 610 611 return (result); 612} 613 614void 615mac_reflect_mbuf_icmp(struct mbuf *m) 616{ 617 struct label *label; 618 619 label = mbuf_to_label(m); 620 621 MAC_PERFORM(reflect_mbuf_icmp, m, label); 622} 623void 624mac_reflect_mbuf_tcp(struct mbuf *m) 625{ 626 struct label *label; 627 628 label = mbuf_to_label(m); 629 630 MAC_PERFORM(reflect_mbuf_tcp, m, label); 631} 632 633void 634mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 635{ 636 struct label *label; 637 638 label = mbuf_to_label(fragment); 639 640 MAC_PERFORM(update_ipq, fragment, label, ipq, ipq->ipq_label); 641} 642 643void 644mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 645{ 646 struct label *label; 647 648 label = mbuf_to_label(mbuf); 649 650 MAC_PERFORM(create_mbuf_from_socket, socket, socket->so_label, mbuf, 651 label); 652} 653 654int 655mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 656{ 657 int error; 658 659 if (!mac_enforce_network) 660 return (0); 661 662 MAC_CHECK(check_bpfdesc_receive, bpf_d, bpf_d->bd_label, ifnet, 663 ifnet->if_label); 664 665 return (error); 666} 667 668int 669mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 670{ 671 struct label *label; 672 int error; 673 674 M_ASSERTPKTHDR(mbuf); 675 676 if (!mac_enforce_network) 677 return (0); 678 679 label = mbuf_to_label(mbuf); 680 681 MAC_CHECK(check_ifnet_transmit, ifnet, ifnet->if_label, mbuf, 682 label); 683 684 return (error); 685} 686 687int 688mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 689 struct sockaddr *sockaddr) 690{ 691 int error; 692 693 if (!mac_enforce_socket) 694 return (0); 695 696 MAC_CHECK(check_socket_bind, ucred, socket, socket->so_label, 697 sockaddr); 698 699 return (error); 700} 701 702int 703mac_check_socket_connect(struct ucred *cred, struct socket *socket, 704 struct sockaddr *sockaddr) 705{ 706 int error; 707 708 if (!mac_enforce_socket) 709 return (0); 710 711 MAC_CHECK(check_socket_connect, cred, socket, socket->so_label, 712 sockaddr); 713 714 return (error); 715} 716 717int 718mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 719{ 720 struct label *label; 721 int error; 722 723 if (!mac_enforce_socket) 724 return (0); 725 726 label = mbuf_to_label(mbuf); 727 728 MAC_CHECK(check_socket_deliver, socket, socket->so_label, mbuf, 729 label); 730 731 return (error); 732} 733 734int 735mac_check_socket_listen(struct ucred *cred, struct socket *socket) 736{ 737 int error; 738 739 if (!mac_enforce_socket) 740 return (0); 741 742 MAC_CHECK(check_socket_listen, cred, socket, socket->so_label); 743 return (error); 744} 745 746int 747mac_check_socket_receive(struct ucred *cred, struct socket *so) 748{ 749 int error; 750 751 if (!mac_enforce_socket) 752 return (0); 753 754 MAC_CHECK(check_socket_receive, cred, so, so->so_label); 755 756 return (error); 757} 758 759static int 760mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 761 struct label *newlabel) 762{ 763 int error; 764 765 MAC_CHECK(check_socket_relabel, cred, socket, socket->so_label, 766 newlabel); 767 768 return (error); 769} 770 771int 772mac_check_socket_send(struct ucred *cred, struct socket *so) 773{ 774 int error; 775 776 if (!mac_enforce_socket) 777 return (0); 778 779 MAC_CHECK(check_socket_send, cred, so, so->so_label); 780 781 return (error); 782} 783 784int 785mac_check_socket_visible(struct ucred *cred, struct socket *socket) 786{ 787 int error; 788 789 if (!mac_enforce_socket) 790 return (0); 791 792 MAC_CHECK(check_socket_visible, cred, socket, socket->so_label); 793 794 return (error); 795} 796 797int 798mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 799 struct ifnet *ifnet) 800{ 801 char *elements, *buffer; 802 struct mac mac; 803 int error; 804 805 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 806 if (error) 807 return (error); 808 809 error = mac_check_structmac_consistent(&mac); 810 if (error) 811 return (error); 812 813 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 814 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 815 if (error) { 816 free(elements, M_MACTEMP); 817 return (error); 818 } 819 820 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 821 error = mac_externalize_ifnet_label(ifnet->if_label, elements, 822 buffer, mac.m_buflen); 823 if (error == 0) 824 error = copyout(buffer, mac.m_string, strlen(buffer)+1); 825 826 free(buffer, M_MACTEMP); 827 free(elements, M_MACTEMP); 828 829 return (error); 830} 831 832int 833mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 834 struct ifnet *ifnet) 835{ 836 struct label *intlabel; 837 struct mac mac; 838 char *buffer; 839 int error; 840 841 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 842 if (error) 843 return (error); 844 845 error = mac_check_structmac_consistent(&mac); 846 if (error) 847 return (error); 848 849 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 850 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 851 if (error) { 852 free(buffer, M_MACTEMP); 853 return (error); 854 } 855 856 intlabel = mac_ifnet_label_alloc(); 857 error = mac_internalize_ifnet_label(intlabel, buffer); 858 free(buffer, M_MACTEMP); 859 if (error) { 860 mac_ifnet_label_free(intlabel); 861 return (error); 862 } 863 864 /* 865 * XXX: Note that this is a redundant privilege check, since 866 * policies impose this check themselves if required by the 867 * policy. Eventually, this should go away. 868 */ 869 error = suser_cred(cred, 0); 870 if (error) { 871 mac_ifnet_label_free(intlabel); 872 return (error); 873 } 874 875 MAC_CHECK(check_ifnet_relabel, cred, ifnet, ifnet->if_label, 876 intlabel); 877 if (error) { 878 mac_ifnet_label_free(intlabel); 879 return (error); 880 } 881 882 MAC_PERFORM(relabel_ifnet, cred, ifnet, ifnet->if_label, intlabel); 883 884 mac_ifnet_label_free(intlabel); 885 return (0); 886} 887 888int
|