1/* 2 * Copyright (c) 2007-2011 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/*- 29 * Copyright (c) 1999-2002 Robert N. M. Watson 30 * Copyright (c) 2001 Ilmar S. Habibulin 31 * Copyright (c) 2001-2004 Networks Associates Technology, Inc. 32 * Copyright (c) 2006-2007 SPARTA, Inc. 33 * All rights reserved. 34 * 35 * This software was developed by Robert Watson and Ilmar Habibulin for the 36 * TrustedBSD Project. 37 * 38 * This software was developed for the FreeBSD Project in part by Network 39 * Associates Laboratories, the Security Research Division of Network 40 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), 41 * as part of the DARPA CHATS research program. 42 * 43 * This software was enhanced by SPARTA ISSO under SPAWAR contract 44 * N66001-04-C-6019 ("SEFOS"). 45 * 46 * Redistribution and use in source and binary forms, with or without 47 * modification, are permitted provided that the following conditions 48 * are met: 49 * 1. Redistributions of source code must retain the above copyright 50 * notice, this list of conditions and the following disclaimer. 51 * 2. Redistributions in binary form must reproduce the above copyright 52 * notice, this list of conditions and the following disclaimer in the 53 * documentation and/or other materials provided with the distribution. 54 * 55 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 58 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 65 * SUCH DAMAGE. 66 */ 67 68#include <sys/param.h> 69#include <sys/kernel.h> 70#include <sys/mbuf.h> 71#include <sys/socket.h> 72#include <sys/socketvar.h> 73 74#include <net/route.h> 75 76#include <netinet/in.h> 77#include <netinet/in_pcb.h> 78#include <netinet/ip_var.h> 79 80#include <security/mac_internal.h> 81 82static struct label * 83mac_inpcb_label_alloc(int flag) 84{ 85 struct label *label; 86 int error; 87 88 label = mac_labelzone_alloc(flag); 89 if (label == NULL) 90 return (NULL); 91 MAC_CHECK(inpcb_label_init, label, flag); 92 if (error) { 93 MAC_PERFORM(inpcb_label_destroy, label); 94 mac_labelzone_free(label); 95 return (NULL); 96 } 97 return (label); 98} 99 100int 101mac_inpcb_label_init(struct inpcb *inp, int flag) 102{ 103 104 inp->inp_label = mac_inpcb_label_alloc(flag); 105 if (inp->inp_label == NULL) 106 return (ENOMEM); 107 return (0); 108} 109 110static struct label * 111mac_ipq_label_alloc(int flag) 112{ 113 struct label *label; 114 int error; 115 116 label = mac_labelzone_alloc(flag); 117 if (label == NULL) 118 return (NULL); 119 120 MAC_CHECK(ipq_label_init, label, flag); 121 if (error) { 122 MAC_PERFORM(ipq_label_destroy, label); 123 mac_labelzone_free(label); 124 return (NULL); 125 } 126 return (label); 127} 128 129int 130mac_ipq_label_init(struct ipq *ipq, int flag) 131{ 132 133 ipq->ipq_label = mac_ipq_label_alloc(flag); 134 if (ipq->ipq_label == NULL) 135 return (ENOMEM); 136 return (0); 137} 138 139static void 140mac_inpcb_label_free(struct label *label) 141{ 142 143 MAC_PERFORM(inpcb_label_destroy, label); 144 mac_labelzone_free(label); 145} 146 147void 148mac_inpcb_label_destroy(struct inpcb *inp) 149{ 150 151 mac_inpcb_label_free(inp->inp_label); 152 inp->inp_label = NULL; 153} 154 155void 156mac_inpcb_label_recycle(struct inpcb *inp) 157{ 158 159 MAC_PERFORM(inpcb_label_recycle, inp->inp_label); 160} 161 162static void 163mac_ipq_label_free(struct label *label) 164{ 165 166 MAC_PERFORM(ipq_label_destroy, label); 167 mac_labelzone_free(label); 168} 169 170void 171mac_ipq_label_destroy(struct ipq *ipq) 172{ 173 174 mac_ipq_label_free(ipq->ipq_label); 175 ipq->ipq_label = NULL; 176} 177 178void 179mac_inpcb_label_associate(struct socket *so, struct inpcb *inp) 180{ 181 182 MAC_PERFORM(inpcb_label_associate, so, so->so_label, inp, 183 inp->inp_label); 184} 185 186void 187mac_mbuf_label_associate_ipq(struct ipq *ipq, struct mbuf *m) 188{ 189 struct label *label; 190 191 label = mac_mbuf_to_label(m); 192 193 MAC_PERFORM(mbuf_label_associate_ipq, ipq, ipq->ipq_label, m, label); 194} 195 196void 197mac_netinet_fragment(struct mbuf *datagram, struct mbuf *fragment) 198{ 199 struct label *datagramlabel, *fragmentlabel; 200 201 datagramlabel = mac_mbuf_to_label(datagram); 202 fragmentlabel = mac_mbuf_to_label(fragment); 203 204 MAC_PERFORM(netinet_fragment, datagram, datagramlabel, fragment, 205 fragmentlabel); 206} 207 208void 209mac_ipq_label_associate(struct mbuf *fragment, struct ipq *ipq) 210{ 211 struct label *label; 212 213 label = mac_mbuf_to_label(fragment); 214 215 MAC_PERFORM(ipq_label_associate, fragment, label, ipq, ipq->ipq_label); 216} 217 218void 219mac_mbuf_label_associate_inpcb(struct inpcb *inp, struct mbuf *m) 220{ 221 struct label *mlabel; 222 223 /* INP_LOCK_ASSERT(inp); */ 224 mlabel = mac_mbuf_to_label(m); 225 226 MAC_PERFORM(mbuf_label_associate_inpcb, inp, inp->inp_label, m, mlabel); 227} 228 229int 230mac_ipq_label_compare(struct mbuf *fragment, struct ipq *ipq) 231{ 232 struct label *label; 233 int result; 234 235 label = mac_mbuf_to_label(fragment); 236 237 result = 1; 238 MAC_BOOLEAN(ipq_label_compare, &&, fragment, label, ipq, ipq->ipq_label); 239 240 return (result); 241} 242 243void 244mac_netinet_icmp_reply(struct mbuf *m) 245{ 246 struct label *label; 247 248 label = mac_mbuf_to_label(m); 249 250 MAC_PERFORM(netinet_icmp_reply, m, label); 251} 252 253void 254mac_netinet_tcp_reply(struct mbuf *m) 255{ 256 struct label *label; 257 258 label = mac_mbuf_to_label(m); 259 260 MAC_PERFORM(netinet_tcp_reply, m, label); 261} 262 263void 264mac_ipq_label_update(struct mbuf *fragment, struct ipq *ipq) 265{ 266 struct label *label; 267 268 label = mac_mbuf_to_label(fragment); 269 270 MAC_PERFORM(ipq_label_update, fragment, label, ipq, ipq->ipq_label); 271} 272 273int 274mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m, int family, int type) 275{ 276 struct label *label; 277 int error; 278 279 if ((m->m_flags & M_PKTHDR) == 0) 280 panic("%s: no mbuf packet header!", __func__); 281 282 label = mac_mbuf_to_label(m); 283 284 MAC_CHECK(inpcb_check_deliver, inp, inp->inp_label, m, label, 285 family, type); 286 287 return (error); 288} 289 290/* 291 * Propagate a change in the socket label to the inpcb label. 292 */ 293void 294mac_inpcb_label_update(struct socket *so) 295{ 296 struct inpcb *inp; 297 298 /* XXX: assert socket lock. */ 299 inp = sotoinpcb(so); /* XXX: inp locking */ 300 301 if (inp != NULL) { 302 /* INP_LOCK_ASSERT(inp); */ 303 MAC_PERFORM(inpcb_label_update, so, so->so_label, inp, 304 inp->inp_label); 305 } 306} 307