xref: /freebsd/sys/security/mac/mac_net.c (revision 28e65e3d2b6bd5713e8c1711d5e36bdf83d8af85)
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>
5395fab37eSRobert Watson #include <sys/socket.h>
5495fab37eSRobert Watson #include <sys/socketvar.h>
5595fab37eSRobert Watson #include <sys/sysctl.h>
5695fab37eSRobert Watson 
5795fab37eSRobert Watson #include <sys/mac_policy.h>
5895fab37eSRobert Watson 
5995fab37eSRobert Watson #include <net/bpfdesc.h>
6095fab37eSRobert Watson #include <net/if.h>
6195fab37eSRobert Watson #include <net/if_var.h>
6295fab37eSRobert Watson 
6395fab37eSRobert Watson #include <netinet/in.h>
6495fab37eSRobert Watson #include <netinet/ip_var.h>
6595fab37eSRobert Watson 
6628e65e3dSRobert Watson #include <security/mac/mac_internal.h>
67a3df768bSRobert Watson 
6895fab37eSRobert Watson static int	mac_enforce_network = 1;
6995fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
7095fab37eSRobert Watson     &mac_enforce_network, 0, "Enforce MAC policy on network packets");
7195fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
7295fab37eSRobert Watson 
7395fab37eSRobert Watson static int	mac_enforce_socket = 1;
7495fab37eSRobert Watson SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
7595fab37eSRobert Watson     &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
7695fab37eSRobert Watson TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
7795fab37eSRobert Watson 
78f050add5SRobert Watson #ifdef MAC_DEBUG
7928e65e3dSRobert Watson static unsigned int nmacmbufs, nmacifnets, nmacbpfdescs, nmacsockets,
8028e65e3dSRobert Watson     nmacipqs;
818d8d5ea8SRobert Watson 
82b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD,
8395fab37eSRobert Watson     &nmacmbufs, 0, "number of mbufs in use");
84b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
8595fab37eSRobert Watson     &nmacifnets, 0, "number of ifnets in use");
86b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
8795fab37eSRobert Watson     &nmacipqs, 0, "number of ipqs in use");
88b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD,
8995fab37eSRobert Watson     &nmacbpfdescs, 0, "number of bpfdescs in use");
90b2f0927aSRobert Watson SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
9195fab37eSRobert Watson     &nmacsockets, 0, "number of sockets in use");
92f050add5SRobert Watson #endif
9395fab37eSRobert Watson 
9483985c26SRobert Watson static void	mac_destroy_socket_label(struct label *label);
9583985c26SRobert Watson 
9610eeb10cSRobert Watson static struct label *
9710eeb10cSRobert Watson mbuf_to_label(struct mbuf *mbuf)
9810eeb10cSRobert Watson {
99225bff6fSRobert Watson 	struct m_tag *tag;
10010eeb10cSRobert Watson 	struct label *label;
10110eeb10cSRobert Watson 
102225bff6fSRobert Watson 	tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
103225bff6fSRobert Watson 	label = (struct label *)(tag+1);
10410eeb10cSRobert Watson 
10510eeb10cSRobert Watson 	return (label);
10610eeb10cSRobert Watson }
10710eeb10cSRobert Watson 
10808bcdc58SRobert Watson void
10987807196SRobert Watson mac_init_bpfdesc(struct bpf_d *bpf_d)
11008bcdc58SRobert Watson {
11108bcdc58SRobert Watson 
11287807196SRobert Watson 	mac_init_label(&bpf_d->bd_label);
11387807196SRobert Watson 	MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label);
1148d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacbpfdescs);
11508bcdc58SRobert Watson }
11608bcdc58SRobert Watson 
117f7b951a8SRobert Watson static void
118f7b951a8SRobert Watson mac_init_ifnet_label(struct label *label)
119f7b951a8SRobert Watson {
120f7b951a8SRobert Watson 
121f7b951a8SRobert Watson 	mac_init_label(label);
122f7b951a8SRobert Watson 	MAC_PERFORM(init_ifnet_label, label);
1238d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_INC(&nmacifnets);
124f7b951a8SRobert Watson }
125f7b951a8SRobert Watson 
12608bcdc58SRobert Watson void
12708bcdc58SRobert Watson mac_init_ifnet(struct ifnet *ifp)
12808bcdc58SRobert Watson {
12908bcdc58SRobert Watson 
130f7b951a8SRobert Watson 	mac_init_ifnet_label(&ifp->if_label);
13108bcdc58SRobert Watson }
13208bcdc58SRobert Watson 
1335e7ce478SRobert Watson int
1345e7ce478SRobert Watson mac_init_ipq(struct ipq *ipq, int flag)
13508bcdc58SRobert Watson {
1365e7ce478SRobert Watson 	int error;
13708bcdc58SRobert Watson 
13808bcdc58SRobert Watson 	mac_init_label(&ipq->ipq_label);
1395e7ce478SRobert Watson 
1405e7ce478SRobert Watson 	MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag);
1415e7ce478SRobert Watson 	if (error) {
1425e7ce478SRobert Watson 		MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
1435e7ce478SRobert Watson 		mac_destroy_label(&ipq->ipq_label);
1448d8d5ea8SRobert Watson 	} else {
1458d8d5ea8SRobert Watson 		MAC_DEBUG_COUNTER_INC(&nmacipqs);
1465e7ce478SRobert Watson 	}
1475e7ce478SRobert Watson 	return (error);
14808bcdc58SRobert Watson }
14908bcdc58SRobert Watson 
15087807196SRobert Watson int
151225bff6fSRobert Watson mac_init_mbuf_tag(struct m_tag *tag, int flag)
15208bcdc58SRobert Watson {
153225bff6fSRobert Watson 	struct label *label;
1546d1a6a9aSRobert Watson 	int error;
15556c15412SRobert Watson 
156225bff6fSRobert Watson 	label = (struct label *) (tag + 1);
157225bff6fSRobert Watson 	mac_init_label(label);
15808bcdc58SRobert Watson 
1596d1a6a9aSRobert Watson 	MAC_CHECK(init_mbuf_label, label, flag);
16056c15412SRobert Watson 	if (error) {
161225bff6fSRobert Watson 		MAC_PERFORM(destroy_mbuf_label, label);
162225bff6fSRobert Watson 		mac_destroy_label(label);
1638d8d5ea8SRobert Watson 	} else {
1648d8d5ea8SRobert Watson 		MAC_DEBUG_COUNTER_INC(&nmacmbufs);
16556c15412SRobert Watson 	}
16656c15412SRobert Watson 	return (error);
16708bcdc58SRobert Watson }
16808bcdc58SRobert Watson 
169225bff6fSRobert Watson int
170225bff6fSRobert Watson mac_init_mbuf(struct mbuf *m, int flag)
171225bff6fSRobert Watson {
172225bff6fSRobert Watson 	struct m_tag *tag;
173225bff6fSRobert Watson 	int error;
174225bff6fSRobert Watson 
175225bff6fSRobert Watson 	M_ASSERTPKTHDR(m);
176225bff6fSRobert Watson 
177225bff6fSRobert Watson #ifndef MAC_ALWAYS_LABEL_MBUF
178225bff6fSRobert Watson 	/*
17919c3e120SRobert Watson 	 * If conditionally allocating mbuf labels, don't allocate unless
18019c3e120SRobert Watson 	 * they are required.
181225bff6fSRobert Watson 	 */
18219c3e120SRobert Watson 	if (!mac_labelmbufs)
18319c3e120SRobert Watson 		return (0);
184225bff6fSRobert Watson #endif
185225bff6fSRobert Watson 	tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
186225bff6fSRobert Watson 	    flag);
187225bff6fSRobert Watson 	if (tag == NULL)
188225bff6fSRobert Watson 		return (ENOMEM);
189225bff6fSRobert Watson 	error = mac_init_mbuf_tag(tag, flag);
190225bff6fSRobert Watson 	if (error) {
191225bff6fSRobert Watson 		m_tag_free(tag);
192225bff6fSRobert Watson 		return (error);
193225bff6fSRobert Watson 	}
194225bff6fSRobert Watson 	m_tag_prepend(m, tag);
195225bff6fSRobert Watson 	return (0);
196225bff6fSRobert Watson }
197225bff6fSRobert Watson 
19883985c26SRobert Watson static int
19983985c26SRobert Watson mac_init_socket_label(struct label *label, int flag)
20008bcdc58SRobert Watson {
20183985c26SRobert Watson 	int error;
20208bcdc58SRobert Watson 
20383985c26SRobert Watson 	mac_init_label(label);
20483985c26SRobert Watson 
20583985c26SRobert Watson 	MAC_CHECK(init_socket_label, label, flag);
20683985c26SRobert Watson 	if (error) {
20783985c26SRobert Watson 		MAC_PERFORM(destroy_socket_label, label);
20883985c26SRobert Watson 		mac_destroy_label(label);
2098d8d5ea8SRobert Watson 	} else {
2108d8d5ea8SRobert Watson 		MAC_DEBUG_COUNTER_INC(&nmacsockets);
21183985c26SRobert Watson 	}
21283985c26SRobert Watson 
21383985c26SRobert Watson 	return (error);
21483985c26SRobert Watson }
21583985c26SRobert Watson 
21683985c26SRobert Watson static int
21783985c26SRobert Watson mac_init_socket_peer_label(struct label *label, int flag)
21883985c26SRobert Watson {
21983985c26SRobert Watson 	int error;
22083985c26SRobert Watson 
22183985c26SRobert Watson 	mac_init_label(label);
22283985c26SRobert Watson 
22383985c26SRobert Watson 	MAC_CHECK(init_socket_peer_label, label, flag);
22483985c26SRobert Watson 	if (error) {
22583985c26SRobert Watson 		MAC_PERFORM(destroy_socket_label, label);
22683985c26SRobert Watson 		mac_destroy_label(label);
22783985c26SRobert Watson 	}
22883985c26SRobert Watson 
22983985c26SRobert Watson 	return (error);
23083985c26SRobert Watson }
23183985c26SRobert Watson 
23283985c26SRobert Watson int
23383985c26SRobert Watson mac_init_socket(struct socket *socket, int flag)
23483985c26SRobert Watson {
23583985c26SRobert Watson 	int error;
23683985c26SRobert Watson 
23783985c26SRobert Watson 	error = mac_init_socket_label(&socket->so_label, flag);
23883985c26SRobert Watson 	if (error)
23983985c26SRobert Watson 		return (error);
24083985c26SRobert Watson 
24183985c26SRobert Watson 	error = mac_init_socket_peer_label(&socket->so_peerlabel, flag);
24283985c26SRobert Watson 	if (error)
24383985c26SRobert Watson 		mac_destroy_socket_label(&socket->so_label);
24483985c26SRobert Watson 
24583985c26SRobert Watson 	return (error);
24687807196SRobert Watson }
24787807196SRobert Watson 
248763bbd2fSRobert Watson void
24908bcdc58SRobert Watson mac_destroy_bpfdesc(struct bpf_d *bpf_d)
25008bcdc58SRobert Watson {
25108bcdc58SRobert Watson 
25208bcdc58SRobert Watson 	MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label);
25308bcdc58SRobert Watson 	mac_destroy_label(&bpf_d->bd_label);
2548d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs);
25508bcdc58SRobert Watson }
25608bcdc58SRobert Watson 
257f7b951a8SRobert Watson static void
258f7b951a8SRobert Watson mac_destroy_ifnet_label(struct label *label)
259f7b951a8SRobert Watson {
260f7b951a8SRobert Watson 
261f7b951a8SRobert Watson 	MAC_PERFORM(destroy_ifnet_label, label);
262f7b951a8SRobert Watson 	mac_destroy_label(label);
2638d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacifnets);
264f7b951a8SRobert Watson }
265f7b951a8SRobert Watson 
26687807196SRobert Watson void
26787807196SRobert Watson mac_destroy_ifnet(struct ifnet *ifp)
26887807196SRobert Watson {
26987807196SRobert Watson 
270f7b951a8SRobert Watson 	mac_destroy_ifnet_label(&ifp->if_label);
27187807196SRobert Watson }
27287807196SRobert Watson 
27387807196SRobert Watson void
27487807196SRobert Watson mac_destroy_ipq(struct ipq *ipq)
27587807196SRobert Watson {
27687807196SRobert Watson 
27787807196SRobert Watson 	MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
27887807196SRobert Watson 	mac_destroy_label(&ipq->ipq_label);
2798d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacipqs);
28087807196SRobert Watson }
28187807196SRobert Watson 
28287807196SRobert Watson void
283225bff6fSRobert Watson mac_destroy_mbuf_tag(struct m_tag *tag)
28487807196SRobert Watson {
285225bff6fSRobert Watson 	struct label *label;
28687807196SRobert Watson 
287225bff6fSRobert Watson 	label = (struct label *)(tag+1);
288225bff6fSRobert Watson 
289225bff6fSRobert Watson 	MAC_PERFORM(destroy_mbuf_label, label);
290225bff6fSRobert Watson 	mac_destroy_label(label);
2918d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacmbufs);
29208bcdc58SRobert Watson }
29308bcdc58SRobert Watson 
29483985c26SRobert Watson static void
29583985c26SRobert Watson mac_destroy_socket_label(struct label *label)
29683985c26SRobert Watson {
29783985c26SRobert Watson 
29883985c26SRobert Watson 	MAC_PERFORM(destroy_socket_label, label);
29983985c26SRobert Watson 	mac_destroy_label(label);
3008d8d5ea8SRobert Watson 	MAC_DEBUG_COUNTER_DEC(&nmacsockets);
30183985c26SRobert Watson }
30283985c26SRobert Watson 
30383985c26SRobert Watson static void
30483985c26SRobert Watson mac_destroy_socket_peer_label(struct label *label)
30583985c26SRobert Watson {
30683985c26SRobert Watson 
30783985c26SRobert Watson 	MAC_PERFORM(destroy_socket_peer_label, label);
30883985c26SRobert Watson 	mac_destroy_label(label);
30983985c26SRobert Watson }
31083985c26SRobert Watson 
31187807196SRobert Watson void
31287807196SRobert Watson mac_destroy_socket(struct socket *socket)
31387807196SRobert Watson {
31487807196SRobert Watson 
31583985c26SRobert Watson 	mac_destroy_socket_label(&socket->so_label);
31683985c26SRobert Watson 	mac_destroy_socket_peer_label(&socket->so_peerlabel);
31708bcdc58SRobert Watson }
31808bcdc58SRobert Watson 
319763bbd2fSRobert Watson void
320225bff6fSRobert Watson mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
321225bff6fSRobert Watson {
322225bff6fSRobert Watson 	struct label *src_label, *dest_label;
323225bff6fSRobert Watson 
324225bff6fSRobert Watson 	src_label = (struct label *)(src+1);
325225bff6fSRobert Watson 	dest_label = (struct label *)(dest+1);
326225bff6fSRobert Watson 
327225bff6fSRobert Watson 	/*
328225bff6fSRobert Watson 	 * mac_init_mbuf_tag() is called on the target tag in
329225bff6fSRobert Watson 	 * m_tag_copy(), so we don't need to call it here.
330225bff6fSRobert Watson 	 */
331225bff6fSRobert Watson 	MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
332225bff6fSRobert Watson }
333225bff6fSRobert Watson 
33469bbb5b1SRobert Watson static int
335f7b951a8SRobert Watson mac_externalize_ifnet_label(struct label *label, char *elements,
336f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
33769bbb5b1SRobert Watson {
33869bbb5b1SRobert Watson 	int error;
33969bbb5b1SRobert Watson 
340f7b951a8SRobert Watson 	MAC_EXTERNALIZE(ifnet_label, label, elements, outbuf, outbuflen);
341f7b951a8SRobert Watson 
342f7b951a8SRobert Watson 	return (error);
343f7b951a8SRobert Watson }
344f7b951a8SRobert Watson 
345f7b951a8SRobert Watson static int
346f7b951a8SRobert Watson mac_externalize_socket_label(struct label *label, char *elements,
347f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
348f7b951a8SRobert Watson {
349f7b951a8SRobert Watson 	int error;
350f7b951a8SRobert Watson 
351f7b951a8SRobert Watson 	MAC_EXTERNALIZE(socket_label, label, elements, outbuf, outbuflen);
352f7b951a8SRobert Watson 
353f7b951a8SRobert Watson 	return (error);
354f7b951a8SRobert Watson }
355f7b951a8SRobert Watson 
356f7b951a8SRobert Watson static int
357f7b951a8SRobert Watson mac_externalize_socket_peer_label(struct label *label, char *elements,
358f7b951a8SRobert Watson     char *outbuf, size_t outbuflen, int flags)
359f7b951a8SRobert Watson {
360f7b951a8SRobert Watson 	int error;
361f7b951a8SRobert Watson 
362f7b951a8SRobert Watson 	MAC_EXTERNALIZE(socket_peer_label, label, elements, outbuf, outbuflen);
363f7b951a8SRobert Watson 
364f7b951a8SRobert Watson 	return (error);
365f7b951a8SRobert Watson }
366f7b951a8SRobert Watson 
367f7b951a8SRobert Watson static int
368f7b951a8SRobert Watson mac_internalize_ifnet_label(struct label *label, char *string)
369f7b951a8SRobert Watson {
370f7b951a8SRobert Watson 	int error;
371f7b951a8SRobert Watson 
372f7b951a8SRobert Watson 	MAC_INTERNALIZE(ifnet_label, label, string);
373f7b951a8SRobert Watson 
374f7b951a8SRobert Watson 	return (error);
375f7b951a8SRobert Watson }
376f7b951a8SRobert Watson 
377f7b951a8SRobert Watson static int
378f7b951a8SRobert Watson mac_internalize_socket_label(struct label *label, char *string)
379f7b951a8SRobert Watson {
380f7b951a8SRobert Watson 	int error;
381f7b951a8SRobert Watson 
382f7b951a8SRobert Watson 	MAC_INTERNALIZE(socket_label, label, string);
383f7b951a8SRobert Watson 
384f7b951a8SRobert Watson 	return (error);
385f7b951a8SRobert Watson }
386f7b951a8SRobert Watson 
38795fab37eSRobert Watson void
38895fab37eSRobert Watson mac_create_ifnet(struct ifnet *ifnet)
38995fab37eSRobert Watson {
39095fab37eSRobert Watson 
39195fab37eSRobert Watson 	MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
39295fab37eSRobert Watson }
39395fab37eSRobert Watson 
39495fab37eSRobert Watson void
39595fab37eSRobert Watson mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
39695fab37eSRobert Watson {
39795fab37eSRobert Watson 
39895fab37eSRobert Watson 	MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
39995fab37eSRobert Watson }
40095fab37eSRobert Watson 
40195fab37eSRobert Watson void
40295fab37eSRobert Watson mac_create_socket(struct ucred *cred, struct socket *socket)
40395fab37eSRobert Watson {
40495fab37eSRobert Watson 
40595fab37eSRobert Watson 	MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
40695fab37eSRobert Watson }
40795fab37eSRobert Watson 
40895fab37eSRobert Watson void
40995fab37eSRobert Watson mac_create_socket_from_socket(struct socket *oldsocket,
41095fab37eSRobert Watson     struct socket *newsocket)
41195fab37eSRobert Watson {
41295fab37eSRobert Watson 
41395fab37eSRobert Watson 	MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
41495fab37eSRobert Watson 	    newsocket, &newsocket->so_label);
41595fab37eSRobert Watson }
41695fab37eSRobert Watson 
41795fab37eSRobert Watson static void
41895fab37eSRobert Watson mac_relabel_socket(struct ucred *cred, struct socket *socket,
41995fab37eSRobert Watson     struct label *newlabel)
42095fab37eSRobert Watson {
42195fab37eSRobert Watson 
42295fab37eSRobert Watson 	MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
42395fab37eSRobert Watson }
42495fab37eSRobert Watson 
42595fab37eSRobert Watson void
42695fab37eSRobert Watson mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
42795fab37eSRobert Watson {
42810eeb10cSRobert Watson 	struct label *label;
42995fab37eSRobert Watson 
43010eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
43110eeb10cSRobert Watson 
43210eeb10cSRobert Watson 	MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket,
43310eeb10cSRobert Watson 	    &socket->so_peerlabel);
43495fab37eSRobert Watson }
43595fab37eSRobert Watson 
43695fab37eSRobert Watson void
43795fab37eSRobert Watson mac_set_socket_peer_from_socket(struct socket *oldsocket,
43895fab37eSRobert Watson     struct socket *newsocket)
43995fab37eSRobert Watson {
44095fab37eSRobert Watson 
44195fab37eSRobert Watson 	MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
44295fab37eSRobert Watson 	    &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
44395fab37eSRobert Watson }
44495fab37eSRobert Watson 
44595fab37eSRobert Watson void
44695fab37eSRobert Watson mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
44795fab37eSRobert Watson {
44810eeb10cSRobert Watson 	struct label *label;
44910eeb10cSRobert Watson 
45010eeb10cSRobert Watson 	label = mbuf_to_label(datagram);
45195fab37eSRobert Watson 
45295fab37eSRobert Watson 	MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
45310eeb10cSRobert Watson 	    datagram, label);
45495fab37eSRobert Watson }
45595fab37eSRobert Watson 
45695fab37eSRobert Watson void
45795fab37eSRobert Watson mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
45895fab37eSRobert Watson {
45910eeb10cSRobert Watson 	struct label *datagramlabel, *fragmentlabel;
46095fab37eSRobert Watson 
46110eeb10cSRobert Watson 	datagramlabel = mbuf_to_label(datagram);
46210eeb10cSRobert Watson 	fragmentlabel = mbuf_to_label(fragment);
46310eeb10cSRobert Watson 
46410eeb10cSRobert Watson 	MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment,
46510eeb10cSRobert Watson 	    fragmentlabel);
46695fab37eSRobert Watson }
46795fab37eSRobert Watson 
46895fab37eSRobert Watson void
46995fab37eSRobert Watson mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
47095fab37eSRobert Watson {
47110eeb10cSRobert Watson 	struct label *label;
47295fab37eSRobert Watson 
47310eeb10cSRobert Watson 	label = mbuf_to_label(fragment);
47410eeb10cSRobert Watson 
47510eeb10cSRobert Watson 	MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label);
47695fab37eSRobert Watson }
47795fab37eSRobert Watson 
47895fab37eSRobert Watson void
47995fab37eSRobert Watson mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
48095fab37eSRobert Watson {
48110eeb10cSRobert Watson 	struct label *oldmbuflabel, *newmbuflabel;
48295fab37eSRobert Watson 
48310eeb10cSRobert Watson 	oldmbuflabel = mbuf_to_label(oldmbuf);
48410eeb10cSRobert Watson 	newmbuflabel = mbuf_to_label(newmbuf);
48510eeb10cSRobert Watson 
48610eeb10cSRobert Watson 	MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf,
48710eeb10cSRobert Watson 	    newmbuflabel);
48895fab37eSRobert Watson }
48995fab37eSRobert Watson 
49095fab37eSRobert Watson void
49195fab37eSRobert Watson mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
49295fab37eSRobert Watson {
49310eeb10cSRobert Watson 	struct label *label;
49410eeb10cSRobert Watson 
49510eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
49695fab37eSRobert Watson 
49795fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
49810eeb10cSRobert Watson 	    label);
49995fab37eSRobert Watson }
50095fab37eSRobert Watson 
50195fab37eSRobert Watson void
50295fab37eSRobert Watson mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
50395fab37eSRobert Watson {
50410eeb10cSRobert Watson 	struct label *label;
50510eeb10cSRobert Watson 
50610eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
50795fab37eSRobert Watson 
50895fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
50910eeb10cSRobert Watson 	    label);
51095fab37eSRobert Watson }
51195fab37eSRobert Watson 
51295fab37eSRobert Watson void
51395fab37eSRobert Watson mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
51495fab37eSRobert Watson {
51510eeb10cSRobert Watson 	struct label *label;
51610eeb10cSRobert Watson 
51710eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
51895fab37eSRobert Watson 
51995fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
52010eeb10cSRobert Watson 	    label);
52195fab37eSRobert Watson }
52295fab37eSRobert Watson 
52395fab37eSRobert Watson void
52495fab37eSRobert Watson mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
52595fab37eSRobert Watson     struct mbuf *newmbuf)
52695fab37eSRobert Watson {
52710eeb10cSRobert Watson 	struct label *oldmbuflabel, *newmbuflabel;
52895fab37eSRobert Watson 
52910eeb10cSRobert Watson 	oldmbuflabel = mbuf_to_label(oldmbuf);
53010eeb10cSRobert Watson 	newmbuflabel = mbuf_to_label(newmbuf);
53110eeb10cSRobert Watson 
53210eeb10cSRobert Watson 	MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel,
53310eeb10cSRobert Watson 	    ifnet, &ifnet->if_label, newmbuf, newmbuflabel);
53495fab37eSRobert Watson }
53595fab37eSRobert Watson 
53695fab37eSRobert Watson void
53795fab37eSRobert Watson mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
53895fab37eSRobert Watson {
53910eeb10cSRobert Watson 	struct label *oldmbuflabel, *newmbuflabel;
54095fab37eSRobert Watson 
54110eeb10cSRobert Watson 	oldmbuflabel = mbuf_to_label(oldmbuf);
54210eeb10cSRobert Watson 	newmbuflabel = mbuf_to_label(newmbuf);
54310eeb10cSRobert Watson 
54410eeb10cSRobert Watson 	MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf,
54510eeb10cSRobert Watson 	    newmbuflabel);
54695fab37eSRobert Watson }
54795fab37eSRobert Watson 
54895fab37eSRobert Watson int
54995fab37eSRobert Watson mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
55095fab37eSRobert Watson {
55110eeb10cSRobert Watson 	struct label *label;
55295fab37eSRobert Watson 	int result;
55395fab37eSRobert Watson 
55410eeb10cSRobert Watson 	label = mbuf_to_label(fragment);
55510eeb10cSRobert Watson 
55695fab37eSRobert Watson 	result = 1;
55710eeb10cSRobert Watson 	MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq,
55810eeb10cSRobert Watson 	    &ipq->ipq_label);
55995fab37eSRobert Watson 
56095fab37eSRobert Watson 	return (result);
56195fab37eSRobert Watson }
56295fab37eSRobert Watson 
56395fab37eSRobert Watson void
564eb8c7f99SRobert Watson mac_reflect_mbuf_icmp(struct mbuf *m)
565eb8c7f99SRobert Watson {
566eb8c7f99SRobert Watson 	struct label *label;
567eb8c7f99SRobert Watson 
568eb8c7f99SRobert Watson 	label = mbuf_to_label(m);
569eb8c7f99SRobert Watson 
570eb8c7f99SRobert Watson 	MAC_PERFORM(reflect_mbuf_icmp, m, label);
571eb8c7f99SRobert Watson }
572eb8c7f99SRobert Watson void
573eb8c7f99SRobert Watson mac_reflect_mbuf_tcp(struct mbuf *m)
574eb8c7f99SRobert Watson {
575eb8c7f99SRobert Watson 	struct label *label;
576eb8c7f99SRobert Watson 
577eb8c7f99SRobert Watson 	label = mbuf_to_label(m);
578eb8c7f99SRobert Watson 
579eb8c7f99SRobert Watson 	MAC_PERFORM(reflect_mbuf_tcp, m, label);
580eb8c7f99SRobert Watson }
581eb8c7f99SRobert Watson 
582eb8c7f99SRobert Watson void
58395fab37eSRobert Watson mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
58495fab37eSRobert Watson {
58510eeb10cSRobert Watson 	struct label *label;
58695fab37eSRobert Watson 
58710eeb10cSRobert Watson 	label = mbuf_to_label(fragment);
58810eeb10cSRobert Watson 
58910eeb10cSRobert Watson 	MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label);
59095fab37eSRobert Watson }
59195fab37eSRobert Watson 
59295fab37eSRobert Watson void
59395fab37eSRobert Watson mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
59495fab37eSRobert Watson {
59510eeb10cSRobert Watson 	struct label *label;
59610eeb10cSRobert Watson 
59710eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
59895fab37eSRobert Watson 
59995fab37eSRobert Watson 	MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
60010eeb10cSRobert Watson 	    label);
60195fab37eSRobert Watson }
60295fab37eSRobert Watson 
60395fab37eSRobert Watson int
60495fab37eSRobert Watson mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
60595fab37eSRobert Watson {
60695fab37eSRobert Watson 	int error;
60795fab37eSRobert Watson 
60895fab37eSRobert Watson 	if (!mac_enforce_network)
60995fab37eSRobert Watson 		return (0);
61095fab37eSRobert Watson 
61195fab37eSRobert Watson 	MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
61295fab37eSRobert Watson 	    &ifnet->if_label);
61395fab37eSRobert Watson 
61495fab37eSRobert Watson 	return (error);
61595fab37eSRobert Watson }
61695fab37eSRobert Watson 
61795fab37eSRobert Watson int
61895fab37eSRobert Watson mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
61995fab37eSRobert Watson {
62010eeb10cSRobert Watson 	struct label *label;
62195fab37eSRobert Watson 	int error;
62295fab37eSRobert Watson 
623225bff6fSRobert Watson 	M_ASSERTPKTHDR(mbuf);
624225bff6fSRobert Watson 
62595fab37eSRobert Watson 	if (!mac_enforce_network)
62695fab37eSRobert Watson 		return (0);
62795fab37eSRobert Watson 
62810eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
62995fab37eSRobert Watson 
63095fab37eSRobert Watson 	MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
63110eeb10cSRobert Watson 	    label);
63295fab37eSRobert Watson 
63395fab37eSRobert Watson 	return (error);
63495fab37eSRobert Watson }
63595fab37eSRobert Watson 
63695fab37eSRobert Watson int
63795fab37eSRobert Watson mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
63895fab37eSRobert Watson     struct sockaddr *sockaddr)
63995fab37eSRobert Watson {
64095fab37eSRobert Watson 	int error;
64195fab37eSRobert Watson 
64295fab37eSRobert Watson 	if (!mac_enforce_socket)
64395fab37eSRobert Watson 		return (0);
64495fab37eSRobert Watson 
64595fab37eSRobert Watson 	MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
64695fab37eSRobert Watson 	    sockaddr);
64795fab37eSRobert Watson 
64895fab37eSRobert Watson 	return (error);
64995fab37eSRobert Watson }
65095fab37eSRobert Watson 
65195fab37eSRobert Watson int
65295fab37eSRobert Watson mac_check_socket_connect(struct ucred *cred, struct socket *socket,
65395fab37eSRobert Watson     struct sockaddr *sockaddr)
65495fab37eSRobert Watson {
65595fab37eSRobert Watson 	int error;
65695fab37eSRobert Watson 
65795fab37eSRobert Watson 	if (!mac_enforce_socket)
65895fab37eSRobert Watson 		return (0);
65995fab37eSRobert Watson 
66095fab37eSRobert Watson 	MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
66195fab37eSRobert Watson 	    sockaddr);
66295fab37eSRobert Watson 
66395fab37eSRobert Watson 	return (error);
66495fab37eSRobert Watson }
66595fab37eSRobert Watson 
66695fab37eSRobert Watson int
667d61198e4SRobert Watson mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
668d61198e4SRobert Watson {
66910eeb10cSRobert Watson 	struct label *label;
670d61198e4SRobert Watson 	int error;
671d61198e4SRobert Watson 
672d61198e4SRobert Watson 	if (!mac_enforce_socket)
673d61198e4SRobert Watson 		return (0);
674d61198e4SRobert Watson 
67510eeb10cSRobert Watson 	label = mbuf_to_label(mbuf);
67610eeb10cSRobert Watson 
677d61198e4SRobert Watson 	MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
67810eeb10cSRobert Watson 	    label);
679d61198e4SRobert Watson 
680d61198e4SRobert Watson 	return (error);
681d61198e4SRobert Watson }
682d61198e4SRobert Watson 
683d61198e4SRobert Watson int
68495fab37eSRobert Watson mac_check_socket_listen(struct ucred *cred, struct socket *socket)
68595fab37eSRobert Watson {
68695fab37eSRobert Watson 	int error;
68795fab37eSRobert Watson 
68895fab37eSRobert Watson 	if (!mac_enforce_socket)
68995fab37eSRobert Watson 		return (0);
69095fab37eSRobert Watson 
69195fab37eSRobert Watson 	MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
69295fab37eSRobert Watson 	return (error);
69395fab37eSRobert Watson }
69495fab37eSRobert Watson 
695b371c939SRobert Watson int
696b371c939SRobert Watson mac_check_socket_receive(struct ucred *cred, struct socket *so)
697b371c939SRobert Watson {
698b371c939SRobert Watson 	int error;
699b371c939SRobert Watson 
700b371c939SRobert Watson 	if (!mac_enforce_socket)
701b371c939SRobert Watson 		return (0);
702b371c939SRobert Watson 
703b371c939SRobert Watson 	MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
704b371c939SRobert Watson 
705b371c939SRobert Watson 	return (error);
706b371c939SRobert Watson }
707b371c939SRobert Watson 
70895fab37eSRobert Watson static int
70995fab37eSRobert Watson mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
71095fab37eSRobert Watson     struct label *newlabel)
71195fab37eSRobert Watson {
71295fab37eSRobert Watson 	int error;
71395fab37eSRobert Watson 
71495fab37eSRobert Watson 	MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
71595fab37eSRobert Watson 	    newlabel);
71695fab37eSRobert Watson 
71795fab37eSRobert Watson 	return (error);
71895fab37eSRobert Watson }
71995fab37eSRobert Watson 
72095fab37eSRobert Watson int
721b371c939SRobert Watson mac_check_socket_send(struct ucred *cred, struct socket *so)
722b371c939SRobert Watson {
723b371c939SRobert Watson 	int error;
724b371c939SRobert Watson 
725b371c939SRobert Watson 	if (!mac_enforce_socket)
726b371c939SRobert Watson 		return (0);
727b371c939SRobert Watson 
728b371c939SRobert Watson 	MAC_CHECK(check_socket_send, cred, so, &so->so_label);
729b371c939SRobert Watson 
730b371c939SRobert Watson 	return (error);
731b371c939SRobert Watson }
732b371c939SRobert Watson 
733b371c939SRobert Watson int
73495fab37eSRobert Watson mac_check_socket_visible(struct ucred *cred, struct socket *socket)
73595fab37eSRobert Watson {
73695fab37eSRobert Watson 	int error;
73795fab37eSRobert Watson 
73895fab37eSRobert Watson 	if (!mac_enforce_socket)
73995fab37eSRobert Watson 		return (0);
74095fab37eSRobert Watson 
74195fab37eSRobert Watson 	MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
74295fab37eSRobert Watson 
74395fab37eSRobert Watson 	return (error);
74495fab37eSRobert Watson }
74595fab37eSRobert Watson 
74695fab37eSRobert Watson int
74795fab37eSRobert Watson mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
74895fab37eSRobert Watson     struct ifnet *ifnet)
74995fab37eSRobert Watson {
750f7b951a8SRobert Watson 	char *elements, *buffer;
751f7b951a8SRobert Watson 	struct mac mac;
75295fab37eSRobert Watson 	int error;
75395fab37eSRobert Watson 
754f7b951a8SRobert Watson 	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
75595fab37eSRobert Watson 	if (error)
75695fab37eSRobert Watson 		return (error);
75795fab37eSRobert Watson 
758f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
759f7b951a8SRobert Watson 	if (error)
760f7b951a8SRobert Watson 		return (error);
761f7b951a8SRobert Watson 
762a163d034SWarner Losh 	elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
763f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
764f7b951a8SRobert Watson 	if (error) {
765f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
766f7b951a8SRobert Watson 		return (error);
767f7b951a8SRobert Watson 	}
768f7b951a8SRobert Watson 
769a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
770f7b951a8SRobert Watson 	error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
771a163d034SWarner Losh 	    buffer, mac.m_buflen, M_WAITOK);
772f7b951a8SRobert Watson 	if (error == 0)
773f7b951a8SRobert Watson 		error = copyout(buffer, mac.m_string, strlen(buffer)+1);
774f7b951a8SRobert Watson 
775f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
776f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
777f7b951a8SRobert Watson 
778f7b951a8SRobert Watson 	return (error);
77995fab37eSRobert Watson }
78095fab37eSRobert Watson 
78195fab37eSRobert Watson int
78295fab37eSRobert Watson mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
78395fab37eSRobert Watson     struct ifnet *ifnet)
78495fab37eSRobert Watson {
78595fab37eSRobert Watson 	struct label intlabel;
786f7b951a8SRobert Watson 	struct mac mac;
787f7b951a8SRobert Watson 	char *buffer;
78895fab37eSRobert Watson 	int error;
78995fab37eSRobert Watson 
790f7b951a8SRobert Watson 	error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
79195fab37eSRobert Watson 	if (error)
79295fab37eSRobert Watson 		return (error);
79395fab37eSRobert Watson 
794f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(&mac);
79595fab37eSRobert Watson 	if (error)
79695fab37eSRobert Watson 		return (error);
79795fab37eSRobert Watson 
798a163d034SWarner Losh 	buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
799f7b951a8SRobert Watson 	error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
800f7b951a8SRobert Watson 	if (error) {
801f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
802f7b951a8SRobert Watson 		return (error);
803f7b951a8SRobert Watson 	}
804f7b951a8SRobert Watson 
805f7b951a8SRobert Watson 	mac_init_ifnet_label(&intlabel);
806f7b951a8SRobert Watson 	error = mac_internalize_ifnet_label(&intlabel, buffer);
807f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
808f7b951a8SRobert Watson 	if (error) {
809f7b951a8SRobert Watson 		mac_destroy_ifnet_label(&intlabel);
810f7b951a8SRobert Watson 		return (error);
811f7b951a8SRobert Watson 	}
812f7b951a8SRobert Watson 
81395fab37eSRobert Watson 	/*
81495fab37eSRobert Watson 	 * XXX: Note that this is a redundant privilege check, since
81595fab37eSRobert Watson 	 * policies impose this check themselves if required by the
81695fab37eSRobert Watson 	 * policy.  Eventually, this should go away.
81795fab37eSRobert Watson 	 */
81895fab37eSRobert Watson 	error = suser_cred(cred, 0);
819f7b951a8SRobert Watson 	if (error) {
820f7b951a8SRobert Watson 		mac_destroy_ifnet_label(&intlabel);
821f7b951a8SRobert Watson 		return (error);
822f7b951a8SRobert Watson 	}
82395fab37eSRobert Watson 
82495fab37eSRobert Watson 	MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
82595fab37eSRobert Watson 	    &intlabel);
826f7b951a8SRobert Watson 	if (error) {
827f7b951a8SRobert Watson 		mac_destroy_ifnet_label(&intlabel);
828f7b951a8SRobert Watson 		return (error);
829f7b951a8SRobert Watson 	}
83095fab37eSRobert Watson 
83195fab37eSRobert Watson 	MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
83295fab37eSRobert Watson 
833f7b951a8SRobert Watson 	mac_destroy_ifnet_label(&intlabel);
834f7b951a8SRobert Watson 	return (0);
83595fab37eSRobert Watson }
83695fab37eSRobert Watson 
83795fab37eSRobert Watson int
83895fab37eSRobert Watson mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
839f7b951a8SRobert Watson     struct mac *mac)
84095fab37eSRobert Watson {
84195fab37eSRobert Watson 	struct label intlabel;
842f7b951a8SRobert Watson 	char *buffer;
84395fab37eSRobert Watson 	int error;
84495fab37eSRobert Watson 
845f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(mac);
84695fab37eSRobert Watson 	if (error)
84795fab37eSRobert Watson 		return (error);
84895fab37eSRobert Watson 
849a163d034SWarner Losh 	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
850f7b951a8SRobert Watson 	error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
851f7b951a8SRobert Watson 	if (error) {
852f7b951a8SRobert Watson 		free(buffer, M_MACTEMP);
853f7b951a8SRobert Watson 		return (error);
854f7b951a8SRobert Watson 	}
855f7b951a8SRobert Watson 
856a163d034SWarner Losh 	mac_init_socket_label(&intlabel, M_WAITOK);
857f7b951a8SRobert Watson 	error = mac_internalize_socket_label(&intlabel, buffer);
858f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
859f7b951a8SRobert Watson 	if (error) {
860f7b951a8SRobert Watson 		mac_destroy_socket_label(&intlabel);
861f7b951a8SRobert Watson 		return (error);
862f7b951a8SRobert Watson 	}
863f7b951a8SRobert Watson 
86495fab37eSRobert Watson 	mac_check_socket_relabel(cred, so, &intlabel);
86595fab37eSRobert Watson 	if (error) {
866f7b951a8SRobert Watson 		mac_destroy_socket_label(&intlabel);
86795fab37eSRobert Watson 		return (error);
86895fab37eSRobert Watson 	}
86995fab37eSRobert Watson 
87095fab37eSRobert Watson 	mac_relabel_socket(cred, so, &intlabel);
87195fab37eSRobert Watson 
872f7b951a8SRobert Watson 	mac_destroy_socket_label(&intlabel);
87395fab37eSRobert Watson 	return (0);
87495fab37eSRobert Watson }
87595fab37eSRobert Watson 
87695fab37eSRobert Watson int
87795fab37eSRobert Watson mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
878f7b951a8SRobert Watson     struct mac *mac)
87995fab37eSRobert Watson {
880f7b951a8SRobert Watson 	char *buffer, *elements;
881f7b951a8SRobert Watson 	int error;
88295fab37eSRobert Watson 
883f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(mac);
884f7b951a8SRobert Watson 	if (error)
885f7b951a8SRobert Watson 		return (error);
886f7b951a8SRobert Watson 
887a163d034SWarner Losh 	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
888f7b951a8SRobert Watson 	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
889f7b951a8SRobert Watson 	if (error) {
890f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
891f7b951a8SRobert Watson 		return (error);
892f7b951a8SRobert Watson 	}
893f7b951a8SRobert Watson 
894a163d034SWarner Losh 	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
895f7b951a8SRobert Watson 	error = mac_externalize_socket_label(&so->so_label, elements,
896a163d034SWarner Losh 	    buffer, mac->m_buflen, M_WAITOK);
897f7b951a8SRobert Watson 	if (error == 0)
898f7b951a8SRobert Watson 		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
899f7b951a8SRobert Watson 
900f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
901f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
902f7b951a8SRobert Watson 
903f7b951a8SRobert Watson 	return (error);
90495fab37eSRobert Watson }
90595fab37eSRobert Watson 
90695fab37eSRobert Watson int
90795fab37eSRobert Watson mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
908f7b951a8SRobert Watson     struct mac *mac)
90995fab37eSRobert Watson {
910f7b951a8SRobert Watson 	char *elements, *buffer;
911f7b951a8SRobert Watson 	int error;
91295fab37eSRobert Watson 
913f7b951a8SRobert Watson 	error = mac_check_structmac_consistent(mac);
914f7b951a8SRobert Watson 	if (error)
915f7b951a8SRobert Watson 		return (error);
916f7b951a8SRobert Watson 
917a163d034SWarner Losh 	elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
918f7b951a8SRobert Watson 	error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
919f7b951a8SRobert Watson 	if (error) {
920f7b951a8SRobert Watson 		free(elements, M_MACTEMP);
921f7b951a8SRobert Watson 		return (error);
922f7b951a8SRobert Watson 	}
923f7b951a8SRobert Watson 
924a163d034SWarner Losh 	buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
925f7b951a8SRobert Watson 	error = mac_externalize_socket_peer_label(&so->so_peerlabel,
926a163d034SWarner Losh 	    elements, buffer, mac->m_buflen, M_WAITOK);
927f7b951a8SRobert Watson 	if (error == 0)
928f7b951a8SRobert Watson 		error = copyout(buffer, mac->m_string, strlen(buffer)+1);
929f7b951a8SRobert Watson 
930f7b951a8SRobert Watson 	free(buffer, M_MACTEMP);
931f7b951a8SRobert Watson 	free(elements, M_MACTEMP);
932f7b951a8SRobert Watson 
933f7b951a8SRobert Watson 	return (error);
93495fab37eSRobert Watson }
935