xref: /freebsd/sys/security/mac/mac_inet.c (revision 3f2792166aeed4baf07d351bcb12a9d196c443eb)
1c66b4d8dSRobert Watson /*-
25c95417dSRobert Watson  * Copyright (c) 1999-2002, 2007, 2009, 2019 Robert N. M. Watson
3c66b4d8dSRobert Watson  * Copyright (c) 2001 Ilmar S. Habibulin
4c66b4d8dSRobert Watson  * Copyright (c) 2001-2004 Networks Associates Technology, Inc.
530d239bcSRobert Watson  * Copyright (c) 2006 SPARTA, Inc.
66356dba0SRobert Watson  * Copyright (c) 2008 Apple Inc.
7c66b4d8dSRobert Watson  * All rights reserved.
8c66b4d8dSRobert Watson  *
9c66b4d8dSRobert Watson  * This software was developed by Robert Watson and Ilmar Habibulin for the
10c66b4d8dSRobert Watson  * TrustedBSD Project.
11c66b4d8dSRobert Watson  *
12c66b4d8dSRobert Watson  * This software was developed for the FreeBSD Project in part by Network
13c66b4d8dSRobert Watson  * Associates Laboratories, the Security Research Division of Network
14c66b4d8dSRobert Watson  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
15c66b4d8dSRobert Watson  * as part of the DARPA CHATS research program.
16c66b4d8dSRobert Watson  *
1730d239bcSRobert Watson  * This software was enhanced by SPARTA ISSO under SPAWAR contract
1830d239bcSRobert Watson  * N66001-04-C-6019 ("SEFOS").
1930d239bcSRobert Watson  *
202087a58cSRobert Watson  * This software was developed at the University of Cambridge Computer
212087a58cSRobert Watson  * Laboratory with support from a grant from Google, Inc.
222087a58cSRobert Watson  *
23c66b4d8dSRobert Watson  * Redistribution and use in source and binary forms, with or without
24c66b4d8dSRobert Watson  * modification, are permitted provided that the following conditions
25c66b4d8dSRobert Watson  * are met:
26c66b4d8dSRobert Watson  * 1. Redistributions of source code must retain the above copyright
27c66b4d8dSRobert Watson  *    notice, this list of conditions and the following disclaimer.
28c66b4d8dSRobert Watson  * 2. Redistributions in binary form must reproduce the above copyright
29c66b4d8dSRobert Watson  *    notice, this list of conditions and the following disclaimer in the
30c66b4d8dSRobert Watson  *    documentation and/or other materials provided with the distribution.
31c66b4d8dSRobert Watson  *
32c66b4d8dSRobert Watson  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
33c66b4d8dSRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34c66b4d8dSRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35c66b4d8dSRobert Watson  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
36c66b4d8dSRobert Watson  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37c66b4d8dSRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38c66b4d8dSRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39c66b4d8dSRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
40c66b4d8dSRobert Watson  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
41c66b4d8dSRobert Watson  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42c66b4d8dSRobert Watson  * SUCH DAMAGE.
43c66b4d8dSRobert Watson  */
44c66b4d8dSRobert Watson 
45c66b4d8dSRobert Watson #include <sys/cdefs.h>
46c66b4d8dSRobert Watson #include "opt_mac.h"
47c66b4d8dSRobert Watson 
48c66b4d8dSRobert Watson #include <sys/param.h>
49c66b4d8dSRobert Watson #include <sys/kernel.h>
50c66b4d8dSRobert Watson #include <sys/lock.h>
51c66b4d8dSRobert Watson #include <sys/malloc.h>
52c66b4d8dSRobert Watson #include <sys/mutex.h>
53c66b4d8dSRobert Watson #include <sys/sbuf.h>
542087a58cSRobert Watson #include <sys/sdt.h>
55c66b4d8dSRobert Watson #include <sys/systm.h>
56c66b4d8dSRobert Watson #include <sys/mount.h>
57c66b4d8dSRobert Watson #include <sys/file.h>
58c66b4d8dSRobert Watson #include <sys/namei.h>
59c66b4d8dSRobert Watson #include <sys/protosw.h>
60c66b4d8dSRobert Watson #include <sys/socket.h>
61c66b4d8dSRobert Watson #include <sys/socketvar.h>
62c66b4d8dSRobert Watson #include <sys/sysctl.h>
63c66b4d8dSRobert Watson 
64c66b4d8dSRobert Watson #include <net/if.h>
65c66b4d8dSRobert Watson #include <net/if_var.h>
66c66b4d8dSRobert Watson 
67c66b4d8dSRobert Watson #include <netinet/in.h>
68c66b4d8dSRobert Watson #include <netinet/in_pcb.h>
69c66b4d8dSRobert Watson #include <netinet/ip_var.h>
70c66b4d8dSRobert Watson 
71aed55708SRobert Watson #include <security/mac/mac_framework.h>
72c66b4d8dSRobert Watson #include <security/mac/mac_internal.h>
730efd6615SRobert Watson #include <security/mac/mac_policy.h>
74c66b4d8dSRobert Watson 
75c66b4d8dSRobert Watson static struct label *
mac_inpcb_label_alloc(int flag)76c66b4d8dSRobert Watson mac_inpcb_label_alloc(int flag)
77c66b4d8dSRobert Watson {
78c66b4d8dSRobert Watson 	struct label *label;
79c66b4d8dSRobert Watson 	int error;
80c66b4d8dSRobert Watson 
81c66b4d8dSRobert Watson 	label = mac_labelzone_alloc(flag);
82c66b4d8dSRobert Watson 	if (label == NULL)
83c66b4d8dSRobert Watson 		return (NULL);
8440202729SRobert Watson 	if (flag & M_WAITOK)
85fa765671SRobert Watson 		MAC_POLICY_CHECK(inpcb_init_label, label, flag);
8640202729SRobert Watson 	else
87fa765671SRobert Watson 		MAC_POLICY_CHECK_NOSLEEP(inpcb_init_label, label, flag);
88c66b4d8dSRobert Watson 	if (error) {
89fa765671SRobert Watson 		MAC_POLICY_PERFORM_NOSLEEP(inpcb_destroy_label, label);
90c66b4d8dSRobert Watson 		mac_labelzone_free(label);
91c66b4d8dSRobert Watson 		return (NULL);
92c66b4d8dSRobert Watson 	}
93c66b4d8dSRobert Watson 	return (label);
94c66b4d8dSRobert Watson }
95c66b4d8dSRobert Watson 
96c66b4d8dSRobert Watson int
mac_inpcb_init(struct inpcb * inp,int flag)9730d239bcSRobert Watson mac_inpcb_init(struct inpcb *inp, int flag)
98c66b4d8dSRobert Watson {
99c66b4d8dSRobert Watson 
1006356dba0SRobert Watson 	if (mac_labeled & MPC_OBJECT_INPCB) {
101c66b4d8dSRobert Watson 		inp->inp_label = mac_inpcb_label_alloc(flag);
102c66b4d8dSRobert Watson 		if (inp->inp_label == NULL)
103c66b4d8dSRobert Watson 			return (ENOMEM);
1046356dba0SRobert Watson 	} else
1056356dba0SRobert Watson 		inp->inp_label = NULL;
106c66b4d8dSRobert Watson 	return (0);
107c66b4d8dSRobert Watson }
108c66b4d8dSRobert Watson 
109215bab79SShivank Garg /* Check with rules in module if the IPv4 address is allowed. */
110215bab79SShivank Garg int
mac_inet_check_add_addr(struct ucred * cred,const struct in_addr * ia,struct ifnet * ifp)111215bab79SShivank Garg mac_inet_check_add_addr(struct ucred *cred, const struct in_addr *ia,
112215bab79SShivank Garg     struct ifnet *ifp)
113215bab79SShivank Garg {
114215bab79SShivank Garg 	int error;
115215bab79SShivank Garg 
116215bab79SShivank Garg 	MAC_POLICY_CHECK(ip4_check_jail, cred, ia, ifp);
117215bab79SShivank Garg 	return (error);
118215bab79SShivank Garg }
119215bab79SShivank Garg 
120c66b4d8dSRobert Watson static struct label *
mac_ipq_label_alloc(int flag)121c66b4d8dSRobert Watson mac_ipq_label_alloc(int flag)
122c66b4d8dSRobert Watson {
123c66b4d8dSRobert Watson 	struct label *label;
124c66b4d8dSRobert Watson 	int error;
125c66b4d8dSRobert Watson 
126c66b4d8dSRobert Watson 	label = mac_labelzone_alloc(flag);
127c66b4d8dSRobert Watson 	if (label == NULL)
128c66b4d8dSRobert Watson 		return (NULL);
129c66b4d8dSRobert Watson 
13040202729SRobert Watson 	if (flag & M_WAITOK)
131fa765671SRobert Watson 		MAC_POLICY_CHECK(ipq_init_label, label, flag);
13240202729SRobert Watson 	else
133fa765671SRobert Watson 		MAC_POLICY_CHECK_NOSLEEP(ipq_init_label, label, flag);
134c66b4d8dSRobert Watson 	if (error) {
135fa765671SRobert Watson 		MAC_POLICY_PERFORM_NOSLEEP(ipq_destroy_label, label);
136c66b4d8dSRobert Watson 		mac_labelzone_free(label);
137c66b4d8dSRobert Watson 		return (NULL);
138c66b4d8dSRobert Watson 	}
139c66b4d8dSRobert Watson 	return (label);
140c66b4d8dSRobert Watson }
141c66b4d8dSRobert Watson 
142c66b4d8dSRobert Watson int
mac_ipq_init(struct ipq * q,int flag)14337f44cb4SRobert Watson mac_ipq_init(struct ipq *q, int flag)
144c66b4d8dSRobert Watson {
145c66b4d8dSRobert Watson 
1466356dba0SRobert Watson 	if (mac_labeled & MPC_OBJECT_IPQ) {
14737f44cb4SRobert Watson 		q->ipq_label = mac_ipq_label_alloc(flag);
14837f44cb4SRobert Watson 		if (q->ipq_label == NULL)
149c66b4d8dSRobert Watson 			return (ENOMEM);
1506356dba0SRobert Watson 	} else
1516356dba0SRobert Watson 		q->ipq_label = NULL;
152c66b4d8dSRobert Watson 	return (0);
153c66b4d8dSRobert Watson }
154c66b4d8dSRobert Watson 
155c66b4d8dSRobert Watson static void
mac_inpcb_label_free(struct label * label)156c66b4d8dSRobert Watson mac_inpcb_label_free(struct label *label)
157c66b4d8dSRobert Watson {
158c66b4d8dSRobert Watson 
159fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(inpcb_destroy_label, label);
160c66b4d8dSRobert Watson 	mac_labelzone_free(label);
161c66b4d8dSRobert Watson }
162c66b4d8dSRobert Watson 
163c66b4d8dSRobert Watson void
mac_inpcb_destroy(struct inpcb * inp)16430d239bcSRobert Watson mac_inpcb_destroy(struct inpcb *inp)
165c66b4d8dSRobert Watson {
166c66b4d8dSRobert Watson 
1676356dba0SRobert Watson 	if (inp->inp_label != NULL) {
168c66b4d8dSRobert Watson 		mac_inpcb_label_free(inp->inp_label);
169c66b4d8dSRobert Watson 		inp->inp_label = NULL;
170c66b4d8dSRobert Watson 	}
1716356dba0SRobert Watson }
172c66b4d8dSRobert Watson 
173c66b4d8dSRobert Watson static void
mac_ipq_label_free(struct label * label)174c66b4d8dSRobert Watson mac_ipq_label_free(struct label *label)
175c66b4d8dSRobert Watson {
176c66b4d8dSRobert Watson 
177fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(ipq_destroy_label, label);
178c66b4d8dSRobert Watson 	mac_labelzone_free(label);
179c66b4d8dSRobert Watson }
180c66b4d8dSRobert Watson 
181c66b4d8dSRobert Watson void
mac_ipq_destroy(struct ipq * q)18237f44cb4SRobert Watson mac_ipq_destroy(struct ipq *q)
183c66b4d8dSRobert Watson {
184c66b4d8dSRobert Watson 
1856356dba0SRobert Watson 	if (q->ipq_label != NULL) {
18637f44cb4SRobert Watson 		mac_ipq_label_free(q->ipq_label);
18737f44cb4SRobert Watson 		q->ipq_label = NULL;
188c66b4d8dSRobert Watson 	}
1896356dba0SRobert Watson }
190c66b4d8dSRobert Watson 
191c66b4d8dSRobert Watson void
mac_inpcb_create(struct socket * so,struct inpcb * inp)19230d239bcSRobert Watson mac_inpcb_create(struct socket *so, struct inpcb *inp)
193c66b4d8dSRobert Watson {
194c66b4d8dSRobert Watson 
195fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(inpcb_create, so, so->so_label, inp,
19640202729SRobert Watson 	    inp->inp_label);
197c66b4d8dSRobert Watson }
198c66b4d8dSRobert Watson 
199c66b4d8dSRobert Watson void
mac_ipq_reassemble(struct ipq * q,struct mbuf * m)20037f44cb4SRobert Watson mac_ipq_reassemble(struct ipq *q, struct mbuf *m)
201c66b4d8dSRobert Watson {
202c66b4d8dSRobert Watson 	struct label *label;
203c66b4d8dSRobert Watson 
2043de40469SRobert Watson 	if (mac_policy_count == 0)
2053de40469SRobert Watson 		return;
2063de40469SRobert Watson 
20726ae2b86SRobert Watson 	label = mac_mbuf_to_label(m);
208c66b4d8dSRobert Watson 
209fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(ipq_reassemble, q, q->ipq_label, m,
210fa765671SRobert Watson 	    label);
211c66b4d8dSRobert Watson }
212c66b4d8dSRobert Watson 
213c66b4d8dSRobert Watson void
mac_netinet_fragment(struct mbuf * m,struct mbuf * frag)21430d239bcSRobert Watson mac_netinet_fragment(struct mbuf *m, struct mbuf *frag)
215c66b4d8dSRobert Watson {
21626ae2b86SRobert Watson 	struct label *mlabel, *fraglabel;
217c66b4d8dSRobert Watson 
2183de40469SRobert Watson 	if (mac_policy_count == 0)
2193de40469SRobert Watson 		return;
2203de40469SRobert Watson 
22126ae2b86SRobert Watson 	mlabel = mac_mbuf_to_label(m);
22226ae2b86SRobert Watson 	fraglabel = mac_mbuf_to_label(frag);
223c66b4d8dSRobert Watson 
224fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(netinet_fragment, m, mlabel, frag,
225fa765671SRobert Watson 	    fraglabel);
226c66b4d8dSRobert Watson }
227c66b4d8dSRobert Watson 
228c66b4d8dSRobert Watson void
mac_ipq_create(struct mbuf * m,struct ipq * q)22937f44cb4SRobert Watson mac_ipq_create(struct mbuf *m, struct ipq *q)
230c66b4d8dSRobert Watson {
231c66b4d8dSRobert Watson 	struct label *label;
232c66b4d8dSRobert Watson 
2333de40469SRobert Watson 	if (mac_policy_count == 0)
2343de40469SRobert Watson 		return;
2353de40469SRobert Watson 
23626ae2b86SRobert Watson 	label = mac_mbuf_to_label(m);
237c66b4d8dSRobert Watson 
238fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(ipq_create, m, label, q, q->ipq_label);
239c66b4d8dSRobert Watson }
240c66b4d8dSRobert Watson 
241c66b4d8dSRobert Watson void
mac_inpcb_create_mbuf(struct inpcb * inp,struct mbuf * m)24230d239bcSRobert Watson mac_inpcb_create_mbuf(struct inpcb *inp, struct mbuf *m)
243c66b4d8dSRobert Watson {
244c66b4d8dSRobert Watson 	struct label *mlabel;
245c66b4d8dSRobert Watson 
246211b72adSRobert Watson 	INP_LOCK_ASSERT(inp);
2473de40469SRobert Watson 
2483de40469SRobert Watson 	if (mac_policy_count == 0)
2493de40469SRobert Watson 		return;
2503de40469SRobert Watson 
251c66b4d8dSRobert Watson 	mlabel = mac_mbuf_to_label(m);
252c66b4d8dSRobert Watson 
253fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(inpcb_create_mbuf, inp, inp->inp_label, m,
25440202729SRobert Watson 	    mlabel);
255c66b4d8dSRobert Watson }
256c66b4d8dSRobert Watson 
257c66b4d8dSRobert Watson int
mac_ipq_match(struct mbuf * m,struct ipq * q)25837f44cb4SRobert Watson mac_ipq_match(struct mbuf *m, struct ipq *q)
259c66b4d8dSRobert Watson {
260c66b4d8dSRobert Watson 	struct label *label;
261c66b4d8dSRobert Watson 	int result;
262c66b4d8dSRobert Watson 
2633de40469SRobert Watson 	if (mac_policy_count == 0)
2643de40469SRobert Watson 		return (1);
2653de40469SRobert Watson 
26626ae2b86SRobert Watson 	label = mac_mbuf_to_label(m);
267c66b4d8dSRobert Watson 
268c66b4d8dSRobert Watson 	result = 1;
269fa765671SRobert Watson 	MAC_POLICY_BOOLEAN_NOSLEEP(ipq_match, &&, m, label, q, q->ipq_label);
270c66b4d8dSRobert Watson 
271c66b4d8dSRobert Watson 	return (result);
272c66b4d8dSRobert Watson }
273c66b4d8dSRobert Watson 
274c66b4d8dSRobert Watson void
mac_netinet_arp_send(struct ifnet * ifp,struct mbuf * m)275b9b0dac3SRobert Watson mac_netinet_arp_send(struct ifnet *ifp, struct mbuf *m)
276b9b0dac3SRobert Watson {
277b9b0dac3SRobert Watson 	struct label *mlabel;
2785c95417dSRobert Watson 	int locked;
279b9b0dac3SRobert Watson 
2803de40469SRobert Watson 	if (mac_policy_count == 0)
2813de40469SRobert Watson 		return;
2823de40469SRobert Watson 
283b9b0dac3SRobert Watson 	mlabel = mac_mbuf_to_label(m);
284b9b0dac3SRobert Watson 
2855c95417dSRobert Watson 	MAC_IFNET_LOCK(ifp, locked);
28630af2c13SJustin Hibbits 	MAC_POLICY_PERFORM_NOSLEEP(netinet_arp_send, ifp, if_getmaclabel(ifp),
28730af2c13SJustin Hibbits 	    m, mlabel);
2885c95417dSRobert Watson 	MAC_IFNET_UNLOCK(ifp, locked);
289b9b0dac3SRobert Watson }
290b9b0dac3SRobert Watson 
291b9b0dac3SRobert Watson void
mac_netinet_icmp_reply(struct mbuf * mrecv,struct mbuf * msend)292a13e21f7SRobert Watson mac_netinet_icmp_reply(struct mbuf *mrecv, struct mbuf *msend)
293a13e21f7SRobert Watson {
294a13e21f7SRobert Watson 	struct label *mrecvlabel, *msendlabel;
295a13e21f7SRobert Watson 
2963de40469SRobert Watson 	if (mac_policy_count == 0)
2973de40469SRobert Watson 		return;
2983de40469SRobert Watson 
299a13e21f7SRobert Watson 	mrecvlabel = mac_mbuf_to_label(mrecv);
300a13e21f7SRobert Watson 	msendlabel = mac_mbuf_to_label(msend);
301a13e21f7SRobert Watson 
302fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(netinet_icmp_reply, mrecv, mrecvlabel,
303fa765671SRobert Watson 	    msend, msendlabel);
304a13e21f7SRobert Watson }
305a13e21f7SRobert Watson 
306a13e21f7SRobert Watson void
mac_netinet_icmp_replyinplace(struct mbuf * m)307a13e21f7SRobert Watson mac_netinet_icmp_replyinplace(struct mbuf *m)
308c66b4d8dSRobert Watson {
309c66b4d8dSRobert Watson 	struct label *label;
310c66b4d8dSRobert Watson 
3113de40469SRobert Watson 	if (mac_policy_count == 0)
3123de40469SRobert Watson 		return;
3133de40469SRobert Watson 
314c66b4d8dSRobert Watson 	label = mac_mbuf_to_label(m);
315c66b4d8dSRobert Watson 
316fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(netinet_icmp_replyinplace, m, label);
317c66b4d8dSRobert Watson }
31826ae2b86SRobert Watson 
319c66b4d8dSRobert Watson void
mac_netinet_igmp_send(struct ifnet * ifp,struct mbuf * m)320b9b0dac3SRobert Watson mac_netinet_igmp_send(struct ifnet *ifp, struct mbuf *m)
321b9b0dac3SRobert Watson {
322b9b0dac3SRobert Watson 	struct label *mlabel;
3235c95417dSRobert Watson 	int locked;
324b9b0dac3SRobert Watson 
3253de40469SRobert Watson 	if (mac_policy_count == 0)
3263de40469SRobert Watson 		return;
3273de40469SRobert Watson 
328b9b0dac3SRobert Watson 	mlabel = mac_mbuf_to_label(m);
329b9b0dac3SRobert Watson 
3305c95417dSRobert Watson 	MAC_IFNET_LOCK(ifp, locked);
33130af2c13SJustin Hibbits 	MAC_POLICY_PERFORM_NOSLEEP(netinet_igmp_send, ifp, if_getmaclabel(ifp),
33230af2c13SJustin Hibbits 	    m, mlabel);
3335c95417dSRobert Watson 	MAC_IFNET_UNLOCK(ifp, locked);
334b9b0dac3SRobert Watson }
335b9b0dac3SRobert Watson 
336b9b0dac3SRobert Watson void
mac_netinet_tcp_reply(struct mbuf * m)33730d239bcSRobert Watson mac_netinet_tcp_reply(struct mbuf *m)
338c66b4d8dSRobert Watson {
339c66b4d8dSRobert Watson 	struct label *label;
340c66b4d8dSRobert Watson 
3413de40469SRobert Watson 	if (mac_policy_count == 0)
3423de40469SRobert Watson 		return;
3433de40469SRobert Watson 
344c66b4d8dSRobert Watson 	label = mac_mbuf_to_label(m);
345c66b4d8dSRobert Watson 
346fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(netinet_tcp_reply, m, label);
347c66b4d8dSRobert Watson }
348c66b4d8dSRobert Watson 
349c66b4d8dSRobert Watson void
mac_ipq_update(struct mbuf * m,struct ipq * q)35037f44cb4SRobert Watson mac_ipq_update(struct mbuf *m, struct ipq *q)
351c66b4d8dSRobert Watson {
352c66b4d8dSRobert Watson 	struct label *label;
353c66b4d8dSRobert Watson 
3543de40469SRobert Watson 	if (mac_policy_count == 0)
3553de40469SRobert Watson 		return;
3563de40469SRobert Watson 
35726ae2b86SRobert Watson 	label = mac_mbuf_to_label(m);
358c66b4d8dSRobert Watson 
359fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(ipq_update, m, label, q, q->ipq_label);
360c66b4d8dSRobert Watson }
361c66b4d8dSRobert Watson 
3622087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(inpcb_check_deliver, "struct inpcb *",
3632087a58cSRobert Watson     "struct mbuf *");
3642087a58cSRobert Watson 
365c66b4d8dSRobert Watson int
mac_inpcb_check_deliver(struct inpcb * inp,struct mbuf * m)36630d239bcSRobert Watson mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m)
367c66b4d8dSRobert Watson {
368c66b4d8dSRobert Watson 	struct label *label;
369c66b4d8dSRobert Watson 	int error;
370c66b4d8dSRobert Watson 
371c66b4d8dSRobert Watson 	M_ASSERTPKTHDR(m);
372c66b4d8dSRobert Watson 
3733de40469SRobert Watson 	if (mac_policy_count == 0)
3743de40469SRobert Watson 		return (0);
3753de40469SRobert Watson 
376c66b4d8dSRobert Watson 	label = mac_mbuf_to_label(m);
377c66b4d8dSRobert Watson 
378fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(inpcb_check_deliver, inp, inp->inp_label, m,
37940202729SRobert Watson 	    label);
3802087a58cSRobert Watson 	MAC_CHECK_PROBE2(inpcb_check_deliver, error, inp, m);
381c66b4d8dSRobert Watson 
382c66b4d8dSRobert Watson 	return (error);
383c66b4d8dSRobert Watson }
384c66b4d8dSRobert Watson 
3852087a58cSRobert Watson MAC_CHECK_PROBE_DEFINE2(inpcb_check_visible, "struct ucred *",
3862087a58cSRobert Watson     "struct inpcb *");
3872087a58cSRobert Watson 
38837ee7293SBjoern A. Zeeb int
mac_inpcb_check_visible(struct ucred * cred,struct inpcb * inp)38937ee7293SBjoern A. Zeeb mac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp)
39037ee7293SBjoern A. Zeeb {
39137ee7293SBjoern A. Zeeb 	int error;
39237ee7293SBjoern A. Zeeb 
39337ee7293SBjoern A. Zeeb 	INP_LOCK_ASSERT(inp);
39437ee7293SBjoern A. Zeeb 
395fa765671SRobert Watson 	MAC_POLICY_CHECK_NOSLEEP(inpcb_check_visible, cred, inp,
396fa765671SRobert Watson 	    inp->inp_label);
3972087a58cSRobert Watson 	MAC_CHECK_PROBE2(inpcb_check_visible, error, cred, inp);
39837ee7293SBjoern A. Zeeb 
39937ee7293SBjoern A. Zeeb 	return (error);
40037ee7293SBjoern A. Zeeb }
40137ee7293SBjoern A. Zeeb 
402c66b4d8dSRobert Watson void
mac_inpcb_sosetlabel(struct socket * so,struct inpcb * inp)403c66b4d8dSRobert Watson mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp)
404c66b4d8dSRobert Watson {
405c66b4d8dSRobert Watson 
4068501a69cSRobert Watson 	INP_WLOCK_ASSERT(inp);
407c982ffa4SRobert Watson 	SOCK_LOCK_ASSERT(so);
40840202729SRobert Watson 
409fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(inpcb_sosetlabel, so, so->so_label, inp,
41040202729SRobert Watson 	    inp->inp_label);
411c66b4d8dSRobert Watson }
412d94f2a68SChristian S.J. Peron 
413d94f2a68SChristian S.J. Peron void
mac_netinet_firewall_reply(struct mbuf * mrecv,struct mbuf * msend)414a13e21f7SRobert Watson mac_netinet_firewall_reply(struct mbuf *mrecv, struct mbuf *msend)
415a13e21f7SRobert Watson {
416a13e21f7SRobert Watson 	struct label *mrecvlabel, *msendlabel;
417a13e21f7SRobert Watson 
418a13e21f7SRobert Watson 	M_ASSERTPKTHDR(mrecv);
419a13e21f7SRobert Watson 	M_ASSERTPKTHDR(msend);
420a13e21f7SRobert Watson 
4213de40469SRobert Watson 	if (mac_policy_count == 0)
4223de40469SRobert Watson 		return;
4233de40469SRobert Watson 
424a13e21f7SRobert Watson 	mrecvlabel = mac_mbuf_to_label(mrecv);
425a13e21f7SRobert Watson 	msendlabel = mac_mbuf_to_label(msend);
426a13e21f7SRobert Watson 
427fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(netinet_firewall_reply, mrecv, mrecvlabel,
428fa765671SRobert Watson 	    msend, msendlabel);
429a13e21f7SRobert Watson }
430a13e21f7SRobert Watson 
431a13e21f7SRobert Watson void
mac_netinet_firewall_send(struct mbuf * m)43286407646SRobert Watson mac_netinet_firewall_send(struct mbuf *m)
433d94f2a68SChristian S.J. Peron {
434d94f2a68SChristian S.J. Peron 	struct label *label;
435d94f2a68SChristian S.J. Peron 
436d94f2a68SChristian S.J. Peron 	M_ASSERTPKTHDR(m);
43740202729SRobert Watson 
4383de40469SRobert Watson 	if (mac_policy_count == 0)
4393de40469SRobert Watson 		return;
4403de40469SRobert Watson 
441d94f2a68SChristian S.J. Peron 	label = mac_mbuf_to_label(m);
44240202729SRobert Watson 
443fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(netinet_firewall_send, m, label);
444d94f2a68SChristian S.J. Peron }
445826cef3dSChristian S.J. Peron 
446826cef3dSChristian S.J. Peron /*
44795c8c170SRobert Watson  * These functions really should be referencing the syncache structure
44895c8c170SRobert Watson  * instead of the label.  However, due to some of the complexities associated
44928323addSBryan Drewery  * with exposing this syncache structure we operate directly on its label
45095c8c170SRobert Watson  * pointer.  This should be OK since we aren't making any access control
45195c8c170SRobert Watson  * decisions within this code directly, we are merely allocating and copying
45295c8c170SRobert Watson  * label storage so we can properly initialize mbuf labels for any packets
45395c8c170SRobert Watson  * the syncache code might create.
454826cef3dSChristian S.J. Peron  */
455826cef3dSChristian S.J. Peron void
mac_syncache_destroy(struct label ** label)45602be6269SRobert Watson mac_syncache_destroy(struct label **label)
457826cef3dSChristian S.J. Peron {
458826cef3dSChristian S.J. Peron 
4596356dba0SRobert Watson 	if (*label != NULL) {
460fa765671SRobert Watson 		MAC_POLICY_PERFORM_NOSLEEP(syncache_destroy_label, *label);
461826cef3dSChristian S.J. Peron 		mac_labelzone_free(*label);
462826cef3dSChristian S.J. Peron 		*label = NULL;
463826cef3dSChristian S.J. Peron 	}
4646356dba0SRobert Watson }
465826cef3dSChristian S.J. Peron 
466826cef3dSChristian S.J. Peron int
mac_syncache_init(struct label ** label)46702be6269SRobert Watson mac_syncache_init(struct label **label)
468826cef3dSChristian S.J. Peron {
469826cef3dSChristian S.J. Peron 	int error;
470826cef3dSChristian S.J. Peron 
4716356dba0SRobert Watson 	if (mac_labeled & MPC_OBJECT_SYNCACHE) {
472826cef3dSChristian S.J. Peron 		*label = mac_labelzone_alloc(M_NOWAIT);
473826cef3dSChristian S.J. Peron 		if (*label == NULL)
474826cef3dSChristian S.J. Peron 			return (ENOMEM);
475826cef3dSChristian S.J. Peron 		/*
4766356dba0SRobert Watson 		 * Since we are holding the inpcb locks the policy can not
4776356dba0SRobert Watson 		 * allocate policy specific label storage using M_WAITOK.  So
4786356dba0SRobert Watson 		 * we need to do a MAC_CHECK instead of the typical
4796356dba0SRobert Watson 		 * MAC_PERFORM so we can propagate allocation failures back
4806356dba0SRobert Watson 		 * to the syncache code.
481826cef3dSChristian S.J. Peron 		 */
482fa765671SRobert Watson 		MAC_POLICY_CHECK_NOSLEEP(syncache_init_label, *label,
483fa765671SRobert Watson 		    M_NOWAIT);
4841f84ab0fSChristian S.J. Peron 		if (error) {
485fa765671SRobert Watson 			MAC_POLICY_PERFORM_NOSLEEP(syncache_destroy_label,
486fa765671SRobert Watson 			    *label);
4871f84ab0fSChristian S.J. Peron 			mac_labelzone_free(*label);
488*3f279216SMichael Tuexen 			*label = NULL;
4891f84ab0fSChristian S.J. Peron 		}
490826cef3dSChristian S.J. Peron 		return (error);
4916356dba0SRobert Watson 	} else
4926356dba0SRobert Watson 		*label = NULL;
4936356dba0SRobert Watson 	return (0);
494826cef3dSChristian S.J. Peron }
495826cef3dSChristian S.J. Peron 
496826cef3dSChristian S.J. Peron void
mac_syncache_create(struct label * label,struct inpcb * inp)49702be6269SRobert Watson mac_syncache_create(struct label *label, struct inpcb *inp)
498826cef3dSChristian S.J. Peron {
499826cef3dSChristian S.J. Peron 
50008d9c920SGleb Smirnoff 	INP_LOCK_ASSERT(inp);
50140202729SRobert Watson 
502fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(syncache_create, label, inp);
503826cef3dSChristian S.J. Peron }
504826cef3dSChristian S.J. Peron 
505826cef3dSChristian S.J. Peron void
mac_syncache_create_mbuf(struct label * sc_label,struct mbuf * m)50602be6269SRobert Watson mac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m)
507826cef3dSChristian S.J. Peron {
50826ae2b86SRobert Watson 	struct label *mlabel;
509826cef3dSChristian S.J. Peron 
510826cef3dSChristian S.J. Peron 	M_ASSERTPKTHDR(m);
51140202729SRobert Watson 
5123de40469SRobert Watson 	if (mac_policy_count == 0)
5133de40469SRobert Watson 		return;
5143de40469SRobert Watson 
51526ae2b86SRobert Watson 	mlabel = mac_mbuf_to_label(m);
51640202729SRobert Watson 
517fa765671SRobert Watson 	MAC_POLICY_PERFORM_NOSLEEP(syncache_create_mbuf, sc_label, m,
518fa765671SRobert Watson 	    mlabel);
519826cef3dSChristian S.J. Peron }
520