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