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, 2019 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$");
   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         int locked;
  270 
  271         if (mac_policy_count == 0)
  272                 return;
  273 
  274         mlabel = mac_mbuf_to_label(m);
  275 
  276         MAC_IFNET_LOCK(ifp, locked);
  277         MAC_POLICY_PERFORM_NOSLEEP(netinet_arp_send, ifp, ifp->if_label, m,
  278             mlabel);
  279         MAC_IFNET_UNLOCK(ifp, locked);
  280 }
  281 
  282 void
  283 mac_netinet_icmp_reply(struct mbuf *mrecv, struct mbuf *msend)
  284 {
  285         struct label *mrecvlabel, *msendlabel;
  286 
  287         if (mac_policy_count == 0)
  288                 return;
  289 
  290         mrecvlabel = mac_mbuf_to_label(mrecv);
  291         msendlabel = mac_mbuf_to_label(msend);
  292 
  293         MAC_POLICY_PERFORM_NOSLEEP(netinet_icmp_reply, mrecv, mrecvlabel,
  294             msend, msendlabel);
  295 }
  296 
  297 void
  298 mac_netinet_icmp_replyinplace(struct mbuf *m)
  299 {
  300         struct label *label;
  301 
  302         if (mac_policy_count == 0)
  303                 return;
  304 
  305         label = mac_mbuf_to_label(m);
  306 
  307         MAC_POLICY_PERFORM_NOSLEEP(netinet_icmp_replyinplace, m, label);
  308 }
  309 
  310 void
  311 mac_netinet_igmp_send(struct ifnet *ifp, struct mbuf *m)
  312 {
  313         struct label *mlabel;
  314         int locked;
  315 
  316         if (mac_policy_count == 0)
  317                 return;
  318 
  319         mlabel = mac_mbuf_to_label(m);
  320 
  321         MAC_IFNET_LOCK(ifp, locked);
  322         MAC_POLICY_PERFORM_NOSLEEP(netinet_igmp_send, ifp, ifp->if_label, m,
  323             mlabel);
  324         MAC_IFNET_UNLOCK(ifp, locked);
  325 }
  326 
  327 void
  328 mac_netinet_tcp_reply(struct mbuf *m)
  329 {
  330         struct label *label;
  331 
  332         if (mac_policy_count == 0)
  333                 return;
  334 
  335         label = mac_mbuf_to_label(m);
  336 
  337         MAC_POLICY_PERFORM_NOSLEEP(netinet_tcp_reply, m, label);
  338 }
  339 
  340 void
  341 mac_ipq_update(struct mbuf *m, struct ipq *q)
  342 {
  343         struct label *label;
  344 
  345         if (mac_policy_count == 0)
  346                 return;
  347 
  348         label = mac_mbuf_to_label(m);
  349 
  350         MAC_POLICY_PERFORM_NOSLEEP(ipq_update, m, label, q, q->ipq_label);
  351 }
  352 
  353 MAC_CHECK_PROBE_DEFINE2(inpcb_check_deliver, "struct inpcb *",
  354     "struct mbuf *");
  355 
  356 int
  357 mac_inpcb_check_deliver(struct inpcb *inp, struct mbuf *m)
  358 {
  359         struct label *label;
  360         int error;
  361 
  362         M_ASSERTPKTHDR(m);
  363 
  364         if (mac_policy_count == 0)
  365                 return (0);
  366 
  367         label = mac_mbuf_to_label(m);
  368 
  369         MAC_POLICY_CHECK_NOSLEEP(inpcb_check_deliver, inp, inp->inp_label, m,
  370             label);
  371         MAC_CHECK_PROBE2(inpcb_check_deliver, error, inp, m);
  372 
  373         return (error);
  374 }
  375 
  376 MAC_CHECK_PROBE_DEFINE2(inpcb_check_visible, "struct ucred *",
  377     "struct inpcb *");
  378 
  379 int
  380 mac_inpcb_check_visible(struct ucred *cred, struct inpcb *inp)
  381 {
  382         int error;
  383 
  384         INP_LOCK_ASSERT(inp);
  385 
  386         MAC_POLICY_CHECK_NOSLEEP(inpcb_check_visible, cred, inp,
  387             inp->inp_label);
  388         MAC_CHECK_PROBE2(inpcb_check_visible, error, cred, inp);
  389 
  390         return (error);
  391 }
  392 
  393 void
  394 mac_inpcb_sosetlabel(struct socket *so, struct inpcb *inp)
  395 {
  396 
  397         INP_WLOCK_ASSERT(inp);
  398         SOCK_LOCK_ASSERT(so);
  399 
  400         MAC_POLICY_PERFORM_NOSLEEP(inpcb_sosetlabel, so, so->so_label, inp,
  401             inp->inp_label);
  402 }
  403 
  404 void
  405 mac_netinet_firewall_reply(struct mbuf *mrecv, struct mbuf *msend)
  406 {
  407         struct label *mrecvlabel, *msendlabel;
  408 
  409         M_ASSERTPKTHDR(mrecv);
  410         M_ASSERTPKTHDR(msend);
  411 
  412         if (mac_policy_count == 0)
  413                 return;
  414 
  415         mrecvlabel = mac_mbuf_to_label(mrecv);
  416         msendlabel = mac_mbuf_to_label(msend);
  417 
  418         MAC_POLICY_PERFORM_NOSLEEP(netinet_firewall_reply, mrecv, mrecvlabel,
  419             msend, msendlabel);
  420 }
  421 
  422 void
  423 mac_netinet_firewall_send(struct mbuf *m)
  424 {
  425         struct label *label;
  426 
  427         M_ASSERTPKTHDR(m);
  428 
  429         if (mac_policy_count == 0)
  430                 return;
  431 
  432         label = mac_mbuf_to_label(m);
  433 
  434         MAC_POLICY_PERFORM_NOSLEEP(netinet_firewall_send, m, label);
  435 }
  436 
  437 /*
  438  * These functions really should be referencing the syncache structure
  439  * instead of the label.  However, due to some of the complexities associated
  440  * with exposing this syncache structure we operate directly on its label
  441  * pointer.  This should be OK since we aren't making any access control
  442  * decisions within this code directly, we are merely allocating and copying
  443  * label storage so we can properly initialize mbuf labels for any packets
  444  * the syncache code might create.
  445  */
  446 void
  447 mac_syncache_destroy(struct label **label)
  448 {
  449 
  450         if (*label != NULL) {
  451                 MAC_POLICY_PERFORM_NOSLEEP(syncache_destroy_label, *label);
  452                 mac_labelzone_free(*label);
  453                 *label = NULL;
  454         }
  455 }
  456 
  457 int
  458 mac_syncache_init(struct label **label)
  459 {
  460         int error;
  461 
  462         if (mac_labeled & MPC_OBJECT_SYNCACHE) {
  463                 *label = mac_labelzone_alloc(M_NOWAIT);
  464                 if (*label == NULL)
  465                         return (ENOMEM);
  466                 /*
  467                  * Since we are holding the inpcb locks the policy can not
  468                  * allocate policy specific label storage using M_WAITOK.  So
  469                  * we need to do a MAC_CHECK instead of the typical
  470                  * MAC_PERFORM so we can propagate allocation failures back
  471                  * to the syncache code.
  472                  */
  473                 MAC_POLICY_CHECK_NOSLEEP(syncache_init_label, *label,
  474                     M_NOWAIT);
  475                 if (error) {
  476                         MAC_POLICY_PERFORM_NOSLEEP(syncache_destroy_label,
  477                             *label);
  478                         mac_labelzone_free(*label);
  479                 }
  480                 return (error);
  481         } else
  482                 *label = NULL;
  483         return (0);
  484 }
  485 
  486 void
  487 mac_syncache_create(struct label *label, struct inpcb *inp)
  488 {
  489 
  490         INP_LOCK_ASSERT(inp);
  491 
  492         MAC_POLICY_PERFORM_NOSLEEP(syncache_create, label, inp);
  493 }
  494 
  495 void
  496 mac_syncache_create_mbuf(struct label *sc_label, struct mbuf *m)
  497 {
  498         struct label *mlabel;
  499 
  500         M_ASSERTPKTHDR(m);
  501 
  502         if (mac_policy_count == 0)
  503                 return;
  504 
  505         mlabel = mac_mbuf_to_label(m);
  506 
  507         MAC_POLICY_PERFORM_NOSLEEP(syncache_create_mbuf, sc_label, m,
  508             mlabel);
  509 }

Cache object: 5707e2af16ee2dc1bc81d52bbb3decaf


[ 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.