1b9b0dac3SRobert Watson /*-
240202729SRobert Watson * Copyright (c) 2007-2009 Robert N. M. Watson
3b9b0dac3SRobert Watson * All rights reserved.
4b9b0dac3SRobert Watson *
5b9b0dac3SRobert Watson * This software was developed by Robert Watson for the TrustedBSD Project.
6b9b0dac3SRobert Watson *
740202729SRobert Watson * This software was developed at the University of Cambridge Computer
840202729SRobert Watson * Laboratory with support from a grant from Google, Inc.
940202729SRobert Watson *
10b9b0dac3SRobert Watson * Redistribution and use in source and binary forms, with or without
11b9b0dac3SRobert Watson * modification, are permitted provided that the following conditions
12b9b0dac3SRobert Watson * are met:
13b9b0dac3SRobert Watson * 1. Redistributions of source code must retain the above copyright
14b9b0dac3SRobert Watson * notice, this list of conditions and the following disclaimer.
15b9b0dac3SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright
16b9b0dac3SRobert Watson * notice, this list of conditions and the following disclaimer in the
17b9b0dac3SRobert Watson * documentation and/or other materials provided with the distribution.
18b9b0dac3SRobert Watson *
19b9b0dac3SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20b9b0dac3SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21b9b0dac3SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22b9b0dac3SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23b9b0dac3SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24b9b0dac3SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25b9b0dac3SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26b9b0dac3SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27b9b0dac3SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28b9b0dac3SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29b9b0dac3SRobert Watson * SUCH DAMAGE.
30b9b0dac3SRobert Watson */
31b9b0dac3SRobert Watson
32b9b0dac3SRobert Watson #include <sys/cdefs.h>
33b9b0dac3SRobert Watson #include "opt_mac.h"
34b9b0dac3SRobert Watson
35b9b0dac3SRobert Watson #include <sys/param.h>
36b9b0dac3SRobert Watson #include <sys/kernel.h>
37b9b0dac3SRobert Watson #include <sys/lock.h>
38b9b0dac3SRobert Watson #include <sys/malloc.h>
39b9b0dac3SRobert Watson #include <sys/mutex.h>
40b9b0dac3SRobert Watson #include <sys/sbuf.h>
41b9b0dac3SRobert Watson #include <sys/systm.h>
42b9b0dac3SRobert Watson #include <sys/mount.h>
43b9b0dac3SRobert Watson #include <sys/file.h>
44b9b0dac3SRobert Watson #include <sys/namei.h>
45b9b0dac3SRobert Watson #include <sys/protosw.h>
46b9b0dac3SRobert Watson #include <sys/socket.h>
47b9b0dac3SRobert Watson #include <sys/socketvar.h>
48b9b0dac3SRobert Watson #include <sys/sysctl.h>
49b9b0dac3SRobert Watson
50b9b0dac3SRobert Watson #include <net/if.h>
51b9b0dac3SRobert Watson #include <net/if_var.h>
52b9b0dac3SRobert Watson
534b908c8bSRobert Watson #include <netinet/in.h>
544b908c8bSRobert Watson #include <netinet/ip6.h>
554b908c8bSRobert Watson #include <netinet6/ip6_var.h>
564b908c8bSRobert Watson
57b9b0dac3SRobert Watson #include <security/mac/mac_framework.h>
58b9b0dac3SRobert Watson #include <security/mac/mac_internal.h>
59b9b0dac3SRobert Watson #include <security/mac/mac_policy.h>
60b9b0dac3SRobert Watson
614b908c8bSRobert Watson static struct label *
mac_ip6q_label_alloc(int flag)624b908c8bSRobert Watson mac_ip6q_label_alloc(int flag)
634b908c8bSRobert Watson {
644b908c8bSRobert Watson struct label *label;
654b908c8bSRobert Watson int error;
664b908c8bSRobert Watson
674b908c8bSRobert Watson label = mac_labelzone_alloc(flag);
684b908c8bSRobert Watson if (label == NULL)
694b908c8bSRobert Watson return (NULL);
704b908c8bSRobert Watson
7140202729SRobert Watson if (flag & M_WAITOK)
72fa765671SRobert Watson MAC_POLICY_CHECK(ip6q_init_label, label, flag);
7340202729SRobert Watson else
74fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(ip6q_init_label, label, flag);
754b908c8bSRobert Watson if (error) {
76fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_destroy_label, label);
774b908c8bSRobert Watson mac_labelzone_free(label);
784b908c8bSRobert Watson return (NULL);
794b908c8bSRobert Watson }
804b908c8bSRobert Watson return (label);
814b908c8bSRobert Watson }
824b908c8bSRobert Watson
834b908c8bSRobert Watson int
mac_ip6q_init(struct ip6q * q6,int flag)844b908c8bSRobert Watson mac_ip6q_init(struct ip6q *q6, int flag)
854b908c8bSRobert Watson {
864b908c8bSRobert Watson
87dbdcb994SRobert Watson if (mac_labeled & MPC_OBJECT_IP6Q) {
884b908c8bSRobert Watson q6->ip6q_label = mac_ip6q_label_alloc(flag);
894b908c8bSRobert Watson if (q6->ip6q_label == NULL)
904b908c8bSRobert Watson return (ENOMEM);
914b908c8bSRobert Watson } else
924b908c8bSRobert Watson q6->ip6q_label = NULL;
934b908c8bSRobert Watson return (0);
944b908c8bSRobert Watson }
954b908c8bSRobert Watson
964b908c8bSRobert Watson static void
mac_ip6q_label_free(struct label * label)974b908c8bSRobert Watson mac_ip6q_label_free(struct label *label)
984b908c8bSRobert Watson {
994b908c8bSRobert Watson
100fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_destroy_label, label);
1014b908c8bSRobert Watson mac_labelzone_free(label);
1024b908c8bSRobert Watson }
1034b908c8bSRobert Watson
1044b908c8bSRobert Watson void
mac_ip6q_destroy(struct ip6q * q6)1054b908c8bSRobert Watson mac_ip6q_destroy(struct ip6q *q6)
1064b908c8bSRobert Watson {
1074b908c8bSRobert Watson
1084b908c8bSRobert Watson if (q6->ip6q_label != NULL) {
1094b908c8bSRobert Watson mac_ip6q_label_free(q6->ip6q_label);
1104b908c8bSRobert Watson q6->ip6q_label = NULL;
1114b908c8bSRobert Watson }
1124b908c8bSRobert Watson }
1134b908c8bSRobert Watson
1144b908c8bSRobert Watson void
mac_ip6q_reassemble(struct ip6q * q6,struct mbuf * m)1154b908c8bSRobert Watson mac_ip6q_reassemble(struct ip6q *q6, struct mbuf *m)
1164b908c8bSRobert Watson {
1174b908c8bSRobert Watson struct label *label;
1184b908c8bSRobert Watson
1193de40469SRobert Watson if (mac_policy_count == 0)
1203de40469SRobert Watson return;
1213de40469SRobert Watson
1224b908c8bSRobert Watson label = mac_mbuf_to_label(m);
1234b908c8bSRobert Watson
124fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_reassemble, q6, q6->ip6q_label, m,
125fa765671SRobert Watson label);
1264b908c8bSRobert Watson }
1274b908c8bSRobert Watson
1284b908c8bSRobert Watson void
mac_ip6q_create(struct mbuf * m,struct ip6q * q6)1294b908c8bSRobert Watson mac_ip6q_create(struct mbuf *m, struct ip6q *q6)
1304b908c8bSRobert Watson {
1314b908c8bSRobert Watson struct label *label;
1324b908c8bSRobert Watson
1333de40469SRobert Watson if (mac_policy_count == 0)
1343de40469SRobert Watson return;
1353de40469SRobert Watson
1364b908c8bSRobert Watson label = mac_mbuf_to_label(m);
1374b908c8bSRobert Watson
138fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_create, m, label, q6,
139fa765671SRobert Watson q6->ip6q_label);
1404b908c8bSRobert Watson }
1414b908c8bSRobert Watson
1424b908c8bSRobert Watson int
mac_ip6q_match(struct mbuf * m,struct ip6q * q6)1434b908c8bSRobert Watson mac_ip6q_match(struct mbuf *m, struct ip6q *q6)
1444b908c8bSRobert Watson {
1454b908c8bSRobert Watson struct label *label;
1464b908c8bSRobert Watson int result;
1474b908c8bSRobert Watson
1483de40469SRobert Watson if (mac_policy_count == 0)
1493de40469SRobert Watson return (1);
1503de40469SRobert Watson
1514b908c8bSRobert Watson label = mac_mbuf_to_label(m);
1524b908c8bSRobert Watson
1534b908c8bSRobert Watson result = 1;
154fa765671SRobert Watson MAC_POLICY_BOOLEAN_NOSLEEP(ip6q_match, &&, m, label, q6,
155fa765671SRobert Watson q6->ip6q_label);
1564b908c8bSRobert Watson
1574b908c8bSRobert Watson return (result);
1584b908c8bSRobert Watson }
1594b908c8bSRobert Watson
1604b908c8bSRobert Watson void
mac_ip6q_update(struct mbuf * m,struct ip6q * q6)1614b908c8bSRobert Watson mac_ip6q_update(struct mbuf *m, struct ip6q *q6)
1624b908c8bSRobert Watson {
1634b908c8bSRobert Watson struct label *label;
1644b908c8bSRobert Watson
1653de40469SRobert Watson if (mac_policy_count == 0)
1663de40469SRobert Watson return;
1673de40469SRobert Watson
1684b908c8bSRobert Watson label = mac_mbuf_to_label(m);
1694b908c8bSRobert Watson
170fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_update, m, label, q6,
171fa765671SRobert Watson q6->ip6q_label);
1724b908c8bSRobert Watson }
1734b908c8bSRobert Watson
174*215bab79SShivank Garg /* Check with rules in module if the IPv6 address is allowed. */
175*215bab79SShivank Garg int
mac_inet6_check_add_addr(struct ucred * cred,const struct in6_addr * ia6,struct ifnet * ifp)176*215bab79SShivank Garg mac_inet6_check_add_addr(struct ucred *cred, const struct in6_addr *ia6,
177*215bab79SShivank Garg struct ifnet *ifp)
178*215bab79SShivank Garg {
179*215bab79SShivank Garg int error;
180*215bab79SShivank Garg
181*215bab79SShivank Garg MAC_POLICY_CHECK(ip6_check_jail, cred, ia6, ifp);
182*215bab79SShivank Garg return (error);
183*215bab79SShivank Garg }
184*215bab79SShivank Garg
185b9b0dac3SRobert Watson void
mac_netinet6_nd6_send(struct ifnet * ifp,struct mbuf * m)186b9b0dac3SRobert Watson mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m)
187b9b0dac3SRobert Watson {
188b9b0dac3SRobert Watson struct label *mlabel;
189b9b0dac3SRobert Watson
1903de40469SRobert Watson if (mac_policy_count == 0)
1913de40469SRobert Watson return;
1923de40469SRobert Watson
193b9b0dac3SRobert Watson mlabel = mac_mbuf_to_label(m);
194b9b0dac3SRobert Watson
19530af2c13SJustin Hibbits MAC_POLICY_PERFORM_NOSLEEP(netinet6_nd6_send, ifp, if_getmaclabel(ifp), m,
19640202729SRobert Watson mlabel);
197b9b0dac3SRobert Watson }
198