The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/security/mac/mac_inet.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999-2002, 2007, 2009 Robert N. M. Watson
    3  * Copyright (c) 2001 Ilmar S. Habibulin
    4  * Copyright (c) 2001-2004 Networks Associates Technology, Inc.
    5  * Copyright (c) 2006 SPARTA, Inc.
    6  * Copyright (c) 2008 Apple Inc.
    7  * All rights reserved.
    8  *
    9  * This software was developed by Robert Watson and Ilmar Habibulin for the
   10  * TrustedBSD Project.
   11  *
   12  * This software was developed for the FreeBSD Project in part by Network
   13  * Associates Laboratories, the Security Research Division of Network
   14  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
   15  * as part of the DARPA CHATS research program.
   16  *
   17  * This software was enhanced by SPARTA ISSO under SPAWAR contract
   18  * N66001-04-C-6019 ("SEFOS").
   19  *
   20  * This software was developed at the University of Cambridge Computer
   21  * Laboratory with support from a grant from Google, Inc. 
   22  *
   23  * Redistribution and use in source and binary forms, with or without
   24  * modification, are permitted provided that the following conditions
   25  * are met:
   26  * 1. Redistributions of source code must retain the above copyright
   27  *    notice, this list of conditions and the following disclaimer.
   28  * 2. Redistributions in binary form must reproduce the above copyright
   29  *    notice, this list of conditions and the following disclaimer in the
   30  *    documentation and/or other materials provided with the distribution.
   31  *
   32  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   33  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   35  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   36  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   40  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   41  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   42  * SUCH DAMAGE.
   43  */
   44 
   45 #include <sys/cdefs.h>
   46 __FBSDID("$FreeBSD: releng/11.0/sys/security/mac/mac_inet.c 258541 2013-11-25 07:38:45Z attilio $");
   47 
   48 #include "opt_mac.h"
   49 
   50 #include <sys/param.h>
   51 #include <sys/kernel.h>
   52 #include <sys/lock.h>
   53 #include <sys/malloc.h>
   54 #include <sys/mutex.h>
   55 #include <sys/sbuf.h>
   56 #include <sys/sdt.h>
   57 #include <sys/systm.h>
   58 #include <sys/mount.h>
   59 #include <sys/file.h>
   60 #include <sys/namei.h>
   61 #include <sys/protosw.h>
   62 #include <sys/socket.h>
   63 #include <sys/socketvar.h>
   64 #include <sys/sysctl.h>
   65 
   66 #include <net/if.h>
   67 #include <net/if_var.h>
   68 
   69 #include <netinet/in.h>
   70 #include <netinet/in_pcb.h>
   71 #include <netinet/ip_var.h>
   72 
   73 #include <security/mac/mac_framework.h>
   74 #include <security/mac/mac_internal.h>
   75 #include <security/mac/mac_policy.h>
   76 
   77 static struct label *
   78 mac_inpcb_label_alloc(int flag)
   79 {
   80         struct label *label;
   81         int error;
   82 
   83         label = mac_labelzone_alloc(flag);
   84         if (label == NULL)
   85                 return (NULL);
   86         if (flag & M_WAITOK)
   87                 MAC_POLICY_CHECK(inpcb_init_label, label, flag);
   88         else
   89                 MAC_POLICY_CHECK_NOSLEEP(inpcb_init_label, label, flag);
   90         if (error) {
   91                 MAC_POLICY_PERFORM_NOSLEEP(inpcb_destroy_label, label);
   92                 mac_labelzone_free(label);
   93                 return (NULL);
   94         }
   95         return (label);
   96 }
   97 
   98 int
   99 mac_inpcb_init(struct inpcb *inp, int flag)
  100 {
  101 
  102         if (mac_labeled & MPC_OBJECT_INPCB) {
  103                 inp->inp_label = mac_inpcb_label_alloc(flag);
  104                 if (inp->inp_label == NULL)
  105                         return (ENOMEM);
  106         } else
  107                 inp->inp_label = NULL;
  108         return (0);
  109 }
  110 
  111 static struct label *
  112 mac_ipq_label_alloc(int flag)
  113 {
  114         struct label *label;
  115         int error;
  116 
  117         label = mac_labelzone_alloc(flag);
  118         if (label == NULL)
  119                 return (NULL);
  120 
  121         if (flag & M_WAITOK)
  122                 MAC_POLICY_CHECK(ipq_init_label, label, flag);
  123         else
  124                 MAC_POLICY_CHECK_NOSLEEP(ipq_init_label, label, flag);
  125         if (error) {
  126                 MAC_POLICY_PERFORM_NOSLEEP(ipq_destroy_label, label);
  127                 mac_labelzone_free(label);
  128                 return (NULL);
  129         }
  130         return (label);
  131 }
  132 
  133 int
  134 mac_ipq_init(struct ipq *q, int flag)
  135 {
  136 
  137         if (mac_labeled & MPC_OBJECT_IPQ) {
  138                 q->ipq_label = mac_ipq_label_alloc(flag);
  139                 if (q->ipq_label == NULL)
  140                         return (ENOMEM);
  141         } else
  142                 q->ipq_label = NULL;
  143         return (0);
  144 }
  145 
  146 static void
  147 mac_inpcb_label_free(struct label *label)
  148 {
  149 
  150         MAC_POLICY_PERFORM_NOSLEEP(inpcb_destroy_label, label);
  151         mac_labelzone_free(label);
  152 }
  153 
  154 void
  155 mac_inpcb_destroy(struct inpcb *inp)
  156 {
  157 
  158         if (inp->inp_label != NULL) {
  159                 mac_inpcb_label_free(inp->inp_label);
  160                 inp->inp_label = NULL;
  161         }
  162 }
  163 
  164 static void
  165 mac_ipq_label_free(struct label *label)
  166 {
  167 
  168         MAC_POLICY_PERFORM_NOSLEEP(ipq_destroy_label, label);
  169         mac_labelzone_free(label);
  170 }
  171 
  172 void
  173 mac_ipq_destroy(struct ipq *q)
  174 {
  175 
  176         if (q->ipq_label != NULL) {
  177                 mac_ipq_label_free(q->ipq_label);
  178                 q->ipq_label = NULL;
  179         }
  180 }
  181 
  182 void
  183 mac_inpcb_create(struct socket *so, struct inpcb *inp)
  184 {
  185 
  186         MAC_POLICY_PERFORM_NOSLEEP(inpcb_create, so, so->so_label, inp,
  187             inp->inp_label);
  188 }
  189 
  190 void
  191 mac_ipq_reassemble(struct ipq *q, struct mbuf *m)
  192 {
  193         struct label *label;
  194 
  195         if (mac_policy_count == 0)
  196                 return;
  197 
  198         label = mac_mbuf_to_label(m);
  199 
  200         MAC_POLICY_PERFORM_NOSLEEP(ipq_reassemble, q, q->ipq_label, m,
  201             label);
  202 }
  203 
  204 void
  205 mac_netinet_fragment(struct mbuf *m, struct mbuf *frag)
  206 {
  207         struct label *mlabel, *fraglabel;
  208 
  209         if (mac_policy_count == 0)
  210                 return;
  211 
  212         mlabel = mac_mbuf_to_label(m);
  213         fraglabel = mac_mbuf_to_label(frag);
  214 
  215         MAC_POLICY_PERFORM_NOSLEEP(netinet_fragment, m, mlabel, frag,
  216             fraglabel);
  217 }
  218 
  219 void
  220 mac_ipq_create(struct mbuf *m, struct ipq *q)
  221 {
  222         struct label *label;
  223 
  224         if (mac_policy_count == 0)
  225                 return;
  226 
  227         label = mac_mbuf_to_label(m);
  228 
  229         MAC_POLICY_PERFORM_NOSLEEP(ipq_create, m, label, q, q->ipq_label);
  230 }
  231 
  232 void
  233 mac_inpcb_create_mbuf(struct inpcb *inp, struct mbuf *m)
  234 {
  235         struct label *mlabel;
  236 
  237         INP_LOCK_ASSERT(inp);
  238 
  239         if (mac_policy_count == 0)
  240                 return;
  241 
  242         mlabel = mac_mbuf_to_label(m);
  243 
  244         MAC_POLICY_PERFORM_NOSLEEP(inpcb_create_mbuf, inp, inp->inp_label, m,
  245             mlabel);
  246 }
  247 
  248 int
  249 mac_ipq_match(struct mbuf *m, struct ipq *q)
  250 {
  251         struct label *label;
  252         int result;
  253 
  254         if (mac_policy_count == 0)
  255                 return (1);
  256 
  257         label = mac_mbuf_to_label(m);
  258 
  259         result = 1;
  260         MAC_POLICY_BOOLEAN_NOSLEEP(ipq_match, &&, m, label, q, q->ipq_label);
  261 
  262         return (result);
  263 }
  264 
  265 void
  266 mac_netinet_arp_send(struct ifnet *ifp, struct mbuf *m)
  267 {
  268         struct label *mlabel;
  269 
  270         if (mac_policy_count == 0)
  271                 return;
  272 
  273         mlabel = mac_mbuf_to_label(m);
  274 
  275         MAC_IFNET_LOCK(ifp);
  276         MAC_POLICY_PERFORM_NOSLEEP(netinet_arp_send, ifp, ifp->if_label, m,
  277             mlabel);
  278         MAC_IFNET_UNLOCK(ifp);
  279 }
  280 
  281 void
  282 mac_netinet_icmp_reply(struct mbuf *mrecv, struct mbuf *msend)
  283 {
  284         struct label *mrecvlabel, *msendlabel;
  285 
  286         if (mac_policy_count == 0)
  287                 return;
  288 
  289         mrecvlabel = mac_mbuf_to_label(mrecv);
  290         msendlabel = mac_mbuf_to_label(msend);
  291 
  292         MAC_POLICY_PERFORM_NOSLEEP(netinet_icmp_reply, mrecv, mrecvlabel,
  293             msend, msendlabel);
  294 }
  295 
  296 void
  297 mac_netinet_icmp_replyinplace(struct mbuf *m)
  298 {
  299         struct label *label;
  300 
  301         if (mac_policy_count == 0)
  302                 return;
  303 
  304         label = mac_mbuf_to_label(m);
  305 
  306         MAC_POLICY_PERFORM_NOSLEEP(netinet_icmp_replyinplace, m, label);
  307 }
  308 
  309 void
  310 mac_netinet_igmp_send(struct ifnet *ifp, struct mbuf *m)
  311 {
  312         struct label *mlabel;
  313 
  314         if (mac_policy_count == 0)
  315                 return;
  316 
  317         mlabel = mac_mbuf_to_label(m);
  318 
  319         MAC_IFNET_LOCK(ifp);
  320         MAC_POLICY_PERFORM_NOSLEEP(netinet_igmp_send, ifp, ifp->if_label, m,
  321             mlabel);
  322         MAC_IFNET_UNLOCK(ifp);
  323 }
  324 
  325 void
  326 mac_netinet_tcp_reply(struct mbuf *m)
  327 {
  328         struct label *label;
  329 
  330         if (mac_policy_count == 0)
  331                 return;
  332 
  333         label = mac_mbuf_to_label(m);
  334 
  335         MAC_POLICY_PERFORM_NOSLEEP(netinet_tcp_reply, m, label);
  336 }
  337 
  338 void
  339 mac_ipq_update(struct mbuf *m, struct ipq *q)
  340 {
  341         struct label *label;
  342 
  343         if (mac_policy_count == 0)
  344                 return;
  345 
  346         label = mac_mbuf_to_label(m);
  347 
  348         MAC_POLICY_PERFORM_NOSLEEP(ipq_update, m, label, q, q->ipq_label);
  349 }
  350 
  351 MAC_CHECK_PROBE_DEFINE2(inpcb_check_deliver, "struct inpcb *",
  352     "struct mbuf *");
  353 
  354 int
  355 mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m)
  356 {
  357         struct label *label;
  358         int error;
  359 
  360         M_ASSERTPKTHDR(m);
  361 
  362         if (mac_policy_count == 0)
  363                 return (0);
  364 
  365         label = mac_mbuf_to_label(m);
  366 
  367         MAC_POLICY_CHECK_NOSLEEP(inpcb_check_deliver, inp, inp->inp_label, m,
  368             label);
  369         MAC_CHECK_PROBE2(inpcb_check_deliver, error, inp, m);
  370 
  371         return (error);
  372 }
  373 
  374 MAC_CHECK_PROBE_DEFINE2(inpcb_check_visible, "struct ucred *",
  375     "struct inpcb *");
  376 
  377 int
  378 mac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp)
  379 {
  380         int error;
  381 
  382         INP_LOCK_ASSERT(inp);
  383 
  384         MAC_POLICY_CHECK_NOSLEEP(inpcb_check_visible, cred, inp,
  385             inp->inp_label);
  386         MAC_CHECK_PROBE2(inpcb_check_visible, error, cred, inp);
  387 
  388         return (error);
  389 }
  390 
  391 void
  392 mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp)
  393 {
  394 
  395         INP_WLOCK_ASSERT(inp);
  396         SOCK_LOCK_ASSERT(so);
  397 
  398         MAC_POLICY_PERFORM_NOSLEEP(inpcb_sosetlabel, so, so->so_label, inp,
  399             inp->inp_label);
  400 }
  401 
  402 void
  403 mac_netinet_firewall_reply(struct mbuf *mrecv, struct mbuf *msend)
  404 {
  405         struct label *mrecvlabel, *msendlabel;
  406 
  407         M_ASSERTPKTHDR(mrecv);
  408         M_ASSERTPKTHDR(msend);
  409 
  410         if (mac_policy_count == 0)
  411                 return;
  412 
  413         mrecvlabel = mac_mbuf_to_label(mrecv);
  414         msendlabel = mac_mbuf_to_label(msend);
  415 
  416         MAC_POLICY_PERFORM_NOSLEEP(netinet_firewall_reply, mrecv, mrecvlabel,
  417             msend, msendlabel);
  418 }
  419 
  420 void
  421 mac_netinet_firewall_send(struct mbuf *m)
  422 {
  423         struct label *label;
  424 
  425         M_ASSERTPKTHDR(m);
  426 
  427         if (mac_policy_count == 0)
  428                 return;
  429 
  430         label = mac_mbuf_to_label(m);
  431 
  432         MAC_POLICY_PERFORM_NOSLEEP(netinet_firewall_send, m, label);
  433 }
  434 
  435 /*
  436  * These functions really should be referencing the syncache structure
  437  * instead of the label.  However, due to some of the complexities associated
  438  * with exposing this syncache structure we operate directly on it's label
  439  * pointer.  This should be OK since we aren't making any access control
  440  * decisions within this code directly, we are merely allocating and copying
  441  * label storage so we can properly initialize mbuf labels for any packets
  442  * the syncache code might create.
  443  */
  444 void
  445 mac_syncache_destroy(struct label **label)
  446 {
  447 
  448         if (*label != NULL) {
  449                 MAC_POLICY_PERFORM_NOSLEEP(syncache_destroy_label, *label);
  450                 mac_labelzone_free(*label);
  451                 *label = NULL;
  452         }
  453 }
  454 
  455 int
  456 mac_syncache_init(struct label **label)
  457 {
  458         int error;
  459 
  460         if (mac_labeled & MPC_OBJECT_SYNCACHE) {
  461                 *label = mac_labelzone_alloc(M_NOWAIT);
  462                 if (*label == NULL)
  463                         return (ENOMEM);
  464                 /*
  465                  * Since we are holding the inpcb locks the policy can not
  466                  * allocate policy specific label storage using M_WAITOK.  So
  467                  * we need to do a MAC_CHECK instead of the typical
  468                  * MAC_PERFORM so we can propagate allocation failures back
  469                  * to the syncache code.
  470                  */
  471                 MAC_POLICY_CHECK_NOSLEEP(syncache_init_label, *label,
  472                     M_NOWAIT);
  473                 if (error) {
  474                         MAC_POLICY_PERFORM_NOSLEEP(syncache_destroy_label,
  475                             *label);
  476                         mac_labelzone_free(*label);
  477                 }
  478                 return (error);
  479         } else
  480                 *label = NULL;
  481         return (0);
  482 }
  483 
  484 void
  485 mac_syncache_create(struct label *label, struct inpcb *inp)
  486 {
  487 
  488         INP_WLOCK_ASSERT(inp);
  489 
  490         MAC_POLICY_PERFORM_NOSLEEP(syncache_create, label, inp);
  491 }
  492 
  493 void
  494 mac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m)
  495 {
  496         struct label *mlabel;
  497 
  498         M_ASSERTPKTHDR(m);
  499 
  500         if (mac_policy_count == 0)
  501                 return;
  502 
  503         mlabel = mac_mbuf_to_label(m);
  504 
  505         MAC_POLICY_PERFORM_NOSLEEP(syncache_create_mbuf, sc_label, m,
  506             mlabel);
  507 }

Cache object: ed11e6fa7140068d351d615b5858ef58


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.