17bc82500SRobert Watson /*- 27bc82500SRobert Watson * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson 37bc82500SRobert Watson * Copyright (c) 2001 Ilmar S. Habibulin 42d3db0b8SRobert Watson * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc. 57bc82500SRobert Watson * All rights reserved. 67bc82500SRobert Watson * 77bc82500SRobert Watson * This software was developed by Robert Watson and Ilmar Habibulin for the 87bc82500SRobert Watson * TrustedBSD Project. 97bc82500SRobert Watson * 106201265bSRobert Watson * This software was developed for the FreeBSD Project in part by Network 116201265bSRobert Watson * Associates Laboratories, the Security Research Division of Network 126201265bSRobert Watson * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 136201265bSRobert Watson * as part of the DARPA CHATS research program. 147bc82500SRobert Watson * 157bc82500SRobert Watson * Redistribution and use in source and binary forms, with or without 167bc82500SRobert Watson * modification, are permitted provided that the following conditions 177bc82500SRobert Watson * are met: 187bc82500SRobert Watson * 1. Redistributions of source code must retain the above copyright 197bc82500SRobert Watson * notice, this list of conditions and the following disclaimer. 207bc82500SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 217bc82500SRobert Watson * notice, this list of conditions and the following disclaimer in the 227bc82500SRobert Watson * documentation and/or other materials provided with the distribution. 237bc82500SRobert Watson * 247bc82500SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 257bc82500SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 267bc82500SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 277bc82500SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 287bc82500SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 297bc82500SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 307bc82500SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 317bc82500SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 327bc82500SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 337bc82500SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 347bc82500SRobert Watson * SUCH DAMAGE. 357bc82500SRobert Watson */ 36677b542eSDavid E. O'Brien 37677b542eSDavid E. O'Brien #include <sys/cdefs.h> 38677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 39677b542eSDavid E. O'Brien 407bc82500SRobert Watson #include "opt_mac.h" 41f9d0d524SRobert Watson 427bc82500SRobert Watson #include <sys/param.h> 4395fab37eSRobert Watson #include <sys/kernel.h> 4495fab37eSRobert Watson #include <sys/lock.h> 45b656366bSBruce Evans #include <sys/malloc.h> 4695fab37eSRobert Watson #include <sys/mutex.h> 4795fab37eSRobert Watson #include <sys/mac.h> 48f51e5803SRobert Watson #include <sys/sbuf.h> 4995fab37eSRobert Watson #include <sys/systm.h> 5095fab37eSRobert Watson #include <sys/mount.h> 5195fab37eSRobert Watson #include <sys/file.h> 5295fab37eSRobert Watson #include <sys/namei.h> 53a557af22SRobert Watson #include <sys/protosw.h> 5495fab37eSRobert Watson #include <sys/socket.h> 5595fab37eSRobert Watson #include <sys/socketvar.h> 5695fab37eSRobert Watson #include <sys/sysctl.h> 5795fab37eSRobert Watson 5895fab37eSRobert Watson #include <sys/mac_policy.h> 5995fab37eSRobert Watson 6095fab37eSRobert Watson #include <net/bpfdesc.h> 6195fab37eSRobert Watson #include <net/if.h> 6295fab37eSRobert Watson #include <net/if_var.h> 6395fab37eSRobert Watson 6495fab37eSRobert Watson #include <netinet/in.h> 65a557af22SRobert Watson #include <netinet/in_pcb.h> 6695fab37eSRobert Watson #include <netinet/ip_var.h> 6795fab37eSRobert Watson 6828e65e3dSRobert Watson #include <security/mac/mac_internal.h> 69a3df768bSRobert Watson 7095fab37eSRobert Watson static int mac_enforce_network = 1; 7195fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW, 7295fab37eSRobert Watson &mac_enforce_network, 0, "Enforce MAC policy on network packets"); 7395fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network); 7495fab37eSRobert Watson 7595fab37eSRobert Watson static int mac_enforce_socket = 1; 7695fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW, 7795fab37eSRobert Watson &mac_enforce_socket, 0, "Enforce MAC policy on socket operations"); 7895fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket); 7995fab37eSRobert Watson 80f050add5SRobert Watson #ifdef MAC_DEBUG 8128e65e3dSRobert Watson static unsigned int nmacmbufs, nmacifnets, nmacbpfdescs, nmacsockets, 82a557af22SRobert Watson nmacinpcbs, nmacipqs; 838d8d5ea8SRobert Watson 84b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD, 8595fab37eSRobert Watson &nmacmbufs, 0, "number of mbufs in use"); 86b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD, 8795fab37eSRobert Watson &nmacifnets, 0, "number of ifnets in use"); 88a557af22SRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, inpcbs, CTLFLAG_RD, 89a557af22SRobert Watson &nmacinpcbs, 0, "number of inpcbs in use"); 90b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD, 9195fab37eSRobert Watson &nmacipqs, 0, "number of ipqs in use"); 92b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD, 9395fab37eSRobert Watson &nmacbpfdescs, 0, "number of bpfdescs in use"); 94b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD, 9595fab37eSRobert Watson &nmacsockets, 0, "number of sockets in use"); 96f050add5SRobert Watson #endif 9795fab37eSRobert Watson 9810eeb10cSRobert Watson static struct label * 9910eeb10cSRobert Watson mbuf_to_label(struct mbuf *mbuf) 10010eeb10cSRobert Watson { 101225bff6fSRobert Watson struct m_tag *tag; 10210eeb10cSRobert Watson struct label *label; 10310eeb10cSRobert Watson 104225bff6fSRobert Watson tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL); 105225bff6fSRobert Watson label = (struct label *)(tag+1); 10610eeb10cSRobert Watson 10710eeb10cSRobert Watson return (label); 10810eeb10cSRobert Watson } 10910eeb10cSRobert Watson 110eca8a663SRobert Watson static struct label * 111eca8a663SRobert Watson mac_bpfdesc_label_alloc(void) 112eca8a663SRobert Watson { 113eca8a663SRobert Watson struct label *label; 114eca8a663SRobert Watson 115eca8a663SRobert Watson label = mac_labelzone_alloc(M_WAITOK); 116eca8a663SRobert Watson MAC_PERFORM(init_bpfdesc_label, label); 117eca8a663SRobert Watson MAC_DEBUG_COUNTER_INC(&nmacbpfdescs); 118eca8a663SRobert Watson return (label); 119eca8a663SRobert Watson } 120eca8a663SRobert Watson 12108bcdc58SRobert Watson void 12287807196SRobert Watson mac_init_bpfdesc(struct bpf_d *bpf_d) 12308bcdc58SRobert Watson { 12408bcdc58SRobert Watson 125eca8a663SRobert Watson bpf_d->bd_label = mac_bpfdesc_label_alloc(); 12608bcdc58SRobert Watson } 12708bcdc58SRobert Watson 128eca8a663SRobert Watson static struct label * 129eca8a663SRobert Watson mac_ifnet_label_alloc(void) 130f7b951a8SRobert Watson { 131eca8a663SRobert Watson struct label *label; 132f7b951a8SRobert Watson 133eca8a663SRobert Watson label = mac_labelzone_alloc(M_WAITOK); 134f7b951a8SRobert Watson MAC_PERFORM(init_ifnet_label, label); 1358d8d5ea8SRobert Watson MAC_DEBUG_COUNTER_INC(&nmacifnets); 136eca8a663SRobert Watson return (label); 137f7b951a8SRobert Watson } 138f7b951a8SRobert Watson 13908bcdc58SRobert Watson void 14008bcdc58SRobert Watson mac_init_ifnet(struct ifnet *ifp) 14108bcdc58SRobert Watson { 14208bcdc58SRobert Watson 143eca8a663SRobert Watson ifp->if_label = mac_ifnet_label_alloc(); 144eca8a663SRobert Watson } 145eca8a663SRobert Watson 146eca8a663SRobert Watson static struct label * 147a557af22SRobert Watson mac_inpcb_label_alloc(int flag) 148a557af22SRobert Watson { 149a557af22SRobert Watson struct label *label; 150a557af22SRobert Watson int error; 151a557af22SRobert Watson 152a557af22SRobert Watson label = mac_labelzone_alloc(flag); 153a557af22SRobert Watson if (label == NULL) 154a557af22SRobert Watson return (NULL); 155a557af22SRobert Watson MAC_CHECK(init_inpcb_label, label, flag); 156a557af22SRobert Watson if (error) { 157a557af22SRobert Watson MAC_PERFORM(destroy_inpcb_label, label); 158a557af22SRobert Watson mac_labelzone_free(label); 159a557af22SRobert Watson return (NULL); 160a557af22SRobert Watson } 161a557af22SRobert Watson MAC_DEBUG_COUNTER_INC(&nmacinpcbs); 162a557af22SRobert Watson return (label); 163a557af22SRobert Watson } 164a557af22SRobert Watson 165a557af22SRobert Watson int 166a557af22SRobert Watson mac_init_inpcb(struct inpcb *inp, int flag) 167a557af22SRobert Watson { 168a557af22SRobert Watson 169a557af22SRobert Watson inp->inp_label = mac_inpcb_label_alloc(flag); 170a557af22SRobert Watson if (inp->inp_label == NULL) 171a557af22SRobert Watson return (ENOMEM); 172a557af22SRobert Watson return (0); 173a557af22SRobert Watson } 174a557af22SRobert Watson 175a557af22SRobert Watson static struct label * 176eca8a663SRobert Watson mac_ipq_label_alloc(int flag) 177eca8a663SRobert Watson { 178eca8a663SRobert Watson struct label *label; 179eca8a663SRobert Watson int error; 180eca8a663SRobert Watson 181eca8a663SRobert Watson label = mac_labelzone_alloc(flag); 182eca8a663SRobert Watson if (label == NULL) 183eca8a663SRobert Watson return (NULL); 184eca8a663SRobert Watson 185eca8a663SRobert Watson MAC_CHECK(init_ipq_label, label, flag); 186eca8a663SRobert Watson if (error) { 187eca8a663SRobert Watson MAC_PERFORM(destroy_ipq_label, label); 188eca8a663SRobert Watson mac_labelzone_free(label); 189eca8a663SRobert Watson return (NULL); 190eca8a663SRobert Watson } 191eca8a663SRobert Watson MAC_DEBUG_COUNTER_INC(&nmacipqs); 192eca8a663SRobert Watson return (label); 19308bcdc58SRobert Watson } 19408bcdc58SRobert Watson 1955e7ce478SRobert Watson int 1965e7ce478SRobert Watson mac_init_ipq(struct ipq *ipq, int flag) 19708bcdc58SRobert Watson { 19808bcdc58SRobert Watson 199eca8a663SRobert Watson ipq->ipq_label = mac_ipq_label_alloc(flag); 200eca8a663SRobert Watson if (ipq->ipq_label == NULL) 201eca8a663SRobert Watson return (ENOMEM); 202eca8a663SRobert Watson return (0); 20308bcdc58SRobert Watson } 20408bcdc58SRobert Watson 20587807196SRobert Watson int 206225bff6fSRobert Watson mac_init_mbuf_tag(struct m_tag *tag, int flag) 20708bcdc58SRobert Watson { 208225bff6fSRobert Watson struct label *label; 2096d1a6a9aSRobert Watson int error; 21056c15412SRobert Watson 211225bff6fSRobert Watson label = (struct label *) (tag + 1); 212225bff6fSRobert Watson mac_init_label(label); 21308bcdc58SRobert Watson 2146d1a6a9aSRobert Watson MAC_CHECK(init_mbuf_label, label, flag); 21556c15412SRobert Watson if (error) { 216225bff6fSRobert Watson MAC_PERFORM(destroy_mbuf_label, label); 217225bff6fSRobert Watson mac_destroy_label(label); 2188d8d5ea8SRobert Watson } else { 2198d8d5ea8SRobert Watson MAC_DEBUG_COUNTER_INC(&nmacmbufs); 22056c15412SRobert Watson } 22156c15412SRobert Watson return (error); 22208bcdc58SRobert Watson } 22308bcdc58SRobert Watson 224225bff6fSRobert Watson int 225225bff6fSRobert Watson mac_init_mbuf(struct mbuf *m, int flag) 226225bff6fSRobert Watson { 227225bff6fSRobert Watson struct m_tag *tag; 228225bff6fSRobert Watson int error; 229225bff6fSRobert Watson 230225bff6fSRobert Watson M_ASSERTPKTHDR(m); 231225bff6fSRobert Watson 232225bff6fSRobert Watson #ifndef MAC_ALWAYS_LABEL_MBUF 233225bff6fSRobert Watson /* 23419c3e120SRobert Watson * If conditionally allocating mbuf labels, don't allocate unless 23519c3e120SRobert Watson * they are required. 236225bff6fSRobert Watson */ 23719c3e120SRobert Watson if (!mac_labelmbufs) 23819c3e120SRobert Watson return (0); 239225bff6fSRobert Watson #endif 240225bff6fSRobert Watson tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label), 241225bff6fSRobert Watson flag); 242225bff6fSRobert Watson if (tag == NULL) 243225bff6fSRobert Watson return (ENOMEM); 244225bff6fSRobert Watson error = mac_init_mbuf_tag(tag, flag); 245225bff6fSRobert Watson if (error) { 246225bff6fSRobert Watson m_tag_free(tag); 247225bff6fSRobert Watson return (error); 248225bff6fSRobert Watson } 249225bff6fSRobert Watson m_tag_prepend(m, tag); 250225bff6fSRobert Watson return (0); 251225bff6fSRobert Watson } 252225bff6fSRobert Watson 253b0323ea3SRobert Watson struct label * 254eca8a663SRobert Watson mac_socket_label_alloc(int flag) 25508bcdc58SRobert Watson { 256eca8a663SRobert Watson struct label *label; 25783985c26SRobert Watson int error; 25808bcdc58SRobert Watson 259eca8a663SRobert Watson label = mac_labelzone_alloc(flag); 260eca8a663SRobert Watson if (label == NULL) 261eca8a663SRobert Watson return (NULL); 26283985c26SRobert Watson 26383985c26SRobert Watson MAC_CHECK(init_socket_label, label, flag); 26483985c26SRobert Watson if (error) { 26583985c26SRobert Watson MAC_PERFORM(destroy_socket_label, label); 266eca8a663SRobert Watson mac_labelzone_free(label); 267eca8a663SRobert Watson return (NULL); 268eca8a663SRobert Watson } 2698d8d5ea8SRobert Watson MAC_DEBUG_COUNTER_INC(&nmacsockets); 270eca8a663SRobert Watson return (label); 27183985c26SRobert Watson } 27283985c26SRobert Watson 273eca8a663SRobert Watson static struct label * 274eca8a663SRobert Watson mac_socket_peer_label_alloc(int flag) 27583985c26SRobert Watson { 276eca8a663SRobert Watson struct label *label; 27783985c26SRobert Watson int error; 27883985c26SRobert Watson 279eca8a663SRobert Watson label = mac_labelzone_alloc(flag); 280eca8a663SRobert Watson if (label == NULL) 281eca8a663SRobert Watson return (NULL); 28283985c26SRobert Watson 28383985c26SRobert Watson MAC_CHECK(init_socket_peer_label, label, flag); 28483985c26SRobert Watson if (error) { 285bea2b56bSRobert Watson MAC_PERFORM(destroy_socket_peer_label, label); 286eca8a663SRobert Watson mac_labelzone_free(label); 287eca8a663SRobert Watson return (NULL); 28883985c26SRobert Watson } 289eca8a663SRobert Watson MAC_DEBUG_COUNTER_INC(&nmacsockets); 290eca8a663SRobert Watson return (label); 29183985c26SRobert Watson } 29283985c26SRobert Watson 29383985c26SRobert Watson int 294eca8a663SRobert Watson mac_init_socket(struct socket *so, int flag) 29583985c26SRobert Watson { 29683985c26SRobert Watson 297eca8a663SRobert Watson so->so_label = mac_socket_label_alloc(flag); 298eca8a663SRobert Watson if (so->so_label == NULL) 299eca8a663SRobert Watson return (ENOMEM); 300eca8a663SRobert Watson so->so_peerlabel = mac_socket_peer_label_alloc(flag); 301eca8a663SRobert Watson if (so->so_peerlabel == NULL) { 302eca8a663SRobert Watson mac_socket_label_free(so->so_label); 303eca8a663SRobert Watson so->so_label = NULL; 304eca8a663SRobert Watson return (ENOMEM); 305eca8a663SRobert Watson } 306eca8a663SRobert Watson return (0); 307eca8a663SRobert Watson } 30883985c26SRobert Watson 309eca8a663SRobert Watson static void 310eca8a663SRobert Watson mac_bpfdesc_label_free(struct label *label) 311eca8a663SRobert Watson { 31283985c26SRobert Watson 313eca8a663SRobert Watson MAC_PERFORM(destroy_bpfdesc_label, label); 314eca8a663SRobert Watson mac_labelzone_free(label); 315eca8a663SRobert Watson MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs); 31687807196SRobert Watson } 31787807196SRobert Watson 318763bbd2fSRobert Watson void 31908bcdc58SRobert Watson mac_destroy_bpfdesc(struct bpf_d *bpf_d) 32008bcdc58SRobert Watson { 32108bcdc58SRobert Watson 322eca8a663SRobert Watson mac_bpfdesc_label_free(bpf_d->bd_label); 323eca8a663SRobert Watson bpf_d->bd_label = NULL; 32408bcdc58SRobert Watson } 32508bcdc58SRobert Watson 326f7b951a8SRobert Watson static void 327eca8a663SRobert Watson mac_ifnet_label_free(struct label *label) 328f7b951a8SRobert Watson { 329f7b951a8SRobert Watson 330f7b951a8SRobert Watson MAC_PERFORM(destroy_ifnet_label, label); 331eca8a663SRobert Watson mac_labelzone_free(label); 3328d8d5ea8SRobert Watson MAC_DEBUG_COUNTER_DEC(&nmacifnets); 333f7b951a8SRobert Watson } 334f7b951a8SRobert Watson 33587807196SRobert Watson void 33687807196SRobert Watson mac_destroy_ifnet(struct ifnet *ifp) 33787807196SRobert Watson { 33887807196SRobert Watson 339eca8a663SRobert Watson mac_ifnet_label_free(ifp->if_label); 340eca8a663SRobert Watson ifp->if_label = NULL; 341eca8a663SRobert Watson } 342eca8a663SRobert Watson 343eca8a663SRobert Watson static void 344a557af22SRobert Watson mac_inpcb_label_free(struct label *label) 345a557af22SRobert Watson { 346a557af22SRobert Watson 347a557af22SRobert Watson MAC_PERFORM(destroy_inpcb_label, label); 348a557af22SRobert Watson mac_labelzone_free(label); 349a557af22SRobert Watson MAC_DEBUG_COUNTER_DEC(&nmacinpcbs); 350a557af22SRobert Watson } 351a557af22SRobert Watson 352a557af22SRobert Watson void 353a557af22SRobert Watson mac_destroy_inpcb(struct inpcb *inp) 354a557af22SRobert Watson { 355a557af22SRobert Watson 356a557af22SRobert Watson mac_inpcb_label_free(inp->inp_label); 357a557af22SRobert Watson inp->inp_label = NULL; 358a557af22SRobert Watson } 359a557af22SRobert Watson 360a557af22SRobert Watson static void 361eca8a663SRobert Watson mac_ipq_label_free(struct label *label) 362eca8a663SRobert Watson { 363eca8a663SRobert Watson 364eca8a663SRobert Watson MAC_PERFORM(destroy_ipq_label, label); 365eca8a663SRobert Watson mac_labelzone_free(label); 366eca8a663SRobert Watson MAC_DEBUG_COUNTER_DEC(&nmacipqs); 36787807196SRobert Watson } 36887807196SRobert Watson 36987807196SRobert Watson void 37087807196SRobert Watson mac_destroy_ipq(struct ipq *ipq) 37187807196SRobert Watson { 37287807196SRobert Watson 373eca8a663SRobert Watson mac_ipq_label_free(ipq->ipq_label); 374eca8a663SRobert Watson ipq->ipq_label = NULL; 37587807196SRobert Watson } 37687807196SRobert Watson 37787807196SRobert Watson void 378225bff6fSRobert Watson mac_destroy_mbuf_tag(struct m_tag *tag) 37987807196SRobert Watson { 380225bff6fSRobert Watson struct label *label; 38187807196SRobert Watson 382225bff6fSRobert Watson label = (struct label *)(tag+1); 383225bff6fSRobert Watson 384225bff6fSRobert Watson MAC_PERFORM(destroy_mbuf_label, label); 385225bff6fSRobert Watson mac_destroy_label(label); 3868d8d5ea8SRobert Watson MAC_DEBUG_COUNTER_DEC(&nmacmbufs); 38708bcdc58SRobert Watson } 38808bcdc58SRobert Watson 389b0323ea3SRobert Watson void 390eca8a663SRobert Watson mac_socket_label_free(struct label *label) 39183985c26SRobert Watson { 39283985c26SRobert Watson 39383985c26SRobert Watson MAC_PERFORM(destroy_socket_label, label); 394eca8a663SRobert Watson mac_labelzone_free(label); 3958d8d5ea8SRobert Watson MAC_DEBUG_COUNTER_DEC(&nmacsockets); 39683985c26SRobert Watson } 39783985c26SRobert Watson 39883985c26SRobert Watson static void 399eca8a663SRobert Watson mac_socket_peer_label_free(struct label *label) 40083985c26SRobert Watson { 40183985c26SRobert Watson 40283985c26SRobert Watson MAC_PERFORM(destroy_socket_peer_label, label); 403eca8a663SRobert Watson mac_labelzone_free(label); 404eca8a663SRobert Watson MAC_DEBUG_COUNTER_DEC(&nmacsockets); 40583985c26SRobert Watson } 40683985c26SRobert Watson 40787807196SRobert Watson void 40887807196SRobert Watson mac_destroy_socket(struct socket *socket) 40987807196SRobert Watson { 41087807196SRobert Watson 411eca8a663SRobert Watson mac_socket_label_free(socket->so_label); 412eca8a663SRobert Watson socket->so_label = NULL; 413eca8a663SRobert Watson mac_socket_peer_label_free(socket->so_peerlabel); 414eca8a663SRobert Watson socket->so_peerlabel = NULL; 41508bcdc58SRobert Watson } 41608bcdc58SRobert Watson 417763bbd2fSRobert Watson void 418225bff6fSRobert Watson mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest) 419225bff6fSRobert Watson { 420225bff6fSRobert Watson struct label *src_label, *dest_label; 421225bff6fSRobert Watson 422225bff6fSRobert Watson src_label = (struct label *)(src+1); 423225bff6fSRobert Watson dest_label = (struct label *)(dest+1); 424225bff6fSRobert Watson 425225bff6fSRobert Watson /* 426225bff6fSRobert Watson * mac_init_mbuf_tag() is called on the target tag in 427225bff6fSRobert Watson * m_tag_copy(), so we don't need to call it here. 428225bff6fSRobert Watson */ 429225bff6fSRobert Watson MAC_PERFORM(copy_mbuf_label, src_label, dest_label); 430225bff6fSRobert Watson } 431225bff6fSRobert Watson 432b0323ea3SRobert Watson void 433b0323ea3SRobert Watson mac_copy_socket_label(struct label *src, struct label *dest) 434b0323ea3SRobert Watson { 435b0323ea3SRobert Watson 436b0323ea3SRobert Watson MAC_PERFORM(copy_socket_label, src, dest); 437b0323ea3SRobert Watson } 438b0323ea3SRobert Watson 43969bbb5b1SRobert Watson static int 440f7b951a8SRobert Watson mac_externalize_ifnet_label(struct label *label, char *elements, 44183b7b0edSRobert Watson char *outbuf, size_t outbuflen) 44269bbb5b1SRobert Watson { 44369bbb5b1SRobert Watson int error; 44469bbb5b1SRobert Watson 445da77b2faSRobert Watson MAC_EXTERNALIZE(ifnet, label, elements, outbuf, outbuflen); 446f7b951a8SRobert Watson 447f7b951a8SRobert Watson return (error); 448f7b951a8SRobert Watson } 449f7b951a8SRobert Watson 450b0323ea3SRobert Watson int 451f7b951a8SRobert Watson mac_externalize_socket_label(struct label *label, char *elements, 45283b7b0edSRobert Watson char *outbuf, size_t outbuflen) 453f7b951a8SRobert Watson { 454f7b951a8SRobert Watson int error; 455f7b951a8SRobert Watson 456da77b2faSRobert Watson MAC_EXTERNALIZE(socket, label, elements, outbuf, outbuflen); 457f7b951a8SRobert Watson 458f7b951a8SRobert Watson return (error); 459f7b951a8SRobert Watson } 460f7b951a8SRobert Watson 461f7b951a8SRobert Watson static int 462f7b951a8SRobert Watson mac_externalize_socket_peer_label(struct label *label, char *elements, 46383b7b0edSRobert Watson char *outbuf, size_t outbuflen) 464f7b951a8SRobert Watson { 465f7b951a8SRobert Watson int error; 466f7b951a8SRobert Watson 467da77b2faSRobert Watson MAC_EXTERNALIZE(socket_peer, label, elements, outbuf, outbuflen); 468f7b951a8SRobert Watson 469f7b951a8SRobert Watson return (error); 470f7b951a8SRobert Watson } 471f7b951a8SRobert Watson 472f7b951a8SRobert Watson static int 473f7b951a8SRobert Watson mac_internalize_ifnet_label(struct label *label, char *string) 474f7b951a8SRobert Watson { 475f7b951a8SRobert Watson int error; 476f7b951a8SRobert Watson 477da77b2faSRobert Watson MAC_INTERNALIZE(ifnet, label, string); 478f7b951a8SRobert Watson 479f7b951a8SRobert Watson return (error); 480f7b951a8SRobert Watson } 481f7b951a8SRobert Watson 482b0323ea3SRobert Watson int 483f7b951a8SRobert Watson mac_internalize_socket_label(struct label *label, char *string) 484f7b951a8SRobert Watson { 485f7b951a8SRobert Watson int error; 486f7b951a8SRobert Watson 487da77b2faSRobert Watson MAC_INTERNALIZE(socket, label, string); 488f7b951a8SRobert Watson 489f7b951a8SRobert Watson return (error); 490f7b951a8SRobert Watson } 491f7b951a8SRobert Watson 49295fab37eSRobert Watson void 49395fab37eSRobert Watson mac_create_ifnet(struct ifnet *ifnet) 49495fab37eSRobert Watson { 49595fab37eSRobert Watson 496eca8a663SRobert Watson MAC_PERFORM(create_ifnet, ifnet, ifnet->if_label); 49795fab37eSRobert Watson } 49895fab37eSRobert Watson 49995fab37eSRobert Watson void 500a557af22SRobert Watson mac_create_inpcb_from_socket(struct socket *so, struct inpcb *inp) 501a557af22SRobert Watson { 502a557af22SRobert Watson 503a557af22SRobert Watson MAC_PERFORM(create_inpcb_from_socket, so, so->so_label, inp, 504a557af22SRobert Watson inp->inp_label); 505a557af22SRobert Watson } 506a557af22SRobert Watson 507a557af22SRobert Watson void 50895fab37eSRobert Watson mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d) 50995fab37eSRobert Watson { 51095fab37eSRobert Watson 511eca8a663SRobert Watson MAC_PERFORM(create_bpfdesc, cred, bpf_d, bpf_d->bd_label); 51295fab37eSRobert Watson } 51395fab37eSRobert Watson 51495fab37eSRobert Watson void 51595fab37eSRobert Watson mac_create_socket(struct ucred *cred, struct socket *socket) 51695fab37eSRobert Watson { 51795fab37eSRobert Watson 518eca8a663SRobert Watson MAC_PERFORM(create_socket, cred, socket, socket->so_label); 51995fab37eSRobert Watson } 52095fab37eSRobert Watson 52195fab37eSRobert Watson void 52295fab37eSRobert Watson mac_create_socket_from_socket(struct socket *oldsocket, 52395fab37eSRobert Watson struct socket *newsocket) 52495fab37eSRobert Watson { 52595fab37eSRobert Watson 526eca8a663SRobert Watson MAC_PERFORM(create_socket_from_socket, oldsocket, oldsocket->so_label, 527eca8a663SRobert Watson newsocket, newsocket->so_label); 52895fab37eSRobert Watson } 52995fab37eSRobert Watson 53095fab37eSRobert Watson static void 53195fab37eSRobert Watson mac_relabel_socket(struct ucred *cred, struct socket *socket, 53295fab37eSRobert Watson struct label *newlabel) 53395fab37eSRobert Watson { 53495fab37eSRobert Watson 535eca8a663SRobert Watson MAC_PERFORM(relabel_socket, cred, socket, socket->so_label, newlabel); 53695fab37eSRobert Watson } 53795fab37eSRobert Watson 53895fab37eSRobert Watson void 53995fab37eSRobert Watson mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket) 54095fab37eSRobert Watson { 54110eeb10cSRobert Watson struct label *label; 54295fab37eSRobert Watson 54310eeb10cSRobert Watson label = mbuf_to_label(mbuf); 54410eeb10cSRobert Watson 54510eeb10cSRobert Watson MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket, 546eca8a663SRobert Watson socket->so_peerlabel); 54795fab37eSRobert Watson } 54895fab37eSRobert Watson 54995fab37eSRobert Watson void 55095fab37eSRobert Watson mac_set_socket_peer_from_socket(struct socket *oldsocket, 55195fab37eSRobert Watson struct socket *newsocket) 55295fab37eSRobert Watson { 55395fab37eSRobert Watson 55495fab37eSRobert Watson MAC_PERFORM(set_socket_peer_from_socket, oldsocket, 555eca8a663SRobert Watson oldsocket->so_label, newsocket, newsocket->so_peerlabel); 55695fab37eSRobert Watson } 55795fab37eSRobert Watson 55895fab37eSRobert Watson void 55995fab37eSRobert Watson mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram) 56095fab37eSRobert Watson { 56110eeb10cSRobert Watson struct label *label; 56210eeb10cSRobert Watson 56310eeb10cSRobert Watson label = mbuf_to_label(datagram); 56495fab37eSRobert Watson 565eca8a663SRobert Watson MAC_PERFORM(create_datagram_from_ipq, ipq, ipq->ipq_label, 56610eeb10cSRobert Watson datagram, label); 56795fab37eSRobert Watson } 56895fab37eSRobert Watson 56995fab37eSRobert Watson void 57095fab37eSRobert Watson mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment) 57195fab37eSRobert Watson { 57210eeb10cSRobert Watson struct label *datagramlabel, *fragmentlabel; 57395fab37eSRobert Watson 57410eeb10cSRobert Watson datagramlabel = mbuf_to_label(datagram); 57510eeb10cSRobert Watson fragmentlabel = mbuf_to_label(fragment); 57610eeb10cSRobert Watson 57710eeb10cSRobert Watson MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment, 57810eeb10cSRobert Watson fragmentlabel); 57995fab37eSRobert Watson } 58095fab37eSRobert Watson 58195fab37eSRobert Watson void 58295fab37eSRobert Watson mac_create_ipq(struct mbuf *fragment, struct ipq *ipq) 58395fab37eSRobert Watson { 58410eeb10cSRobert Watson struct label *label; 58595fab37eSRobert Watson 58610eeb10cSRobert Watson label = mbuf_to_label(fragment); 58710eeb10cSRobert Watson 588eca8a663SRobert Watson MAC_PERFORM(create_ipq, fragment, label, ipq, ipq->ipq_label); 58995fab37eSRobert Watson } 59095fab37eSRobert Watson 59195fab37eSRobert Watson void 59295fab37eSRobert Watson mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf) 59395fab37eSRobert Watson { 59410eeb10cSRobert Watson struct label *oldmbuflabel, *newmbuflabel; 59595fab37eSRobert Watson 59610eeb10cSRobert Watson oldmbuflabel = mbuf_to_label(oldmbuf); 59710eeb10cSRobert Watson newmbuflabel = mbuf_to_label(newmbuf); 59810eeb10cSRobert Watson 59910eeb10cSRobert Watson MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf, 60010eeb10cSRobert Watson newmbuflabel); 60195fab37eSRobert Watson } 60295fab37eSRobert Watson 60395fab37eSRobert Watson void 60495fab37eSRobert Watson mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf) 60595fab37eSRobert Watson { 60610eeb10cSRobert Watson struct label *label; 60710eeb10cSRobert Watson 60810eeb10cSRobert Watson label = mbuf_to_label(mbuf); 60995fab37eSRobert Watson 610eca8a663SRobert Watson MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, bpf_d->bd_label, mbuf, 61110eeb10cSRobert Watson label); 61295fab37eSRobert Watson } 61395fab37eSRobert Watson 61495fab37eSRobert Watson void 61595fab37eSRobert Watson mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf) 61695fab37eSRobert Watson { 61710eeb10cSRobert Watson struct label *label; 61810eeb10cSRobert Watson 61910eeb10cSRobert Watson label = mbuf_to_label(mbuf); 62095fab37eSRobert Watson 621eca8a663SRobert Watson MAC_PERFORM(create_mbuf_linklayer, ifnet, ifnet->if_label, mbuf, 62210eeb10cSRobert Watson label); 62395fab37eSRobert Watson } 62495fab37eSRobert Watson 62595fab37eSRobert Watson void 62695fab37eSRobert Watson mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf) 62795fab37eSRobert Watson { 62810eeb10cSRobert Watson struct label *label; 62910eeb10cSRobert Watson 63010eeb10cSRobert Watson label = mbuf_to_label(mbuf); 63195fab37eSRobert Watson 632eca8a663SRobert Watson MAC_PERFORM(create_mbuf_from_ifnet, ifnet, ifnet->if_label, mbuf, 63310eeb10cSRobert Watson label); 63495fab37eSRobert Watson } 63595fab37eSRobert Watson 63695fab37eSRobert Watson void 63795fab37eSRobert Watson mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet, 63895fab37eSRobert Watson struct mbuf *newmbuf) 63995fab37eSRobert Watson { 64010eeb10cSRobert Watson struct label *oldmbuflabel, *newmbuflabel; 64195fab37eSRobert Watson 64210eeb10cSRobert Watson oldmbuflabel = mbuf_to_label(oldmbuf); 64310eeb10cSRobert Watson newmbuflabel = mbuf_to_label(newmbuf); 64410eeb10cSRobert Watson 64510eeb10cSRobert Watson MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel, 646eca8a663SRobert Watson ifnet, ifnet->if_label, newmbuf, newmbuflabel); 64795fab37eSRobert Watson } 64895fab37eSRobert Watson 64995fab37eSRobert Watson void 65095fab37eSRobert Watson mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf) 65195fab37eSRobert Watson { 65210eeb10cSRobert Watson struct label *oldmbuflabel, *newmbuflabel; 65395fab37eSRobert Watson 65410eeb10cSRobert Watson oldmbuflabel = mbuf_to_label(oldmbuf); 65510eeb10cSRobert Watson newmbuflabel = mbuf_to_label(newmbuf); 65610eeb10cSRobert Watson 65710eeb10cSRobert Watson MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf, 65810eeb10cSRobert Watson newmbuflabel); 65995fab37eSRobert Watson } 66095fab37eSRobert Watson 66195fab37eSRobert Watson int 66295fab37eSRobert Watson mac_fragment_match(struct mbuf *fragment, struct ipq *ipq) 66395fab37eSRobert Watson { 66410eeb10cSRobert Watson struct label *label; 66595fab37eSRobert Watson int result; 66695fab37eSRobert Watson 66710eeb10cSRobert Watson label = mbuf_to_label(fragment); 66810eeb10cSRobert Watson 66995fab37eSRobert Watson result = 1; 67010eeb10cSRobert Watson MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq, 671eca8a663SRobert Watson ipq->ipq_label); 67295fab37eSRobert Watson 67395fab37eSRobert Watson return (result); 67495fab37eSRobert Watson } 67595fab37eSRobert Watson 67695fab37eSRobert Watson void 677eb8c7f99SRobert Watson mac_reflect_mbuf_icmp(struct mbuf *m) 678eb8c7f99SRobert Watson { 679eb8c7f99SRobert Watson struct label *label; 680eb8c7f99SRobert Watson 681eb8c7f99SRobert Watson label = mbuf_to_label(m); 682eb8c7f99SRobert Watson 683eb8c7f99SRobert Watson MAC_PERFORM(reflect_mbuf_icmp, m, label); 684eb8c7f99SRobert Watson } 685eb8c7f99SRobert Watson void 686eb8c7f99SRobert Watson mac_reflect_mbuf_tcp(struct mbuf *m) 687eb8c7f99SRobert Watson { 688eb8c7f99SRobert Watson struct label *label; 689eb8c7f99SRobert Watson 690eb8c7f99SRobert Watson label = mbuf_to_label(m); 691eb8c7f99SRobert Watson 692eb8c7f99SRobert Watson MAC_PERFORM(reflect_mbuf_tcp, m, label); 693eb8c7f99SRobert Watson } 694eb8c7f99SRobert Watson 695eb8c7f99SRobert Watson void 69695fab37eSRobert Watson mac_update_ipq(struct mbuf *fragment, struct ipq *ipq) 69795fab37eSRobert Watson { 69810eeb10cSRobert Watson struct label *label; 69995fab37eSRobert Watson 70010eeb10cSRobert Watson label = mbuf_to_label(fragment); 70110eeb10cSRobert Watson 702eca8a663SRobert Watson MAC_PERFORM(update_ipq, fragment, label, ipq, ipq->ipq_label); 70395fab37eSRobert Watson } 70495fab37eSRobert Watson 70595fab37eSRobert Watson void 70695fab37eSRobert Watson mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf) 70795fab37eSRobert Watson { 70810eeb10cSRobert Watson struct label *label; 70910eeb10cSRobert Watson 71010eeb10cSRobert Watson label = mbuf_to_label(mbuf); 71195fab37eSRobert Watson 712eca8a663SRobert Watson MAC_PERFORM(create_mbuf_from_socket, socket, socket->so_label, mbuf, 71310eeb10cSRobert Watson label); 71495fab37eSRobert Watson } 71595fab37eSRobert Watson 71695fab37eSRobert Watson int 71795fab37eSRobert Watson mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet) 71895fab37eSRobert Watson { 71995fab37eSRobert Watson int error; 72095fab37eSRobert Watson 72195fab37eSRobert Watson if (!mac_enforce_network) 72295fab37eSRobert Watson return (0); 72395fab37eSRobert Watson 724eca8a663SRobert Watson MAC_CHECK(check_bpfdesc_receive, bpf_d, bpf_d->bd_label, ifnet, 725eca8a663SRobert Watson ifnet->if_label); 72695fab37eSRobert Watson 72795fab37eSRobert Watson return (error); 72895fab37eSRobert Watson } 72995fab37eSRobert Watson 73095fab37eSRobert Watson int 73195fab37eSRobert Watson mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf) 73295fab37eSRobert Watson { 73310eeb10cSRobert Watson struct label *label; 73495fab37eSRobert Watson int error; 73595fab37eSRobert Watson 736225bff6fSRobert Watson M_ASSERTPKTHDR(mbuf); 737225bff6fSRobert Watson 73895fab37eSRobert Watson if (!mac_enforce_network) 73995fab37eSRobert Watson return (0); 74095fab37eSRobert Watson 74110eeb10cSRobert Watson label = mbuf_to_label(mbuf); 74295fab37eSRobert Watson 743eca8a663SRobert Watson MAC_CHECK(check_ifnet_transmit, ifnet, ifnet->if_label, mbuf, 74410eeb10cSRobert Watson label); 74595fab37eSRobert Watson 74695fab37eSRobert Watson return (error); 74795fab37eSRobert Watson } 74895fab37eSRobert Watson 74995fab37eSRobert Watson int 750a557af22SRobert Watson mac_check_inpcb_deliver(struct inpcb *inp, struct mbuf *m) 751a557af22SRobert Watson { 752a557af22SRobert Watson struct label *label; 753a557af22SRobert Watson int error; 754a557af22SRobert Watson 755a557af22SRobert Watson M_ASSERTPKTHDR(m); 756a557af22SRobert Watson 757a557af22SRobert Watson if (!mac_enforce_socket) 758a557af22SRobert Watson return (0); 759a557af22SRobert Watson 760a557af22SRobert Watson label = mbuf_to_label(m); 761a557af22SRobert Watson 762a557af22SRobert Watson MAC_CHECK(check_inpcb_deliver, inp, inp->inp_label, m, label); 763a557af22SRobert Watson 764a557af22SRobert Watson return (error); 765a557af22SRobert Watson } 766a557af22SRobert Watson 767a557af22SRobert Watson int 76895fab37eSRobert Watson mac_check_socket_bind(struct ucred *ucred, struct socket *socket, 76995fab37eSRobert Watson struct sockaddr *sockaddr) 77095fab37eSRobert Watson { 77195fab37eSRobert Watson int error; 77295fab37eSRobert Watson 77395fab37eSRobert Watson if (!mac_enforce_socket) 77495fab37eSRobert Watson return (0); 77595fab37eSRobert Watson 776eca8a663SRobert Watson MAC_CHECK(check_socket_bind, ucred, socket, socket->so_label, 77795fab37eSRobert Watson sockaddr); 77895fab37eSRobert Watson 77995fab37eSRobert Watson return (error); 78095fab37eSRobert Watson } 78195fab37eSRobert Watson 78295fab37eSRobert Watson int 78395fab37eSRobert Watson mac_check_socket_connect(struct ucred *cred, struct socket *socket, 78495fab37eSRobert Watson struct sockaddr *sockaddr) 78595fab37eSRobert Watson { 78695fab37eSRobert Watson int error; 78795fab37eSRobert Watson 78895fab37eSRobert Watson if (!mac_enforce_socket) 78995fab37eSRobert Watson return (0); 79095fab37eSRobert Watson 791eca8a663SRobert Watson MAC_CHECK(check_socket_connect, cred, socket, socket->so_label, 79295fab37eSRobert Watson sockaddr); 79395fab37eSRobert Watson 79495fab37eSRobert Watson return (error); 79595fab37eSRobert Watson } 79695fab37eSRobert Watson 79795fab37eSRobert Watson int 798d61198e4SRobert Watson mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf) 799d61198e4SRobert Watson { 80010eeb10cSRobert Watson struct label *label; 801d61198e4SRobert Watson int error; 802d61198e4SRobert Watson 803d61198e4SRobert Watson if (!mac_enforce_socket) 804d61198e4SRobert Watson return (0); 805d61198e4SRobert Watson 80610eeb10cSRobert Watson label = mbuf_to_label(mbuf); 80710eeb10cSRobert Watson 808eca8a663SRobert Watson MAC_CHECK(check_socket_deliver, socket, socket->so_label, mbuf, 80910eeb10cSRobert Watson label); 810d61198e4SRobert Watson 811d61198e4SRobert Watson return (error); 812d61198e4SRobert Watson } 813d61198e4SRobert Watson 814d61198e4SRobert Watson int 81595fab37eSRobert Watson mac_check_socket_listen(struct ucred *cred, struct socket *socket) 81695fab37eSRobert Watson { 81795fab37eSRobert Watson int error; 81895fab37eSRobert Watson 81995fab37eSRobert Watson if (!mac_enforce_socket) 82095fab37eSRobert Watson return (0); 82195fab37eSRobert Watson 822eca8a663SRobert Watson MAC_CHECK(check_socket_listen, cred, socket, socket->so_label); 82395fab37eSRobert Watson return (error); 82495fab37eSRobert Watson } 82595fab37eSRobert Watson 826b371c939SRobert Watson int 827b371c939SRobert Watson mac_check_socket_receive(struct ucred *cred, struct socket *so) 828b371c939SRobert Watson { 829b371c939SRobert Watson int error; 830b371c939SRobert Watson 831b371c939SRobert Watson if (!mac_enforce_socket) 832b371c939SRobert Watson return (0); 833b371c939SRobert Watson 834eca8a663SRobert Watson MAC_CHECK(check_socket_receive, cred, so, so->so_label); 835b371c939SRobert Watson 836b371c939SRobert Watson return (error); 837b371c939SRobert Watson } 838b371c939SRobert Watson 83995fab37eSRobert Watson static int 84095fab37eSRobert Watson mac_check_socket_relabel(struct ucred *cred, struct socket *socket, 84195fab37eSRobert Watson struct label *newlabel) 84295fab37eSRobert Watson { 84395fab37eSRobert Watson int error; 84495fab37eSRobert Watson 845eca8a663SRobert Watson MAC_CHECK(check_socket_relabel, cred, socket, socket->so_label, 84695fab37eSRobert Watson newlabel); 84795fab37eSRobert Watson 84895fab37eSRobert Watson return (error); 84995fab37eSRobert Watson } 85095fab37eSRobert Watson 85195fab37eSRobert Watson int 852b371c939SRobert Watson mac_check_socket_send(struct ucred *cred, struct socket *so) 853b371c939SRobert Watson { 854b371c939SRobert Watson int error; 855b371c939SRobert Watson 856b371c939SRobert Watson if (!mac_enforce_socket) 857b371c939SRobert Watson return (0); 858b371c939SRobert Watson 859eca8a663SRobert Watson MAC_CHECK(check_socket_send, cred, so, so->so_label); 860b371c939SRobert Watson 861b371c939SRobert Watson return (error); 862b371c939SRobert Watson } 863b371c939SRobert Watson 864b371c939SRobert Watson int 86595fab37eSRobert Watson mac_check_socket_visible(struct ucred *cred, struct socket *socket) 86695fab37eSRobert Watson { 86795fab37eSRobert Watson int error; 86895fab37eSRobert Watson 86995fab37eSRobert Watson if (!mac_enforce_socket) 87095fab37eSRobert Watson return (0); 87195fab37eSRobert Watson 872eca8a663SRobert Watson MAC_CHECK(check_socket_visible, cred, socket, socket->so_label); 87395fab37eSRobert Watson 87495fab37eSRobert Watson return (error); 87595fab37eSRobert Watson } 87695fab37eSRobert Watson 87795fab37eSRobert Watson int 87895fab37eSRobert Watson mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr, 87995fab37eSRobert Watson struct ifnet *ifnet) 88095fab37eSRobert Watson { 881f7b951a8SRobert Watson char *elements, *buffer; 882f7b951a8SRobert Watson struct mac mac; 88395fab37eSRobert Watson int error; 88495fab37eSRobert Watson 885f7b951a8SRobert Watson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 88695fab37eSRobert Watson if (error) 88795fab37eSRobert Watson return (error); 88895fab37eSRobert Watson 889f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 890f7b951a8SRobert Watson if (error) 891f7b951a8SRobert Watson return (error); 892f7b951a8SRobert Watson 893a163d034SWarner Losh elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 894f7b951a8SRobert Watson error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL); 895f7b951a8SRobert Watson if (error) { 896f7b951a8SRobert Watson free(elements, M_MACTEMP); 897f7b951a8SRobert Watson return (error); 898f7b951a8SRobert Watson } 899f7b951a8SRobert Watson 900a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 901eca8a663SRobert Watson error = mac_externalize_ifnet_label(ifnet->if_label, elements, 90283b7b0edSRobert Watson buffer, mac.m_buflen); 903f7b951a8SRobert Watson if (error == 0) 904f7b951a8SRobert Watson error = copyout(buffer, mac.m_string, strlen(buffer)+1); 905f7b951a8SRobert Watson 906f7b951a8SRobert Watson free(buffer, M_MACTEMP); 907f7b951a8SRobert Watson free(elements, M_MACTEMP); 908f7b951a8SRobert Watson 909f7b951a8SRobert Watson return (error); 91095fab37eSRobert Watson } 91195fab37eSRobert Watson 91295fab37eSRobert Watson int 91395fab37eSRobert Watson mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, 91495fab37eSRobert Watson struct ifnet *ifnet) 91595fab37eSRobert Watson { 916eca8a663SRobert Watson struct label *intlabel; 917f7b951a8SRobert Watson struct mac mac; 918f7b951a8SRobert Watson char *buffer; 91995fab37eSRobert Watson int error; 92095fab37eSRobert Watson 921f7b951a8SRobert Watson error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac)); 92295fab37eSRobert Watson if (error) 92395fab37eSRobert Watson return (error); 92495fab37eSRobert Watson 925f7b951a8SRobert Watson error = mac_check_structmac_consistent(&mac); 92695fab37eSRobert Watson if (error) 92795fab37eSRobert Watson return (error); 92895fab37eSRobert Watson 929a163d034SWarner Losh buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK); 930f7b951a8SRobert Watson error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL); 931f7b951a8SRobert Watson if (error) { 932f7b951a8SRobert Watson free(buffer, M_MACTEMP); 933f7b951a8SRobert Watson return (error); 934f7b951a8SRobert Watson } 935f7b951a8SRobert Watson 936eca8a663SRobert Watson intlabel = mac_ifnet_label_alloc(); 937eca8a663SRobert Watson error = mac_internalize_ifnet_label(intlabel, buffer); 938f7b951a8SRobert Watson free(buffer, M_MACTEMP); 939f7b951a8SRobert Watson if (error) { 940eca8a663SRobert Watson mac_ifnet_label_free(intlabel); 941f7b951a8SRobert Watson return (error); 942f7b951a8SRobert Watson } 943f7b951a8SRobert Watson 94495fab37eSRobert Watson /* 94595fab37eSRobert Watson * XXX: Note that this is a redundant privilege check, since 94695fab37eSRobert Watson * policies impose this check themselves if required by the 94795fab37eSRobert Watson * policy. Eventually, this should go away. 94895fab37eSRobert Watson */ 94995fab37eSRobert Watson error = suser_cred(cred, 0); 950f7b951a8SRobert Watson if (error) { 951eca8a663SRobert Watson mac_ifnet_label_free(intlabel); 952f7b951a8SRobert Watson return (error); 953f7b951a8SRobert Watson } 95495fab37eSRobert Watson 955eca8a663SRobert Watson MAC_CHECK(check_ifnet_relabel, cred, ifnet, ifnet->if_label, 956eca8a663SRobert Watson intlabel); 957f7b951a8SRobert Watson if (error) { 958eca8a663SRobert Watson mac_ifnet_label_free(intlabel); 959f7b951a8SRobert Watson return (error); 960f7b951a8SRobert Watson } 96195fab37eSRobert Watson 962eca8a663SRobert Watson MAC_PERFORM(relabel_ifnet, cred, ifnet, ifnet->if_label, intlabel); 96395fab37eSRobert Watson 964eca8a663SRobert Watson mac_ifnet_label_free(intlabel); 965f7b951a8SRobert Watson return (0); 96695fab37eSRobert Watson } 96795fab37eSRobert Watson 968a557af22SRobert Watson void 969a557af22SRobert Watson mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp) 970a557af22SRobert Watson { 971a557af22SRobert Watson 972a557af22SRobert Watson /* XXX: assert socket lock. */ 973a557af22SRobert Watson INP_LOCK_ASSERT(inp); 974a557af22SRobert Watson MAC_PERFORM(inpcb_sosetlabel, so, so->so_label, inp, inp->inp_label); 975a557af22SRobert Watson } 976a557af22SRobert Watson 97795fab37eSRobert Watson int 978c9ea2dcfSRobert Watson mac_socket_label_set(struct ucred *cred, struct socket *so, 979c9ea2dcfSRobert Watson struct label *label) 980c9ea2dcfSRobert Watson { 981c9ea2dcfSRobert Watson int error; 982c9ea2dcfSRobert Watson 983c9ea2dcfSRobert Watson error = mac_check_socket_relabel(cred, so, label); 984c9ea2dcfSRobert Watson if (error) 985c9ea2dcfSRobert Watson return (error); 986c9ea2dcfSRobert Watson 987c9ea2dcfSRobert Watson mac_relabel_socket(cred, so, label); 988a557af22SRobert Watson 989a557af22SRobert Watson /* 990a557af22SRobert Watson * If the protocol has expressed interest in socket layer changes, 991a557af22SRobert Watson * such as if it needs to propagate changes to a cached pcb 992a557af22SRobert Watson * label from the socket, notify it of the label change while 993a557af22SRobert Watson * holding the socket lock. 994a557af22SRobert Watson */ 995a557af22SRobert Watson if (so->so_proto->pr_usrreqs->pru_sosetlabel != NULL) 996a557af22SRobert Watson (so->so_proto->pr_usrreqs->pru_sosetlabel)(so); 997a557af22SRobert Watson 998c9ea2dcfSRobert Watson return (0); 999c9ea2dcfSRobert Watson } 1000c9ea2dcfSRobert Watson 1001c9ea2dcfSRobert Watson int 10029e71dd0fSRobert Watson mac_setsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac) 100395fab37eSRobert Watson { 1004eca8a663SRobert Watson struct label *intlabel; 1005f7b951a8SRobert Watson char *buffer; 100695fab37eSRobert Watson int error; 100795fab37eSRobert Watson 1008f7b951a8SRobert Watson error = mac_check_structmac_consistent(mac); 100995fab37eSRobert Watson if (error) 101095fab37eSRobert Watson return (error); 101195fab37eSRobert Watson 1012a163d034SWarner Losh buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 1013f7b951a8SRobert Watson error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL); 1014f7b951a8SRobert Watson if (error) { 1015f7b951a8SRobert Watson free(buffer, M_MACTEMP); 1016f7b951a8SRobert Watson return (error); 1017f7b951a8SRobert Watson } 1018f7b951a8SRobert Watson 1019eca8a663SRobert Watson intlabel = mac_socket_label_alloc(M_WAITOK); 1020eca8a663SRobert Watson error = mac_internalize_socket_label(intlabel, buffer); 1021f7b951a8SRobert Watson free(buffer, M_MACTEMP); 1022c9ea2dcfSRobert Watson if (error) 1023c9ea2dcfSRobert Watson goto out; 1024c9ea2dcfSRobert Watson 1025c9ea2dcfSRobert Watson /* XXX: Socket lock here. */ 1026c9ea2dcfSRobert Watson error = mac_socket_label_set(cred, so, intlabel); 1027c9ea2dcfSRobert Watson /* XXX: Socket unlock here. */ 1028c9ea2dcfSRobert Watson out: 1029eca8a663SRobert Watson mac_socket_label_free(intlabel); 1030f7b951a8SRobert Watson return (error); 1031f7b951a8SRobert Watson } 1032f7b951a8SRobert Watson 103395fab37eSRobert Watson int 10349e71dd0fSRobert Watson mac_getsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac) 103595fab37eSRobert Watson { 1036f7b951a8SRobert Watson char *buffer, *elements; 1037f7b951a8SRobert Watson int error; 103895fab37eSRobert Watson 1039f7b951a8SRobert Watson error = mac_check_structmac_consistent(mac); 1040f7b951a8SRobert Watson if (error) 1041f7b951a8SRobert Watson return (error); 1042f7b951a8SRobert Watson 1043a163d034SWarner Losh elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 1044f7b951a8SRobert Watson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 1045f7b951a8SRobert Watson if (error) { 1046f7b951a8SRobert Watson free(elements, M_MACTEMP); 1047f7b951a8SRobert Watson return (error); 1048f7b951a8SRobert Watson } 1049f7b951a8SRobert Watson 1050a163d034SWarner Losh buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 1051eca8a663SRobert Watson error = mac_externalize_socket_label(so->so_label, elements, 105283b7b0edSRobert Watson buffer, mac->m_buflen); 1053f7b951a8SRobert Watson if (error == 0) 1054f7b951a8SRobert Watson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 1055f7b951a8SRobert Watson 1056f7b951a8SRobert Watson free(buffer, M_MACTEMP); 1057f7b951a8SRobert Watson free(elements, M_MACTEMP); 1058f7b951a8SRobert Watson 1059f7b951a8SRobert Watson return (error); 106095fab37eSRobert Watson } 106195fab37eSRobert Watson 106295fab37eSRobert Watson int 10639e71dd0fSRobert Watson mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so, 1064f7b951a8SRobert Watson struct mac *mac) 106595fab37eSRobert Watson { 1066f7b951a8SRobert Watson char *elements, *buffer; 1067f7b951a8SRobert Watson int error; 106895fab37eSRobert Watson 1069f7b951a8SRobert Watson error = mac_check_structmac_consistent(mac); 1070f7b951a8SRobert Watson if (error) 1071f7b951a8SRobert Watson return (error); 1072f7b951a8SRobert Watson 1073a163d034SWarner Losh elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK); 1074f7b951a8SRobert Watson error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL); 1075f7b951a8SRobert Watson if (error) { 1076f7b951a8SRobert Watson free(elements, M_MACTEMP); 1077f7b951a8SRobert Watson return (error); 1078f7b951a8SRobert Watson } 1079f7b951a8SRobert Watson 1080a163d034SWarner Losh buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); 1081eca8a663SRobert Watson error = mac_externalize_socket_peer_label(so->so_peerlabel, 108283b7b0edSRobert Watson elements, buffer, mac->m_buflen); 1083f7b951a8SRobert Watson if (error == 0) 1084f7b951a8SRobert Watson error = copyout(buffer, mac->m_string, strlen(buffer)+1); 1085f7b951a8SRobert Watson 1086f7b951a8SRobert Watson free(buffer, M_MACTEMP); 1087f7b951a8SRobert Watson free(elements, M_MACTEMP); 1088f7b951a8SRobert Watson 1089f7b951a8SRobert Watson return (error); 109095fab37eSRobert Watson } 1091