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 __FBSDID("$FreeBSD$"); 34b9b0dac3SRobert Watson 35b9b0dac3SRobert Watson #include "opt_mac.h" 36b9b0dac3SRobert Watson 37b9b0dac3SRobert Watson #include <sys/param.h> 38b9b0dac3SRobert Watson #include <sys/kernel.h> 39b9b0dac3SRobert Watson #include <sys/lock.h> 40b9b0dac3SRobert Watson #include <sys/malloc.h> 41b9b0dac3SRobert Watson #include <sys/mutex.h> 42b9b0dac3SRobert Watson #include <sys/sbuf.h> 43b9b0dac3SRobert Watson #include <sys/systm.h> 44b9b0dac3SRobert Watson #include <sys/mount.h> 45b9b0dac3SRobert Watson #include <sys/file.h> 46b9b0dac3SRobert Watson #include <sys/namei.h> 47b9b0dac3SRobert Watson #include <sys/protosw.h> 48b9b0dac3SRobert Watson #include <sys/socket.h> 49b9b0dac3SRobert Watson #include <sys/socketvar.h> 50b9b0dac3SRobert Watson #include <sys/sysctl.h> 51b9b0dac3SRobert Watson 52b9b0dac3SRobert Watson #include <net/if.h> 53b9b0dac3SRobert Watson #include <net/if_var.h> 54b9b0dac3SRobert Watson 554b908c8bSRobert Watson #include <netinet/in.h> 564b908c8bSRobert Watson #include <netinet/ip6.h> 574b908c8bSRobert Watson #include <netinet6/ip6_var.h> 584b908c8bSRobert Watson 59b9b0dac3SRobert Watson #include <security/mac/mac_framework.h> 60b9b0dac3SRobert Watson #include <security/mac/mac_internal.h> 61b9b0dac3SRobert Watson #include <security/mac/mac_policy.h> 62b9b0dac3SRobert Watson 634b908c8bSRobert Watson static struct label * 644b908c8bSRobert Watson mac_ip6q_label_alloc(int flag) 654b908c8bSRobert Watson { 664b908c8bSRobert Watson struct label *label; 674b908c8bSRobert Watson int error; 684b908c8bSRobert Watson 694b908c8bSRobert Watson label = mac_labelzone_alloc(flag); 704b908c8bSRobert Watson if (label == NULL) 714b908c8bSRobert Watson return (NULL); 724b908c8bSRobert Watson 7340202729SRobert Watson if (flag & M_WAITOK) 74fa765671SRobert Watson MAC_POLICY_CHECK(ip6q_init_label, label, flag); 7540202729SRobert Watson else 76fa765671SRobert Watson MAC_POLICY_CHECK_NOSLEEP(ip6q_init_label, label, flag); 774b908c8bSRobert Watson if (error) { 78fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_destroy_label, label); 794b908c8bSRobert Watson mac_labelzone_free(label); 804b908c8bSRobert Watson return (NULL); 814b908c8bSRobert Watson } 824b908c8bSRobert Watson return (label); 834b908c8bSRobert Watson } 844b908c8bSRobert Watson 854b908c8bSRobert Watson int 864b908c8bSRobert Watson mac_ip6q_init(struct ip6q *q6, int flag) 874b908c8bSRobert Watson { 884b908c8bSRobert Watson 89dbdcb994SRobert Watson if (mac_labeled & MPC_OBJECT_IP6Q) { 904b908c8bSRobert Watson q6->ip6q_label = mac_ip6q_label_alloc(flag); 914b908c8bSRobert Watson if (q6->ip6q_label == NULL) 924b908c8bSRobert Watson return (ENOMEM); 934b908c8bSRobert Watson } else 944b908c8bSRobert Watson q6->ip6q_label = NULL; 954b908c8bSRobert Watson return (0); 964b908c8bSRobert Watson } 974b908c8bSRobert Watson 984b908c8bSRobert Watson static void 994b908c8bSRobert Watson mac_ip6q_label_free(struct label *label) 1004b908c8bSRobert Watson { 1014b908c8bSRobert Watson 102fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_destroy_label, label); 1034b908c8bSRobert Watson mac_labelzone_free(label); 1044b908c8bSRobert Watson } 1054b908c8bSRobert Watson 1064b908c8bSRobert Watson void 1074b908c8bSRobert Watson mac_ip6q_destroy(struct ip6q *q6) 1084b908c8bSRobert Watson { 1094b908c8bSRobert Watson 1104b908c8bSRobert Watson if (q6->ip6q_label != NULL) { 1114b908c8bSRobert Watson mac_ip6q_label_free(q6->ip6q_label); 1124b908c8bSRobert Watson q6->ip6q_label = NULL; 1134b908c8bSRobert Watson } 1144b908c8bSRobert Watson } 1154b908c8bSRobert Watson 1164b908c8bSRobert Watson void 1174b908c8bSRobert Watson mac_ip6q_reassemble(struct ip6q *q6, struct mbuf *m) 1184b908c8bSRobert Watson { 1194b908c8bSRobert Watson struct label *label; 1204b908c8bSRobert Watson 1213de40469SRobert Watson if (mac_policy_count == 0) 1223de40469SRobert Watson return; 1233de40469SRobert Watson 1244b908c8bSRobert Watson label = mac_mbuf_to_label(m); 1254b908c8bSRobert Watson 126fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_reassemble, q6, q6->ip6q_label, m, 127fa765671SRobert Watson label); 1284b908c8bSRobert Watson } 1294b908c8bSRobert Watson 1304b908c8bSRobert Watson void 1314b908c8bSRobert Watson mac_ip6q_create(struct mbuf *m, struct ip6q *q6) 1324b908c8bSRobert Watson { 1334b908c8bSRobert Watson struct label *label; 1344b908c8bSRobert Watson 1353de40469SRobert Watson if (mac_policy_count == 0) 1363de40469SRobert Watson return; 1373de40469SRobert Watson 1384b908c8bSRobert Watson label = mac_mbuf_to_label(m); 1394b908c8bSRobert Watson 140fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_create, m, label, q6, 141fa765671SRobert Watson q6->ip6q_label); 1424b908c8bSRobert Watson } 1434b908c8bSRobert Watson 1444b908c8bSRobert Watson int 1454b908c8bSRobert Watson mac_ip6q_match(struct mbuf *m, struct ip6q *q6) 1464b908c8bSRobert Watson { 1474b908c8bSRobert Watson struct label *label; 1484b908c8bSRobert Watson int result; 1494b908c8bSRobert Watson 1503de40469SRobert Watson if (mac_policy_count == 0) 1513de40469SRobert Watson return (1); 1523de40469SRobert Watson 1534b908c8bSRobert Watson label = mac_mbuf_to_label(m); 1544b908c8bSRobert Watson 1554b908c8bSRobert Watson result = 1; 156fa765671SRobert Watson MAC_POLICY_BOOLEAN_NOSLEEP(ip6q_match, &&, m, label, q6, 157fa765671SRobert Watson q6->ip6q_label); 1584b908c8bSRobert Watson 1594b908c8bSRobert Watson return (result); 1604b908c8bSRobert Watson } 1614b908c8bSRobert Watson 1624b908c8bSRobert Watson void 1634b908c8bSRobert Watson mac_ip6q_update(struct mbuf *m, struct ip6q *q6) 1644b908c8bSRobert Watson { 1654b908c8bSRobert Watson struct label *label; 1664b908c8bSRobert Watson 1673de40469SRobert Watson if (mac_policy_count == 0) 1683de40469SRobert Watson return; 1693de40469SRobert Watson 1704b908c8bSRobert Watson label = mac_mbuf_to_label(m); 1714b908c8bSRobert Watson 172fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(ip6q_update, m, label, q6, 173fa765671SRobert Watson q6->ip6q_label); 1744b908c8bSRobert Watson } 1754b908c8bSRobert Watson 176b9b0dac3SRobert Watson void 177b9b0dac3SRobert Watson mac_netinet6_nd6_send(struct ifnet *ifp, struct mbuf *m) 178b9b0dac3SRobert Watson { 179b9b0dac3SRobert Watson struct label *mlabel; 180b9b0dac3SRobert Watson 1813de40469SRobert Watson if (mac_policy_count == 0) 1823de40469SRobert Watson return; 1833de40469SRobert Watson 184b9b0dac3SRobert Watson mlabel = mac_mbuf_to_label(m); 185b9b0dac3SRobert Watson 186fa765671SRobert Watson MAC_POLICY_PERFORM_NOSLEEP(netinet6_nd6_send, ifp, ifp->if_label, m, 18740202729SRobert Watson mlabel); 188b9b0dac3SRobert Watson } 189