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_net.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 Robert N. M. Watson
    3  * Copyright (c) 2001 Ilmar S. Habibulin
    4  * Copyright (c) 2001-2004 Networks Associates Technology, Inc.
    5  * All rights reserved.
    6  *
    7  * This software was developed by Robert Watson and Ilmar Habibulin for the
    8  * TrustedBSD Project.
    9  *
   10  * This software was developed for the FreeBSD Project in part by Network
   11  * Associates Laboratories, the Security Research Division of Network
   12  * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
   13  * as part of the DARPA CHATS research program.
   14  *
   15  * Redistribution and use in source and binary forms, with or without
   16  * modification, are permitted provided that the following conditions
   17  * are met:
   18  * 1. Redistributions of source code must retain the above copyright
   19  *    notice, this list of conditions and the following disclaimer.
   20  * 2. Redistributions in binary form must reproduce the above copyright
   21  *    notice, this list of conditions and the following disclaimer in the
   22  *    documentation and/or other materials provided with the distribution.
   23  *
   24  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   34  * SUCH DAMAGE.
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __FBSDID("$FreeBSD$");
   39 
   40 #include "opt_mac.h"
   41 
   42 #include <sys/param.h>
   43 #include <sys/kernel.h>
   44 #include <sys/lock.h>
   45 #include <sys/malloc.h>
   46 #include <sys/mutex.h>
   47 #include <sys/mac.h>
   48 #include <sys/priv.h>
   49 #include <sys/sbuf.h>
   50 #include <sys/systm.h>
   51 #include <sys/mount.h>
   52 #include <sys/file.h>
   53 #include <sys/namei.h>
   54 #include <sys/protosw.h>
   55 #include <sys/socket.h>
   56 #include <sys/socketvar.h>
   57 #include <sys/sysctl.h>
   58 
   59 #include <net/bpfdesc.h>
   60 #include <net/if.h>
   61 #include <net/if_var.h>
   62 
   63 #include <security/mac/mac_framework.h>
   64 #include <security/mac/mac_internal.h>
   65 #include <security/mac/mac_policy.h>
   66 
   67 /*
   68  * XXXRW: struct ifnet locking is incomplete in the network code, so we use
   69  * our own global mutex for struct ifnet.  Non-ideal, but should help in the
   70  * SMP environment.
   71  */
   72 static struct mtx mac_ifnet_mtx;
   73 MTX_SYSINIT(mac_ifnet_mtx, &mac_ifnet_mtx, "mac_ifnet", MTX_DEF);
   74 #define MAC_IFNET_LOCK(ifp)     mtx_lock(&mac_ifnet_mtx)
   75 #define MAC_IFNET_UNLOCK(ifp)   mtx_unlock(&mac_ifnet_mtx)
   76 
   77 /*
   78  * Retrieve the label associated with an mbuf by searching for the tag.
   79  * Depending on the value of mac_labelmbufs, it's possible that a label will
   80  * not be present, in which case NULL is returned.  Policies must handle the
   81  * possibility of an mbuf not having label storage if they do not enforce
   82  * early loading.
   83  */
   84 struct label *
   85 mac_mbuf_to_label(struct mbuf *m)
   86 {
   87         struct m_tag *tag;
   88         struct label *label;
   89 
   90         if (m == NULL)
   91                 return (NULL);
   92         tag = m_tag_find(m, PACKET_TAG_MACLABEL, NULL);
   93         if (tag == NULL)
   94                 return (NULL);
   95         label = (struct label *)(tag+1);
   96         return (label);
   97 }
   98 
   99 static struct label *
  100 mac_bpfdesc_label_alloc(void)
  101 {
  102         struct label *label;
  103 
  104         label = mac_labelzone_alloc(M_WAITOK);
  105         MAC_PERFORM(init_bpfdesc_label, label);
  106         return (label);
  107 }
  108 
  109 void
  110 mac_init_bpfdesc(struct bpf_d *d)
  111 {
  112 
  113         d->bd_label = mac_bpfdesc_label_alloc();
  114 }
  115 
  116 static struct label *
  117 mac_ifnet_label_alloc(void)
  118 {
  119         struct label *label;
  120 
  121         label = mac_labelzone_alloc(M_WAITOK);
  122         MAC_PERFORM(init_ifnet_label, label);
  123         return (label);
  124 }
  125 
  126 void
  127 mac_init_ifnet(struct ifnet *ifp)
  128 {
  129 
  130         ifp->if_label = mac_ifnet_label_alloc();
  131 }
  132 
  133 int
  134 mac_init_mbuf_tag(struct m_tag *tag, int flag)
  135 {
  136         struct label *label;
  137         int error;
  138 
  139         label = (struct label *) (tag + 1);
  140         mac_init_label(label);
  141 
  142         MAC_CHECK(init_mbuf_label, label, flag);
  143         if (error) {
  144                 MAC_PERFORM(destroy_mbuf_label, label);
  145                 mac_destroy_label(label);
  146         }
  147         return (error);
  148 }
  149 
  150 int
  151 mac_init_mbuf(struct mbuf *m, int flag)
  152 {
  153         struct m_tag *tag;
  154         int error;
  155 
  156         M_ASSERTPKTHDR(m);
  157 
  158 #ifndef MAC_ALWAYS_LABEL_MBUF
  159         /*
  160          * If conditionally allocating mbuf labels, don't allocate unless
  161          * they are required.
  162          */
  163         if (!mac_labelmbufs)
  164                 return (0);
  165 #endif
  166         tag = m_tag_get(PACKET_TAG_MACLABEL, sizeof(struct label),
  167             flag);
  168         if (tag == NULL)
  169                 return (ENOMEM);
  170         error = mac_init_mbuf_tag(tag, flag);
  171         if (error) {
  172                 m_tag_free(tag);
  173                 return (error);
  174         }
  175         m_tag_prepend(m, tag);
  176         return (0);
  177 }
  178 
  179 static void
  180 mac_bpfdesc_label_free(struct label *label)
  181 {
  182 
  183         MAC_PERFORM(destroy_bpfdesc_label, label);
  184         mac_labelzone_free(label);
  185 }
  186 
  187 void
  188 mac_destroy_bpfdesc(struct bpf_d *d)
  189 {
  190 
  191         mac_bpfdesc_label_free(d->bd_label);
  192         d->bd_label = NULL;
  193 }
  194 
  195 static void
  196 mac_ifnet_label_free(struct label *label)
  197 {
  198 
  199         MAC_PERFORM(destroy_ifnet_label, label);
  200         mac_labelzone_free(label);
  201 }
  202 
  203 void
  204 mac_destroy_ifnet(struct ifnet *ifp)
  205 {
  206 
  207         mac_ifnet_label_free(ifp->if_label);
  208         ifp->if_label = NULL;
  209 }
  210 
  211 void
  212 mac_destroy_mbuf_tag(struct m_tag *tag)
  213 {
  214         struct label *label;
  215 
  216         label = (struct label *)(tag+1);
  217 
  218         MAC_PERFORM(destroy_mbuf_label, label);
  219         mac_destroy_label(label);
  220 }
  221 
  222 /*
  223  * mac_copy_mbuf_tag is called when an mbuf header is duplicated, in which
  224  * case the labels must also be duplicated.
  225  */
  226 void
  227 mac_copy_mbuf_tag(struct m_tag *src, struct m_tag *dest)
  228 {
  229         struct label *src_label, *dest_label;
  230 
  231         src_label = (struct label *)(src+1);
  232         dest_label = (struct label *)(dest+1);
  233 
  234         /*
  235          * mac_init_mbuf_tag() is called on the target tag in m_tag_copy(),
  236          * so we don't need to call it here.
  237          */
  238         MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
  239 }
  240 
  241 void
  242 mac_copy_mbuf(struct mbuf *m_from, struct mbuf *m_to)
  243 {
  244         struct label *src_label, *dest_label;
  245 
  246         src_label = mac_mbuf_to_label(m_from);
  247         dest_label = mac_mbuf_to_label(m_to);
  248 
  249         MAC_PERFORM(copy_mbuf_label, src_label, dest_label);
  250 }
  251 
  252 static void
  253 mac_copy_ifnet_label(struct label *src, struct label *dest)
  254 {
  255 
  256         MAC_PERFORM(copy_ifnet_label, src, dest);
  257 }
  258 
  259 static int
  260 mac_externalize_ifnet_label(struct label *label, char *elements,
  261     char *outbuf, size_t outbuflen)
  262 {
  263         int error;
  264 
  265         MAC_EXTERNALIZE(ifnet, label, elements, outbuf, outbuflen);
  266 
  267         return (error);
  268 }
  269 
  270 static int
  271 mac_internalize_ifnet_label(struct label *label, char *string)
  272 {
  273         int error;
  274 
  275         MAC_INTERNALIZE(ifnet, label, string);
  276 
  277         return (error);
  278 }
  279 
  280 void
  281 mac_create_ifnet(struct ifnet *ifp)
  282 {
  283 
  284         MAC_IFNET_LOCK(ifp);
  285         MAC_PERFORM(create_ifnet, ifp, ifp->if_label);
  286         MAC_IFNET_UNLOCK(ifp);
  287 }
  288 
  289 void
  290 mac_create_bpfdesc(struct ucred *cred, struct bpf_d *d)
  291 {
  292 
  293         MAC_PERFORM(create_bpfdesc, cred, d, d->bd_label);
  294 }
  295 
  296 void
  297 mac_create_mbuf_from_bpfdesc(struct bpf_d *d, struct mbuf *m)
  298 {
  299         struct label *label;
  300 
  301         BPFD_LOCK_ASSERT(d);
  302 
  303         label = mac_mbuf_to_label(m);
  304 
  305         MAC_PERFORM(create_mbuf_from_bpfdesc, d, d->bd_label, m, label);
  306 }
  307 
  308 void
  309 mac_create_mbuf_linklayer(struct ifnet *ifp, struct mbuf *m)
  310 {
  311         struct label *label;
  312 
  313         label = mac_mbuf_to_label(m);
  314 
  315         MAC_IFNET_LOCK(ifp);
  316         MAC_PERFORM(create_mbuf_linklayer, ifp, ifp->if_label, m, label);
  317         MAC_IFNET_UNLOCK(ifp);
  318 }
  319 
  320 void
  321 mac_create_mbuf_from_ifnet(struct ifnet *ifp, struct mbuf *m)
  322 {
  323         struct label *label;
  324 
  325         label = mac_mbuf_to_label(m);
  326 
  327         MAC_IFNET_LOCK(ifp);
  328         MAC_PERFORM(create_mbuf_from_ifnet, ifp, ifp->if_label, m, label);
  329         MAC_IFNET_UNLOCK(ifp);
  330 }
  331 
  332 void
  333 mac_create_mbuf_multicast_encap(struct mbuf *m, struct ifnet *ifp,
  334     struct mbuf *mnew)
  335 {
  336         struct label *mlabel, *mnewlabel;
  337 
  338         mlabel = mac_mbuf_to_label(m);
  339         mnewlabel = mac_mbuf_to_label(mnew);
  340 
  341         MAC_IFNET_LOCK(ifp);
  342         MAC_PERFORM(create_mbuf_multicast_encap, m, mlabel, ifp,
  343             ifp->if_label, mnew, mnewlabel);
  344         MAC_IFNET_UNLOCK(ifp);
  345 }
  346 
  347 void
  348 mac_create_mbuf_netlayer(struct mbuf *m, struct mbuf *mnew)
  349 {
  350         struct label *mlabel, *mnewlabel;
  351 
  352         mlabel = mac_mbuf_to_label(m);
  353         mnewlabel = mac_mbuf_to_label(mnew);
  354 
  355         MAC_PERFORM(create_mbuf_netlayer, m, mlabel, mnew, mnewlabel);
  356 }
  357 
  358 int
  359 mac_check_bpfdesc_receive(struct bpf_d *d, struct ifnet *ifp)
  360 {
  361         int error;
  362 
  363         BPFD_LOCK_ASSERT(d);
  364 
  365         MAC_IFNET_LOCK(ifp);
  366         MAC_CHECK(check_bpfdesc_receive, d, d->bd_label, ifp, ifp->if_label);
  367         MAC_IFNET_UNLOCK(ifp);
  368 
  369         return (error);
  370 }
  371 
  372 int
  373 mac_check_ifnet_transmit(struct ifnet *ifp, struct mbuf *m)
  374 {
  375         struct label *label;
  376         int error;
  377 
  378         M_ASSERTPKTHDR(m);
  379 
  380         label = mac_mbuf_to_label(m);
  381 
  382         MAC_IFNET_LOCK(ifp);
  383         MAC_CHECK(check_ifnet_transmit, ifp, ifp->if_label, m, label);
  384         MAC_IFNET_UNLOCK(ifp);
  385 
  386         return (error);
  387 }
  388 
  389 int
  390 mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
  391     struct ifnet *ifp)
  392 {
  393         char *elements, *buffer;
  394         struct label *intlabel;
  395         struct mac mac;
  396         int error;
  397 
  398         error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
  399         if (error)
  400                 return (error);
  401 
  402         error = mac_check_structmac_consistent(&mac);
  403         if (error)
  404                 return (error);
  405 
  406         elements = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
  407         error = copyinstr(mac.m_string, elements, mac.m_buflen, NULL);
  408         if (error) {
  409                 free(elements, M_MACTEMP);
  410                 return (error);
  411         }
  412 
  413         buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
  414         intlabel = mac_ifnet_label_alloc();
  415         MAC_IFNET_LOCK(ifp);
  416         mac_copy_ifnet_label(ifp->if_label, intlabel);
  417         MAC_IFNET_UNLOCK(ifp);
  418         error = mac_externalize_ifnet_label(intlabel, elements, buffer,
  419             mac.m_buflen);
  420         mac_ifnet_label_free(intlabel);
  421         if (error == 0)
  422                 error = copyout(buffer, mac.m_string, strlen(buffer)+1);
  423 
  424         free(buffer, M_MACTEMP);
  425         free(elements, M_MACTEMP);
  426 
  427         return (error);
  428 }
  429 
  430 int
  431 mac_ioctl_ifnet_set(struct ucred *cred, struct ifreq *ifr, struct ifnet *ifp)
  432 {
  433         struct label *intlabel;
  434         struct mac mac;
  435         char *buffer;
  436         int error;
  437 
  438         error = copyin(ifr->ifr_ifru.ifru_data, &mac, sizeof(mac));
  439         if (error)
  440                 return (error);
  441 
  442         error = mac_check_structmac_consistent(&mac);
  443         if (error)
  444                 return (error);
  445 
  446         buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK);
  447         error = copyinstr(mac.m_string, buffer, mac.m_buflen, NULL);
  448         if (error) {
  449                 free(buffer, M_MACTEMP);
  450                 return (error);
  451         }
  452 
  453         intlabel = mac_ifnet_label_alloc();
  454         error = mac_internalize_ifnet_label(intlabel, buffer);
  455         free(buffer, M_MACTEMP);
  456         if (error) {
  457                 mac_ifnet_label_free(intlabel);
  458                 return (error);
  459         }
  460 
  461         /*
  462          * XXX: Note that this is a redundant privilege check, since policies
  463          * impose this check themselves if required by the policy
  464          * Eventually, this should go away.
  465          */
  466         error = priv_check_cred(cred, PRIV_NET_SETIFMAC, 0);
  467         if (error) {
  468                 mac_ifnet_label_free(intlabel);
  469                 return (error);
  470         }
  471 
  472         MAC_IFNET_LOCK(ifp);
  473         MAC_CHECK(check_ifnet_relabel, cred, ifp, ifp->if_label, intlabel);
  474         if (error) {
  475                 MAC_IFNET_UNLOCK(ifp);
  476                 mac_ifnet_label_free(intlabel);
  477                 return (error);
  478         }
  479 
  480         MAC_PERFORM(relabel_ifnet, cred, ifp, ifp->if_label, intlabel);
  481         MAC_IFNET_UNLOCK(ifp);
  482 
  483         mac_ifnet_label_free(intlabel);
  484         return (0);
  485 }

Cache object: 8258b7f319db3bb7e3a3f11de39fc874


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