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