Deleted Added
full compact
mac_net.c (121507) mac_net.c (122159)
1/*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001 Ilmar S. Habibulin
4 * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
5 * All rights reserved.
6 *
7 * This software was developed by Robert Watson and Ilmar Habibulin for the
8 * TrustedBSD Project.
9 *
10 * This software was developed for the FreeBSD Project in part by Network
11 * Associates Laboratories, the Security Research Division of Network
12 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
13 * as part of the DARPA CHATS research program.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
3 * Copyright (c) 2001 Ilmar S. Habibulin
4 * Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
5 * All rights reserved.
6 *
7 * This software was developed by Robert Watson and Ilmar Habibulin for the
8 * TrustedBSD Project.
9 *
10 * This software was developed for the FreeBSD Project in part by Network
11 * Associates Laboratories, the Security Research Division of Network
12 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
13 * as part of the DARPA CHATS research program.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: head/sys/security/mac/mac_net.c 121507 2003-10-25 15:28:20Z rwatson $");
38__FBSDID("$FreeBSD: head/sys/security/mac/mac_net.c 122159 2003-11-06 03:42:43Z rwatson $");
39
40#include "opt_mac.h"
41
42#include <sys/param.h>
43#include <sys/kernel.h>
44#include <sys/lock.h>
45#include <sys/malloc.h>
46#include <sys/mutex.h>
47#include <sys/mac.h>
48#include <sys/sbuf.h>
49#include <sys/systm.h>
50#include <sys/mount.h>
51#include <sys/file.h>
52#include <sys/namei.h>
53#include <sys/socket.h>
54#include <sys/socketvar.h>
55#include <sys/sysctl.h>
56
57#include <sys/mac_policy.h>
58
59#include <net/bpfdesc.h>
60#include <net/if.h>
61#include <net/if_var.h>
62
63#include <netinet/in.h>
64#include <netinet/ip_var.h>
65
66#include <security/mac/mac_internal.h>
67
68static int mac_enforce_network = 1;
69SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
70 &mac_enforce_network, 0, "Enforce MAC policy on network packets");
71TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
72
73static int mac_enforce_socket = 1;
74SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
75 &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
76TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
77
78#ifdef MAC_DEBUG
79static unsigned int nmacmbufs, nmacifnets, nmacbpfdescs, nmacsockets,
80 nmacipqs;
81
82SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD,
83 &nmacmbufs, 0, "number of mbufs in use");
84SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
85 &nmacifnets, 0, "number of ifnets in use");
86SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
87 &nmacipqs, 0, "number of ipqs in use");
88SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD,
89 &nmacbpfdescs, 0, "number of bpfdescs in use");
90SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
91 &nmacsockets, 0, "number of sockets in use");
92#endif
93
94static void mac_destroy_socket_label(struct label *label);
95
96static struct label *
97mbuf_to_label(struct mbuf *mbuf)
98{
99 struct m_tag *tag;
100 struct label *label;
101
102 tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
103 label = (struct label *)(tag+1);
104
105 return (label);
106}
107
108void
109mac_init_bpfdesc(struct bpf_d *bpf_d)
110{
111
112 mac_init_label(&bpf_d->bd_label);
113 MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label);
114 MAC_DEBUG_COUNTER_INC(&nmacbpfdescs);
115}
116
117static void
118mac_init_ifnet_label(struct label *label)
119{
120
121 mac_init_label(label);
122 MAC_PERFORM(init_ifnet_label, label);
123 MAC_DEBUG_COUNTER_INC(&nmacifnets);
124}
125
126void
127mac_init_ifnet(struct ifnet *ifp)
128{
129
130 mac_init_ifnet_label(&ifp->if_label);
131}
132
133int
134mac_init_ipq(struct ipq *ipq, int flag)
135{
136 int error;
137
138 mac_init_label(&ipq->ipq_label);
139
140 MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag);
141 if (error) {
142 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
143 mac_destroy_label(&ipq->ipq_label);
144 } else {
145 MAC_DEBUG_COUNTER_INC(&nmacipqs);
146 }
147 return (error);
148}
149
150int
151mac_init_mbuf_tag(struct m_tag *tag, int flag)
152{
153 struct label *label;
154 int error;
155
156 label = (struct label *) (tag + 1);
157 mac_init_label(label);
158
159 MAC_CHECK(init_mbuf_label, label, flag);
160 if (error) {
161 MAC_PERFORM(destroy_mbuf_label, label);
162 mac_destroy_label(label);
163 } else {
164 MAC_DEBUG_COUNTER_INC(&nmacmbufs);
165 }
166 return (error);
167}
168
169int
170mac_init_mbuf(struct mbuf *m, int flag)
171{
172 struct m_tag *tag;
173 int error;
174
175 M_ASSERTPKTHDR(m);
176
177#ifndef MAC_ALWAYS_LABEL_MBUF
178 /*
179 * If conditionally allocating mbuf labels, don't allocate unless
180 * they are required.
181 */
182 if (!mac_labelmbufs)
183 return (0);
184#endif
185 tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
186 flag);
187 if (tag == NULL)
188 return (ENOMEM);
189 error = mac_init_mbuf_tag(tag, flag);
190 if (error) {
191 m_tag_free(tag);
192 return (error);
193 }
194 m_tag_prepend(m, tag);
195 return (0);
196}
197
198static int
199mac_init_socket_label(struct label *label, int flag)
200{
201 int error;
202
203 mac_init_label(label);
204
205 MAC_CHECK(init_socket_label, label, flag);
206 if (error) {
207 MAC_PERFORM(destroy_socket_label, label);
208 mac_destroy_label(label);
209 } else {
210 MAC_DEBUG_COUNTER_INC(&nmacsockets);
211 }
212
213 return (error);
214}
215
216static int
217mac_init_socket_peer_label(struct label *label, int flag)
218{
219 int error;
220
221 mac_init_label(label);
222
223 MAC_CHECK(init_socket_peer_label, label, flag);
224 if (error) {
225 MAC_PERFORM(destroy_socket_label, label);
226 mac_destroy_label(label);
227 }
228
229 return (error);
230}
231
232int
233mac_init_socket(struct socket *socket, int flag)
234{
235 int error;
236
237 error = mac_init_socket_label(&socket->so_label, flag);
238 if (error)
239 return (error);
240
241 error = mac_init_socket_peer_label(&socket->so_peerlabel, flag);
242 if (error)
243 mac_destroy_socket_label(&socket->so_label);
244
245 return (error);
246}
247
248void
249mac_destroy_bpfdesc(struct bpf_d *bpf_d)
250{
251
252 MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label);
253 mac_destroy_label(&bpf_d->bd_label);
254 MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs);
255}
256
257static void
258mac_destroy_ifnet_label(struct label *label)
259{
260
261 MAC_PERFORM(destroy_ifnet_label, label);
262 mac_destroy_label(label);
263 MAC_DEBUG_COUNTER_DEC(&nmacifnets);
264}
265
266void
267mac_destroy_ifnet(struct ifnet *ifp)
268{
269
270 mac_destroy_ifnet_label(&ifp->if_label);
271}
272
273void
274mac_destroy_ipq(struct ipq *ipq)
275{
276
277 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
278 mac_destroy_label(&ipq->ipq_label);
279 MAC_DEBUG_COUNTER_DEC(&nmacipqs);
280}
281
282void
283mac_destroy_mbuf_tag(struct m_tag *tag)
284{
285 struct label *label;
286
287 label = (struct label *)(tag+1);
288
289 MAC_PERFORM(destroy_mbuf_label, label);
290 mac_destroy_label(label);
291 MAC_DEBUG_COUNTER_DEC(&nmacmbufs);
292}
293
294static void
295mac_destroy_socket_label(struct label *label)
296{
297
298 MAC_PERFORM(destroy_socket_label, label);
299 mac_destroy_label(label);
300 MAC_DEBUG_COUNTER_DEC(&nmacsockets);
301}
302
303static void
304mac_destroy_socket_peer_label(struct label *label)
305{
306
307 MAC_PERFORM(destroy_socket_peer_label, label);
308 mac_destroy_label(label);
309}
310
311void
312mac_destroy_socket(struct socket *socket)
313{
314
315 mac_destroy_socket_label(&socket->so_label);
316 mac_destroy_socket_peer_label(&socket->so_peerlabel);
317}
318
319void
320mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
321{
322 struct label *src_label, *dest_label;
323
324 src_label = (struct label *)(src+1);
325 dest_label = (struct label *)(dest+1);
326
327 /*
328 * mac_init_mbuf_tag() is called on the target tag in
329 * m_tag_copy(), so we don't need to call it here.
330 */
331 MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
332}
333
334static int
335mac_externalize_ifnet_label(struct label *label, char *elements,
39
40#include "opt_mac.h"
41
42#include <sys/param.h>
43#include <sys/kernel.h>
44#include <sys/lock.h>
45#include <sys/malloc.h>
46#include <sys/mutex.h>
47#include <sys/mac.h>
48#include <sys/sbuf.h>
49#include <sys/systm.h>
50#include <sys/mount.h>
51#include <sys/file.h>
52#include <sys/namei.h>
53#include <sys/socket.h>
54#include <sys/socketvar.h>
55#include <sys/sysctl.h>
56
57#include <sys/mac_policy.h>
58
59#include <net/bpfdesc.h>
60#include <net/if.h>
61#include <net/if_var.h>
62
63#include <netinet/in.h>
64#include <netinet/ip_var.h>
65
66#include <security/mac/mac_internal.h>
67
68static int mac_enforce_network = 1;
69SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
70 &mac_enforce_network, 0, "Enforce MAC policy on network packets");
71TUNABLE_INT("security.mac.enforce_network", &mac_enforce_network);
72
73static int mac_enforce_socket = 1;
74SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
75 &mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
76TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
77
78#ifdef MAC_DEBUG
79static unsigned int nmacmbufs, nmacifnets, nmacbpfdescs, nmacsockets,
80 nmacipqs;
81
82SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, mbufs, CTLFLAG_RD,
83 &nmacmbufs, 0, "number of mbufs in use");
84SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ifnets, CTLFLAG_RD,
85 &nmacifnets, 0, "number of ifnets in use");
86SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, ipqs, CTLFLAG_RD,
87 &nmacipqs, 0, "number of ipqs in use");
88SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, bpfdescs, CTLFLAG_RD,
89 &nmacbpfdescs, 0, "number of bpfdescs in use");
90SYSCTL_UINT(_security_mac_debug_counters, OID_AUTO, sockets, CTLFLAG_RD,
91 &nmacsockets, 0, "number of sockets in use");
92#endif
93
94static void mac_destroy_socket_label(struct label *label);
95
96static struct label *
97mbuf_to_label(struct mbuf *mbuf)
98{
99 struct m_tag *tag;
100 struct label *label;
101
102 tag = m_tag_find(mbuf, PACKET_TAG_MACLABEL, NULL);
103 label = (struct label *)(tag+1);
104
105 return (label);
106}
107
108void
109mac_init_bpfdesc(struct bpf_d *bpf_d)
110{
111
112 mac_init_label(&bpf_d->bd_label);
113 MAC_PERFORM(init_bpfdesc_label, &bpf_d->bd_label);
114 MAC_DEBUG_COUNTER_INC(&nmacbpfdescs);
115}
116
117static void
118mac_init_ifnet_label(struct label *label)
119{
120
121 mac_init_label(label);
122 MAC_PERFORM(init_ifnet_label, label);
123 MAC_DEBUG_COUNTER_INC(&nmacifnets);
124}
125
126void
127mac_init_ifnet(struct ifnet *ifp)
128{
129
130 mac_init_ifnet_label(&ifp->if_label);
131}
132
133int
134mac_init_ipq(struct ipq *ipq, int flag)
135{
136 int error;
137
138 mac_init_label(&ipq->ipq_label);
139
140 MAC_CHECK(init_ipq_label, &ipq->ipq_label, flag);
141 if (error) {
142 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
143 mac_destroy_label(&ipq->ipq_label);
144 } else {
145 MAC_DEBUG_COUNTER_INC(&nmacipqs);
146 }
147 return (error);
148}
149
150int
151mac_init_mbuf_tag(struct m_tag *tag, int flag)
152{
153 struct label *label;
154 int error;
155
156 label = (struct label *) (tag + 1);
157 mac_init_label(label);
158
159 MAC_CHECK(init_mbuf_label, label, flag);
160 if (error) {
161 MAC_PERFORM(destroy_mbuf_label, label);
162 mac_destroy_label(label);
163 } else {
164 MAC_DEBUG_COUNTER_INC(&nmacmbufs);
165 }
166 return (error);
167}
168
169int
170mac_init_mbuf(struct mbuf *m, int flag)
171{
172 struct m_tag *tag;
173 int error;
174
175 M_ASSERTPKTHDR(m);
176
177#ifndef MAC_ALWAYS_LABEL_MBUF
178 /*
179 * If conditionally allocating mbuf labels, don't allocate unless
180 * they are required.
181 */
182 if (!mac_labelmbufs)
183 return (0);
184#endif
185 tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
186 flag);
187 if (tag == NULL)
188 return (ENOMEM);
189 error = mac_init_mbuf_tag(tag, flag);
190 if (error) {
191 m_tag_free(tag);
192 return (error);
193 }
194 m_tag_prepend(m, tag);
195 return (0);
196}
197
198static int
199mac_init_socket_label(struct label *label, int flag)
200{
201 int error;
202
203 mac_init_label(label);
204
205 MAC_CHECK(init_socket_label, label, flag);
206 if (error) {
207 MAC_PERFORM(destroy_socket_label, label);
208 mac_destroy_label(label);
209 } else {
210 MAC_DEBUG_COUNTER_INC(&nmacsockets);
211 }
212
213 return (error);
214}
215
216static int
217mac_init_socket_peer_label(struct label *label, int flag)
218{
219 int error;
220
221 mac_init_label(label);
222
223 MAC_CHECK(init_socket_peer_label, label, flag);
224 if (error) {
225 MAC_PERFORM(destroy_socket_label, label);
226 mac_destroy_label(label);
227 }
228
229 return (error);
230}
231
232int
233mac_init_socket(struct socket *socket, int flag)
234{
235 int error;
236
237 error = mac_init_socket_label(&socket->so_label, flag);
238 if (error)
239 return (error);
240
241 error = mac_init_socket_peer_label(&socket->so_peerlabel, flag);
242 if (error)
243 mac_destroy_socket_label(&socket->so_label);
244
245 return (error);
246}
247
248void
249mac_destroy_bpfdesc(struct bpf_d *bpf_d)
250{
251
252 MAC_PERFORM(destroy_bpfdesc_label, &bpf_d->bd_label);
253 mac_destroy_label(&bpf_d->bd_label);
254 MAC_DEBUG_COUNTER_DEC(&nmacbpfdescs);
255}
256
257static void
258mac_destroy_ifnet_label(struct label *label)
259{
260
261 MAC_PERFORM(destroy_ifnet_label, label);
262 mac_destroy_label(label);
263 MAC_DEBUG_COUNTER_DEC(&nmacifnets);
264}
265
266void
267mac_destroy_ifnet(struct ifnet *ifp)
268{
269
270 mac_destroy_ifnet_label(&ifp->if_label);
271}
272
273void
274mac_destroy_ipq(struct ipq *ipq)
275{
276
277 MAC_PERFORM(destroy_ipq_label, &ipq->ipq_label);
278 mac_destroy_label(&ipq->ipq_label);
279 MAC_DEBUG_COUNTER_DEC(&nmacipqs);
280}
281
282void
283mac_destroy_mbuf_tag(struct m_tag *tag)
284{
285 struct label *label;
286
287 label = (struct label *)(tag+1);
288
289 MAC_PERFORM(destroy_mbuf_label, label);
290 mac_destroy_label(label);
291 MAC_DEBUG_COUNTER_DEC(&nmacmbufs);
292}
293
294static void
295mac_destroy_socket_label(struct label *label)
296{
297
298 MAC_PERFORM(destroy_socket_label, label);
299 mac_destroy_label(label);
300 MAC_DEBUG_COUNTER_DEC(&nmacsockets);
301}
302
303static void
304mac_destroy_socket_peer_label(struct label *label)
305{
306
307 MAC_PERFORM(destroy_socket_peer_label, label);
308 mac_destroy_label(label);
309}
310
311void
312mac_destroy_socket(struct socket *socket)
313{
314
315 mac_destroy_socket_label(&socket->so_label);
316 mac_destroy_socket_peer_label(&socket->so_peerlabel);
317}
318
319void
320mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
321{
322 struct label *src_label, *dest_label;
323
324 src_label = (struct label *)(src+1);
325 dest_label = (struct label *)(dest+1);
326
327 /*
328 * mac_init_mbuf_tag() is called on the target tag in
329 * m_tag_copy(), so we don't need to call it here.
330 */
331 MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
332}
333
334static int
335mac_externalize_ifnet_label(struct label *label, char *elements,
336 char *outbuf, size_t outbuflen, int flags)
336 char *outbuf, size_t outbuflen)
337{
338 int error;
339
340 MAC_EXTERNALIZE(ifnet, label, elements, outbuf, outbuflen);
341
342 return (error);
343}
344
345static int
346mac_externalize_socket_label(struct label *label, char *elements,
337{
338 int error;
339
340 MAC_EXTERNALIZE(ifnet, label, elements, outbuf, outbuflen);
341
342 return (error);
343}
344
345static int
346mac_externalize_socket_label(struct label *label, char *elements,
347 char *outbuf, size_t outbuflen, int flags)
347 char *outbuf, size_t outbuflen)
348{
349 int error;
350
351 MAC_EXTERNALIZE(socket, label, elements, outbuf, outbuflen);
352
353 return (error);
354}
355
356static int
357mac_externalize_socket_peer_label(struct label *label, char *elements,
348{
349 int error;
350
351 MAC_EXTERNALIZE(socket, label, elements, outbuf, outbuflen);
352
353 return (error);
354}
355
356static int
357mac_externalize_socket_peer_label(struct label *label, char *elements,
358 char *outbuf, size_t outbuflen, int flags)
358 char *outbuf, size_t outbuflen)
359{
360 int error;
361
362 MAC_EXTERNALIZE(socket_peer, label, elements, outbuf, outbuflen);
363
364 return (error);
365}
366
367static int
368mac_internalize_ifnet_label(struct label *label, char *string)
369{
370 int error;
371
372 MAC_INTERNALIZE(ifnet, label, string);
373
374 return (error);
375}
376
377static int
378mac_internalize_socket_label(struct label *label, char *string)
379{
380 int error;
381
382 MAC_INTERNALIZE(socket, label, string);
383
384 return (error);
385}
386
387void
388mac_create_ifnet(struct ifnet *ifnet)
389{
390
391 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
392}
393
394void
395mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
396{
397
398 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
399}
400
401void
402mac_create_socket(struct ucred *cred, struct socket *socket)
403{
404
405 MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
406}
407
408void
409mac_create_socket_from_socket(struct socket *oldsocket,
410 struct socket *newsocket)
411{
412
413 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
414 newsocket, &newsocket->so_label);
415}
416
417static void
418mac_relabel_socket(struct ucred *cred, struct socket *socket,
419 struct label *newlabel)
420{
421
422 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
423}
424
425void
426mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
427{
428 struct label *label;
429
430 label = mbuf_to_label(mbuf);
431
432 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket,
433 &socket->so_peerlabel);
434}
435
436void
437mac_set_socket_peer_from_socket(struct socket *oldsocket,
438 struct socket *newsocket)
439{
440
441 MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
442 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
443}
444
445void
446mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
447{
448 struct label *label;
449
450 label = mbuf_to_label(datagram);
451
452 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
453 datagram, label);
454}
455
456void
457mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
458{
459 struct label *datagramlabel, *fragmentlabel;
460
461 datagramlabel = mbuf_to_label(datagram);
462 fragmentlabel = mbuf_to_label(fragment);
463
464 MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment,
465 fragmentlabel);
466}
467
468void
469mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
470{
471 struct label *label;
472
473 label = mbuf_to_label(fragment);
474
475 MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label);
476}
477
478void
479mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
480{
481 struct label *oldmbuflabel, *newmbuflabel;
482
483 oldmbuflabel = mbuf_to_label(oldmbuf);
484 newmbuflabel = mbuf_to_label(newmbuf);
485
486 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf,
487 newmbuflabel);
488}
489
490void
491mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
492{
493 struct label *label;
494
495 label = mbuf_to_label(mbuf);
496
497 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
498 label);
499}
500
501void
502mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
503{
504 struct label *label;
505
506 label = mbuf_to_label(mbuf);
507
508 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
509 label);
510}
511
512void
513mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
514{
515 struct label *label;
516
517 label = mbuf_to_label(mbuf);
518
519 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
520 label);
521}
522
523void
524mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
525 struct mbuf *newmbuf)
526{
527 struct label *oldmbuflabel, *newmbuflabel;
528
529 oldmbuflabel = mbuf_to_label(oldmbuf);
530 newmbuflabel = mbuf_to_label(newmbuf);
531
532 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel,
533 ifnet, &ifnet->if_label, newmbuf, newmbuflabel);
534}
535
536void
537mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
538{
539 struct label *oldmbuflabel, *newmbuflabel;
540
541 oldmbuflabel = mbuf_to_label(oldmbuf);
542 newmbuflabel = mbuf_to_label(newmbuf);
543
544 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf,
545 newmbuflabel);
546}
547
548int
549mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
550{
551 struct label *label;
552 int result;
553
554 label = mbuf_to_label(fragment);
555
556 result = 1;
557 MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq,
558 &ipq->ipq_label);
559
560 return (result);
561}
562
563void
564mac_reflect_mbuf_icmp(struct mbuf *m)
565{
566 struct label *label;
567
568 label = mbuf_to_label(m);
569
570 MAC_PERFORM(reflect_mbuf_icmp, m, label);
571}
572void
573mac_reflect_mbuf_tcp(struct mbuf *m)
574{
575 struct label *label;
576
577 label = mbuf_to_label(m);
578
579 MAC_PERFORM(reflect_mbuf_tcp, m, label);
580}
581
582void
583mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
584{
585 struct label *label;
586
587 label = mbuf_to_label(fragment);
588
589 MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label);
590}
591
592void
593mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
594{
595 struct label *label;
596
597 label = mbuf_to_label(mbuf);
598
599 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
600 label);
601}
602
603int
604mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
605{
606 int error;
607
608 if (!mac_enforce_network)
609 return (0);
610
611 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
612 &ifnet->if_label);
613
614 return (error);
615}
616
617int
618mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
619{
620 struct label *label;
621 int error;
622
623 M_ASSERTPKTHDR(mbuf);
624
625 if (!mac_enforce_network)
626 return (0);
627
628 label = mbuf_to_label(mbuf);
629
630 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
631 label);
632
633 return (error);
634}
635
636int
637mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
638 struct sockaddr *sockaddr)
639{
640 int error;
641
642 if (!mac_enforce_socket)
643 return (0);
644
645 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
646 sockaddr);
647
648 return (error);
649}
650
651int
652mac_check_socket_connect(struct ucred *cred, struct socket *socket,
653 struct sockaddr *sockaddr)
654{
655 int error;
656
657 if (!mac_enforce_socket)
658 return (0);
659
660 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
661 sockaddr);
662
663 return (error);
664}
665
666int
667mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
668{
669 struct label *label;
670 int error;
671
672 if (!mac_enforce_socket)
673 return (0);
674
675 label = mbuf_to_label(mbuf);
676
677 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
678 label);
679
680 return (error);
681}
682
683int
684mac_check_socket_listen(struct ucred *cred, struct socket *socket)
685{
686 int error;
687
688 if (!mac_enforce_socket)
689 return (0);
690
691 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
692 return (error);
693}
694
695int
696mac_check_socket_receive(struct ucred *cred, struct socket *so)
697{
698 int error;
699
700 if (!mac_enforce_socket)
701 return (0);
702
703 MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
704
705 return (error);
706}
707
708static int
709mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
710 struct label *newlabel)
711{
712 int error;
713
714 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
715 newlabel);
716
717 return (error);
718}
719
720int
721mac_check_socket_send(struct ucred *cred, struct socket *so)
722{
723 int error;
724
725 if (!mac_enforce_socket)
726 return (0);
727
728 MAC_CHECK(check_socket_send, cred, so, &so->so_label);
729
730 return (error);
731}
732
733int
734mac_check_socket_visible(struct ucred *cred, struct socket *socket)
735{
736 int error;
737
738 if (!mac_enforce_socket)
739 return (0);
740
741 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
742
743 return (error);
744}
745
746int
747mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
748 struct ifnet *ifnet)
749{
750 char *elements, *buffer;
751 struct mac mac;
752 int error;
753
754 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
755 if (error)
756 return (error);
757
758 error = mac_check_structmac_consistent(&mac);
759 if (error)
760 return (error);
761
762 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
763 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
764 if (error) {
765 free(elements, M_MACTEMP);
766 return (error);
767 }
768
769 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
770 error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
359{
360 int error;
361
362 MAC_EXTERNALIZE(socket_peer, label, elements, outbuf, outbuflen);
363
364 return (error);
365}
366
367static int
368mac_internalize_ifnet_label(struct label *label, char *string)
369{
370 int error;
371
372 MAC_INTERNALIZE(ifnet, label, string);
373
374 return (error);
375}
376
377static int
378mac_internalize_socket_label(struct label *label, char *string)
379{
380 int error;
381
382 MAC_INTERNALIZE(socket, label, string);
383
384 return (error);
385}
386
387void
388mac_create_ifnet(struct ifnet *ifnet)
389{
390
391 MAC_PERFORM(create_ifnet, ifnet, &ifnet->if_label);
392}
393
394void
395mac_create_bpfdesc(struct ucred *cred, struct bpf_d *bpf_d)
396{
397
398 MAC_PERFORM(create_bpfdesc, cred, bpf_d, &bpf_d->bd_label);
399}
400
401void
402mac_create_socket(struct ucred *cred, struct socket *socket)
403{
404
405 MAC_PERFORM(create_socket, cred, socket, &socket->so_label);
406}
407
408void
409mac_create_socket_from_socket(struct socket *oldsocket,
410 struct socket *newsocket)
411{
412
413 MAC_PERFORM(create_socket_from_socket, oldsocket, &oldsocket->so_label,
414 newsocket, &newsocket->so_label);
415}
416
417static void
418mac_relabel_socket(struct ucred *cred, struct socket *socket,
419 struct label *newlabel)
420{
421
422 MAC_PERFORM(relabel_socket, cred, socket, &socket->so_label, newlabel);
423}
424
425void
426mac_set_socket_peer_from_mbuf(struct mbuf *mbuf, struct socket *socket)
427{
428 struct label *label;
429
430 label = mbuf_to_label(mbuf);
431
432 MAC_PERFORM(set_socket_peer_from_mbuf, mbuf, label, socket,
433 &socket->so_peerlabel);
434}
435
436void
437mac_set_socket_peer_from_socket(struct socket *oldsocket,
438 struct socket *newsocket)
439{
440
441 MAC_PERFORM(set_socket_peer_from_socket, oldsocket,
442 &oldsocket->so_label, newsocket, &newsocket->so_peerlabel);
443}
444
445void
446mac_create_datagram_from_ipq(struct ipq *ipq, struct mbuf *datagram)
447{
448 struct label *label;
449
450 label = mbuf_to_label(datagram);
451
452 MAC_PERFORM(create_datagram_from_ipq, ipq, &ipq->ipq_label,
453 datagram, label);
454}
455
456void
457mac_create_fragment(struct mbuf *datagram, struct mbuf *fragment)
458{
459 struct label *datagramlabel, *fragmentlabel;
460
461 datagramlabel = mbuf_to_label(datagram);
462 fragmentlabel = mbuf_to_label(fragment);
463
464 MAC_PERFORM(create_fragment, datagram, datagramlabel, fragment,
465 fragmentlabel);
466}
467
468void
469mac_create_ipq(struct mbuf *fragment, struct ipq *ipq)
470{
471 struct label *label;
472
473 label = mbuf_to_label(fragment);
474
475 MAC_PERFORM(create_ipq, fragment, label, ipq, &ipq->ipq_label);
476}
477
478void
479mac_create_mbuf_from_mbuf(struct mbuf *oldmbuf, struct mbuf *newmbuf)
480{
481 struct label *oldmbuflabel, *newmbuflabel;
482
483 oldmbuflabel = mbuf_to_label(oldmbuf);
484 newmbuflabel = mbuf_to_label(newmbuf);
485
486 MAC_PERFORM(create_mbuf_from_mbuf, oldmbuf, oldmbuflabel, newmbuf,
487 newmbuflabel);
488}
489
490void
491mac_create_mbuf_from_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
492{
493 struct label *label;
494
495 label = mbuf_to_label(mbuf);
496
497 MAC_PERFORM(create_mbuf_from_bpfdesc, bpf_d, &bpf_d->bd_label, mbuf,
498 label);
499}
500
501void
502mac_create_mbuf_linklayer(struct ifnet *ifnet, struct mbuf *mbuf)
503{
504 struct label *label;
505
506 label = mbuf_to_label(mbuf);
507
508 MAC_PERFORM(create_mbuf_linklayer, ifnet, &ifnet->if_label, mbuf,
509 label);
510}
511
512void
513mac_create_mbuf_from_ifnet(struct ifnet *ifnet, struct mbuf *mbuf)
514{
515 struct label *label;
516
517 label = mbuf_to_label(mbuf);
518
519 MAC_PERFORM(create_mbuf_from_ifnet, ifnet, &ifnet->if_label, mbuf,
520 label);
521}
522
523void
524mac_create_mbuf_multicast_encap(struct mbuf *oldmbuf, struct ifnet *ifnet,
525 struct mbuf *newmbuf)
526{
527 struct label *oldmbuflabel, *newmbuflabel;
528
529 oldmbuflabel = mbuf_to_label(oldmbuf);
530 newmbuflabel = mbuf_to_label(newmbuf);
531
532 MAC_PERFORM(create_mbuf_multicast_encap, oldmbuf, oldmbuflabel,
533 ifnet, &ifnet->if_label, newmbuf, newmbuflabel);
534}
535
536void
537mac_create_mbuf_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
538{
539 struct label *oldmbuflabel, *newmbuflabel;
540
541 oldmbuflabel = mbuf_to_label(oldmbuf);
542 newmbuflabel = mbuf_to_label(newmbuf);
543
544 MAC_PERFORM(create_mbuf_netlayer, oldmbuf, oldmbuflabel, newmbuf,
545 newmbuflabel);
546}
547
548int
549mac_fragment_match(struct mbuf *fragment, struct ipq *ipq)
550{
551 struct label *label;
552 int result;
553
554 label = mbuf_to_label(fragment);
555
556 result = 1;
557 MAC_BOOLEAN(fragment_match, &&, fragment, label, ipq,
558 &ipq->ipq_label);
559
560 return (result);
561}
562
563void
564mac_reflect_mbuf_icmp(struct mbuf *m)
565{
566 struct label *label;
567
568 label = mbuf_to_label(m);
569
570 MAC_PERFORM(reflect_mbuf_icmp, m, label);
571}
572void
573mac_reflect_mbuf_tcp(struct mbuf *m)
574{
575 struct label *label;
576
577 label = mbuf_to_label(m);
578
579 MAC_PERFORM(reflect_mbuf_tcp, m, label);
580}
581
582void
583mac_update_ipq(struct mbuf *fragment, struct ipq *ipq)
584{
585 struct label *label;
586
587 label = mbuf_to_label(fragment);
588
589 MAC_PERFORM(update_ipq, fragment, label, ipq, &ipq->ipq_label);
590}
591
592void
593mac_create_mbuf_from_socket(struct socket *socket, struct mbuf *mbuf)
594{
595 struct label *label;
596
597 label = mbuf_to_label(mbuf);
598
599 MAC_PERFORM(create_mbuf_from_socket, socket, &socket->so_label, mbuf,
600 label);
601}
602
603int
604mac_check_bpfdesc_receive(struct bpf_d *bpf_d, struct ifnet *ifnet)
605{
606 int error;
607
608 if (!mac_enforce_network)
609 return (0);
610
611 MAC_CHECK(check_bpfdesc_receive, bpf_d, &bpf_d->bd_label, ifnet,
612 &ifnet->if_label);
613
614 return (error);
615}
616
617int
618mac_check_ifnet_transmit(struct ifnet *ifnet, struct mbuf *mbuf)
619{
620 struct label *label;
621 int error;
622
623 M_ASSERTPKTHDR(mbuf);
624
625 if (!mac_enforce_network)
626 return (0);
627
628 label = mbuf_to_label(mbuf);
629
630 MAC_CHECK(check_ifnet_transmit, ifnet, &ifnet->if_label, mbuf,
631 label);
632
633 return (error);
634}
635
636int
637mac_check_socket_bind(struct ucred *ucred, struct socket *socket,
638 struct sockaddr *sockaddr)
639{
640 int error;
641
642 if (!mac_enforce_socket)
643 return (0);
644
645 MAC_CHECK(check_socket_bind, ucred, socket, &socket->so_label,
646 sockaddr);
647
648 return (error);
649}
650
651int
652mac_check_socket_connect(struct ucred *cred, struct socket *socket,
653 struct sockaddr *sockaddr)
654{
655 int error;
656
657 if (!mac_enforce_socket)
658 return (0);
659
660 MAC_CHECK(check_socket_connect, cred, socket, &socket->so_label,
661 sockaddr);
662
663 return (error);
664}
665
666int
667mac_check_socket_deliver(struct socket *socket, struct mbuf *mbuf)
668{
669 struct label *label;
670 int error;
671
672 if (!mac_enforce_socket)
673 return (0);
674
675 label = mbuf_to_label(mbuf);
676
677 MAC_CHECK(check_socket_deliver, socket, &socket->so_label, mbuf,
678 label);
679
680 return (error);
681}
682
683int
684mac_check_socket_listen(struct ucred *cred, struct socket *socket)
685{
686 int error;
687
688 if (!mac_enforce_socket)
689 return (0);
690
691 MAC_CHECK(check_socket_listen, cred, socket, &socket->so_label);
692 return (error);
693}
694
695int
696mac_check_socket_receive(struct ucred *cred, struct socket *so)
697{
698 int error;
699
700 if (!mac_enforce_socket)
701 return (0);
702
703 MAC_CHECK(check_socket_receive, cred, so, &so->so_label);
704
705 return (error);
706}
707
708static int
709mac_check_socket_relabel(struct ucred *cred, struct socket *socket,
710 struct label *newlabel)
711{
712 int error;
713
714 MAC_CHECK(check_socket_relabel, cred, socket, &socket->so_label,
715 newlabel);
716
717 return (error);
718}
719
720int
721mac_check_socket_send(struct ucred *cred, struct socket *so)
722{
723 int error;
724
725 if (!mac_enforce_socket)
726 return (0);
727
728 MAC_CHECK(check_socket_send, cred, so, &so->so_label);
729
730 return (error);
731}
732
733int
734mac_check_socket_visible(struct ucred *cred, struct socket *socket)
735{
736 int error;
737
738 if (!mac_enforce_socket)
739 return (0);
740
741 MAC_CHECK(check_socket_visible, cred, socket, &socket->so_label);
742
743 return (error);
744}
745
746int
747mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
748 struct ifnet *ifnet)
749{
750 char *elements, *buffer;
751 struct mac mac;
752 int error;
753
754 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
755 if (error)
756 return (error);
757
758 error = mac_check_structmac_consistent(&mac);
759 if (error)
760 return (error);
761
762 elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
763 error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
764 if (error) {
765 free(elements, M_MACTEMP);
766 return (error);
767 }
768
769 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
770 error = mac_externalize_ifnet_label(&ifnet->if_label, elements,
771 buffer, mac.m_buflen, M_WAITOK);
771 buffer, mac.m_buflen);
772 if (error == 0)
773 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
774
775 free(buffer, M_MACTEMP);
776 free(elements, M_MACTEMP);
777
778 return (error);
779}
780
781int
782mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
783 struct ifnet *ifnet)
784{
785 struct label intlabel;
786 struct mac mac;
787 char *buffer;
788 int error;
789
790 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
791 if (error)
792 return (error);
793
794 error = mac_check_structmac_consistent(&mac);
795 if (error)
796 return (error);
797
798 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
799 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
800 if (error) {
801 free(buffer, M_MACTEMP);
802 return (error);
803 }
804
805 mac_init_ifnet_label(&intlabel);
806 error = mac_internalize_ifnet_label(&intlabel, buffer);
807 free(buffer, M_MACTEMP);
808 if (error) {
809 mac_destroy_ifnet_label(&intlabel);
810 return (error);
811 }
812
813 /*
814 * XXX: Note that this is a redundant privilege check, since
815 * policies impose this check themselves if required by the
816 * policy. Eventually, this should go away.
817 */
818 error = suser_cred(cred, 0);
819 if (error) {
820 mac_destroy_ifnet_label(&intlabel);
821 return (error);
822 }
823
824 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
825 &intlabel);
826 if (error) {
827 mac_destroy_ifnet_label(&intlabel);
828 return (error);
829 }
830
831 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
832
833 mac_destroy_ifnet_label(&intlabel);
834 return (0);
835}
836
837int
838mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
839 struct mac *mac)
840{
841 struct label intlabel;
842 char *buffer;
843 int error;
844
845 error = mac_check_structmac_consistent(mac);
846 if (error)
847 return (error);
848
849 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
850 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
851 if (error) {
852 free(buffer, M_MACTEMP);
853 return (error);
854 }
855
856 mac_init_socket_label(&intlabel, M_WAITOK);
857 error = mac_internalize_socket_label(&intlabel, buffer);
858 free(buffer, M_MACTEMP);
859 if (error) {
860 mac_destroy_socket_label(&intlabel);
861 return (error);
862 }
863
864 mac_check_socket_relabel(cred, so, &intlabel);
865 if (error) {
866 mac_destroy_socket_label(&intlabel);
867 return (error);
868 }
869
870 mac_relabel_socket(cred, so, &intlabel);
871
872 mac_destroy_socket_label(&intlabel);
873 return (0);
874}
875
876int
877mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
878 struct mac *mac)
879{
880 char *buffer, *elements;
881 int error;
882
883 error = mac_check_structmac_consistent(mac);
884 if (error)
885 return (error);
886
887 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
888 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
889 if (error) {
890 free(elements, M_MACTEMP);
891 return (error);
892 }
893
894 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
895 error = mac_externalize_socket_label(&so->so_label, elements,
772 if (error == 0)
773 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
774
775 free(buffer, M_MACTEMP);
776 free(elements, M_MACTEMP);
777
778 return (error);
779}
780
781int
782mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr,
783 struct ifnet *ifnet)
784{
785 struct label intlabel;
786 struct mac mac;
787 char *buffer;
788 int error;
789
790 error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
791 if (error)
792 return (error);
793
794 error = mac_check_structmac_consistent(&mac);
795 if (error)
796 return (error);
797
798 buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
799 error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
800 if (error) {
801 free(buffer, M_MACTEMP);
802 return (error);
803 }
804
805 mac_init_ifnet_label(&intlabel);
806 error = mac_internalize_ifnet_label(&intlabel, buffer);
807 free(buffer, M_MACTEMP);
808 if (error) {
809 mac_destroy_ifnet_label(&intlabel);
810 return (error);
811 }
812
813 /*
814 * XXX: Note that this is a redundant privilege check, since
815 * policies impose this check themselves if required by the
816 * policy. Eventually, this should go away.
817 */
818 error = suser_cred(cred, 0);
819 if (error) {
820 mac_destroy_ifnet_label(&intlabel);
821 return (error);
822 }
823
824 MAC_CHECK(check_ifnet_relabel, cred, ifnet, &ifnet->if_label,
825 &intlabel);
826 if (error) {
827 mac_destroy_ifnet_label(&intlabel);
828 return (error);
829 }
830
831 MAC_PERFORM(relabel_ifnet, cred, ifnet, &ifnet->if_label, &intlabel);
832
833 mac_destroy_ifnet_label(&intlabel);
834 return (0);
835}
836
837int
838mac_setsockopt_label_set(struct ucred *cred, struct socket *so,
839 struct mac *mac)
840{
841 struct label intlabel;
842 char *buffer;
843 int error;
844
845 error = mac_check_structmac_consistent(mac);
846 if (error)
847 return (error);
848
849 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
850 error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
851 if (error) {
852 free(buffer, M_MACTEMP);
853 return (error);
854 }
855
856 mac_init_socket_label(&intlabel, M_WAITOK);
857 error = mac_internalize_socket_label(&intlabel, buffer);
858 free(buffer, M_MACTEMP);
859 if (error) {
860 mac_destroy_socket_label(&intlabel);
861 return (error);
862 }
863
864 mac_check_socket_relabel(cred, so, &intlabel);
865 if (error) {
866 mac_destroy_socket_label(&intlabel);
867 return (error);
868 }
869
870 mac_relabel_socket(cred, so, &intlabel);
871
872 mac_destroy_socket_label(&intlabel);
873 return (0);
874}
875
876int
877mac_getsockopt_label_get(struct ucred *cred, struct socket *so,
878 struct mac *mac)
879{
880 char *buffer, *elements;
881 int error;
882
883 error = mac_check_structmac_consistent(mac);
884 if (error)
885 return (error);
886
887 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
888 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
889 if (error) {
890 free(elements, M_MACTEMP);
891 return (error);
892 }
893
894 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
895 error = mac_externalize_socket_label(&so->so_label, elements,
896 buffer, mac->m_buflen, M_WAITOK);
896 buffer, mac->m_buflen);
897 if (error == 0)
898 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
899
900 free(buffer, M_MACTEMP);
901 free(elements, M_MACTEMP);
902
903 return (error);
904}
905
906int
907mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
908 struct mac *mac)
909{
910 char *elements, *buffer;
911 int error;
912
913 error = mac_check_structmac_consistent(mac);
914 if (error)
915 return (error);
916
917 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
918 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
919 if (error) {
920 free(elements, M_MACTEMP);
921 return (error);
922 }
923
924 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
925 error = mac_externalize_socket_peer_label(&so->so_peerlabel,
897 if (error == 0)
898 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
899
900 free(buffer, M_MACTEMP);
901 free(elements, M_MACTEMP);
902
903 return (error);
904}
905
906int
907mac_getsockopt_peerlabel_get(struct ucred *cred, struct socket *so,
908 struct mac *mac)
909{
910 char *elements, *buffer;
911 int error;
912
913 error = mac_check_structmac_consistent(mac);
914 if (error)
915 return (error);
916
917 elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
918 error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
919 if (error) {
920 free(elements, M_MACTEMP);
921 return (error);
922 }
923
924 buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
925 error = mac_externalize_socket_peer_label(&so->so_peerlabel,
926 elements, buffer, mac->m_buflen, M_WAITOK);
926 elements, buffer, mac->m_buflen);
927 if (error == 0)
928 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
929
930 free(buffer, M_MACTEMP);
931 free(elements, M_MACTEMP);
932
933 return (error);
934}
927 if (error == 0)
928 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
929
930 free(buffer, M_MACTEMP);
931 free(elements, M_MACTEMP);
932
933 return (error);
934}