xref: /f-stack/freebsd/security/mac/mac_inet6.c (revision a9643ea8)
1*a9643ea8Slogwang /*-
2*a9643ea8Slogwang  * Copyright (c) 2007-2009 Robert N. M. Watson
3*a9643ea8Slogwang  * All rights reserved.
4*a9643ea8Slogwang  *
5*a9643ea8Slogwang  * This software was developed by Robert Watson for the TrustedBSD Project.
6*a9643ea8Slogwang  *
7*a9643ea8Slogwang  * This software was developed at the University of Cambridge Computer
8*a9643ea8Slogwang  * Laboratory with support from a grant from Google, Inc.
9*a9643ea8Slogwang  *
10*a9643ea8Slogwang  * Redistribution and use in source and binary forms, with or without
11*a9643ea8Slogwang  * modification, are permitted provided that the following conditions
12*a9643ea8Slogwang  * are met:
13*a9643ea8Slogwang  * 1. Redistributions of source code must retain the above copyright
14*a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer.
15*a9643ea8Slogwang  * 2. Redistributions in binary form must reproduce the above copyright
16*a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer in the
17*a9643ea8Slogwang  *    documentation and/or other materials provided with the distribution.
18*a9643ea8Slogwang  *
19*a9643ea8Slogwang  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20*a9643ea8Slogwang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21*a9643ea8Slogwang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*a9643ea8Slogwang  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23*a9643ea8Slogwang  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24*a9643ea8Slogwang  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25*a9643ea8Slogwang  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26*a9643ea8Slogwang  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27*a9643ea8Slogwang  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28*a9643ea8Slogwang  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29*a9643ea8Slogwang  * SUCH DAMAGE.
30*a9643ea8Slogwang  */
31*a9643ea8Slogwang 
32*a9643ea8Slogwang #include <sys/cdefs.h>
33*a9643ea8Slogwang __FBSDID("$FreeBSD$");
34*a9643ea8Slogwang 
35*a9643ea8Slogwang #include "opt_mac.h"
36*a9643ea8Slogwang 
37*a9643ea8Slogwang #include <sys/param.h>
38*a9643ea8Slogwang #include <sys/kernel.h>
39*a9643ea8Slogwang #include <sys/lock.h>
40*a9643ea8Slogwang #include <sys/malloc.h>
41*a9643ea8Slogwang #include <sys/mutex.h>
42*a9643ea8Slogwang #include <sys/sbuf.h>
43*a9643ea8Slogwang #include <sys/systm.h>
44*a9643ea8Slogwang #include <sys/mount.h>
45*a9643ea8Slogwang #include <sys/file.h>
46*a9643ea8Slogwang #include <sys/namei.h>
47*a9643ea8Slogwang #include <sys/protosw.h>
48*a9643ea8Slogwang #include <sys/socket.h>
49*a9643ea8Slogwang #include <sys/socketvar.h>
50*a9643ea8Slogwang #include <sys/sysctl.h>
51*a9643ea8Slogwang 
52*a9643ea8Slogwang #include <net/if.h>
53*a9643ea8Slogwang #include <net/if_var.h>
54*a9643ea8Slogwang 
55*a9643ea8Slogwang #include <netinet/in.h>
56*a9643ea8Slogwang #include <netinet/ip6.h>
57*a9643ea8Slogwang #include <netinet6/ip6_var.h>
58*a9643ea8Slogwang 
59*a9643ea8Slogwang #include <security/mac/mac_framework.h>
60*a9643ea8Slogwang #include <security/mac/mac_internal.h>
61*a9643ea8Slogwang #include <security/mac/mac_policy.h>
62*a9643ea8Slogwang 
63*a9643ea8Slogwang static struct label *
mac_ip6q_label_alloc(int flag)64*a9643ea8Slogwang mac_ip6q_label_alloc(int flag)
65*a9643ea8Slogwang {
66*a9643ea8Slogwang 	struct label *label;
67*a9643ea8Slogwang 	int error;
68*a9643ea8Slogwang 
69*a9643ea8Slogwang 	label = mac_labelzone_alloc(flag);
70*a9643ea8Slogwang 	if (label == NULL)
71*a9643ea8Slogwang 		return (NULL);
72*a9643ea8Slogwang 
73*a9643ea8Slogwang 	if (flag & M_WAITOK)
74*a9643ea8Slogwang 		MAC_POLICY_CHECK(ip6q_init_label, label, flag);
75*a9643ea8Slogwang 	else
76*a9643ea8Slogwang 		MAC_POLICY_CHECK_NOSLEEP(ip6q_init_label, label, flag);
77*a9643ea8Slogwang 	if (error) {
78*a9643ea8Slogwang 		MAC_POLICY_PERFORM_NOSLEEP(ip6q_destroy_label, label);
79*a9643ea8Slogwang 		mac_labelzone_free(label);
80*a9643ea8Slogwang 		return (NULL);
81*a9643ea8Slogwang 	}
82*a9643ea8Slogwang 	return (label);
83*a9643ea8Slogwang }
84*a9643ea8Slogwang 
85*a9643ea8Slogwang int
mac_ip6q_init(struct ip6q * q6,int flag)86*a9643ea8Slogwang mac_ip6q_init(struct ip6q *q6, int flag)
87*a9643ea8Slogwang {
88*a9643ea8Slogwang 
89*a9643ea8Slogwang 	if (mac_labeled & MPC_OBJECT_IP6Q) {
90*a9643ea8Slogwang 		q6->ip6q_label = mac_ip6q_label_alloc(flag);
91*a9643ea8Slogwang 		if (q6->ip6q_label == NULL)
92*a9643ea8Slogwang 			return (ENOMEM);
93*a9643ea8Slogwang 	} else
94*a9643ea8Slogwang 		q6->ip6q_label = NULL;
95*a9643ea8Slogwang 	return (0);
96*a9643ea8Slogwang }
97*a9643ea8Slogwang 
98*a9643ea8Slogwang static void
mac_ip6q_label_free(struct label * label)99*a9643ea8Slogwang mac_ip6q_label_free(struct label *label)
100*a9643ea8Slogwang {
101*a9643ea8Slogwang 
102*a9643ea8Slogwang 	MAC_POLICY_PERFORM_NOSLEEP(ip6q_destroy_label, label);
103*a9643ea8Slogwang 	mac_labelzone_free(label);
104*a9643ea8Slogwang }
105*a9643ea8Slogwang 
106*a9643ea8Slogwang void
mac_ip6q_destroy(struct ip6q * q6)107*a9643ea8Slogwang mac_ip6q_destroy(struct ip6q *q6)
108*a9643ea8Slogwang {
109*a9643ea8Slogwang 
110*a9643ea8Slogwang 	if (q6->ip6q_label != NULL) {
111*a9643ea8Slogwang 		mac_ip6q_label_free(q6->ip6q_label);
112*a9643ea8Slogwang 		q6->ip6q_label = NULL;
113*a9643ea8Slogwang 	}
114*a9643ea8Slogwang }
115*a9643ea8Slogwang 
116*a9643ea8Slogwang void
mac_ip6q_reassemble(struct ip6q * q6,struct mbuf * m)117*a9643ea8Slogwang mac_ip6q_reassemble(struct ip6q *q6, struct mbuf *m)
118*a9643ea8Slogwang {
119*a9643ea8Slogwang 	struct label *label;
120*a9643ea8Slogwang 
121*a9643ea8Slogwang 	if (mac_policy_count == 0)
122*a9643ea8Slogwang 		return;
123*a9643ea8Slogwang 
124*a9643ea8Slogwang 	label = mac_mbuf_to_label(m);
125*a9643ea8Slogwang 
126*a9643ea8Slogwang 	MAC_POLICY_PERFORM_NOSLEEP(ip6q_reassemble, q6, q6->ip6q_label, m,
127*a9643ea8Slogwang 	    label);
128*a9643ea8Slogwang }
129*a9643ea8Slogwang 
130*a9643ea8Slogwang void
mac_ip6q_create(struct mbuf * m,struct ip6q * q6)131*a9643ea8Slogwang mac_ip6q_create(struct mbuf *m, struct ip6q *q6)
132*a9643ea8Slogwang {
133*a9643ea8Slogwang 	struct label *label;
134*a9643ea8Slogwang 
135*a9643ea8Slogwang 	if (mac_policy_count == 0)
136*a9643ea8Slogwang 		return;
137*a9643ea8Slogwang 
138*a9643ea8Slogwang 	label = mac_mbuf_to_label(m);
139*a9643ea8Slogwang 
140*a9643ea8Slogwang 	MAC_POLICY_PERFORM_NOSLEEP(ip6q_create, m, label, q6,
141*a9643ea8Slogwang 	    q6->ip6q_label);
142*a9643ea8Slogwang }
143*a9643ea8Slogwang 
144*a9643ea8Slogwang int
mac_ip6q_match(struct mbuf * m,struct ip6q * q6)145*a9643ea8Slogwang mac_ip6q_match(struct mbuf *m, struct ip6q *q6)
146*a9643ea8Slogwang {
147*a9643ea8Slogwang 	struct label *label;
148*a9643ea8Slogwang 	int result;
149*a9643ea8Slogwang 
150*a9643ea8Slogwang 	if (mac_policy_count == 0)
151*a9643ea8Slogwang 		return (1);
152*a9643ea8Slogwang 
153*a9643ea8Slogwang 	label = mac_mbuf_to_label(m);
154*a9643ea8Slogwang 
155*a9643ea8Slogwang 	result = 1;
156*a9643ea8Slogwang 	MAC_POLICY_BOOLEAN_NOSLEEP(ip6q_match, &&, m, label, q6,
157*a9643ea8Slogwang 	    q6->ip6q_label);
158*a9643ea8Slogwang 
159*a9643ea8Slogwang 	return (result);
160*a9643ea8Slogwang }
161*a9643ea8Slogwang 
162*a9643ea8Slogwang void
mac_ip6q_update(struct mbuf * m,struct ip6q * q6)163*a9643ea8Slogwang mac_ip6q_update(struct mbuf *m, struct ip6q *q6)
164*a9643ea8Slogwang {
165*a9643ea8Slogwang 	struct label *label;
166*a9643ea8Slogwang 
167*a9643ea8Slogwang 	if (mac_policy_count == 0)
168*a9643ea8Slogwang 		return;
169*a9643ea8Slogwang 
170*a9643ea8Slogwang 	label = mac_mbuf_to_label(m);
171*a9643ea8Slogwang 
172*a9643ea8Slogwang 	MAC_POLICY_PERFORM_NOSLEEP(ip6q_update, m, label, q6,
173*a9643ea8Slogwang 	    q6->ip6q_label);
174*a9643ea8Slogwang }
175*a9643ea8Slogwang 
176*a9643ea8Slogwang void
mac_netinet6_nd6_send(struct ifnet * ifp,struct mbuf * m)177*a9643ea8Slogwang mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m)
178*a9643ea8Slogwang {
179*a9643ea8Slogwang 	struct label *mlabel;
180*a9643ea8Slogwang 
181*a9643ea8Slogwang 	if (mac_policy_count == 0)
182*a9643ea8Slogwang 		return;
183*a9643ea8Slogwang 
184*a9643ea8Slogwang 	mlabel = mac_mbuf_to_label(m);
185*a9643ea8Slogwang 
186*a9643ea8Slogwang 	MAC_POLICY_PERFORM_NOSLEEP(netinet6_nd6_send, ifp, ifp->if_label, m,
187*a9643ea8Slogwang 	    mlabel);
188*a9643ea8Slogwang }
189