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_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) 2007 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 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 
   72 #include <net/bpf.h>
   73 #include <net/if.h>
   74 
   75 #include <bsd/bsm/audit.h>
   76 #include <bsd/bsm/audit_kernel.h>
   77 
   78 #include <security/mac_internal.h>
   79 
   80 struct label *
   81 mac_mbuf_to_label(struct mbuf *mbuf)
   82 {
   83         struct m_tag *tag;
   84         struct label *label;
   85 
   86         if (mbuf == NULL)
   87                 return (NULL);
   88 
   89         if ((mbuf->m_flags & M_PKTHDR) == 0) {
   90                 printf("%s() got non-header MBUF!\n", __func__);
   91                 return (NULL);
   92         }
   93 
   94         tag = m_tag_locate(mbuf, KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_MACLABEL,
   95                            NULL);
   96         if (tag == NULL) {
   97                 printf("%s() m_tag_locate() returned NULL! (m->flags %04x)\n",
   98                         __func__, mbuf->m_flags);
   99                 return (NULL);
  100         }
  101         label = (struct label *)(tag+1);
  102         return (label);
  103 }
  104 
  105 static struct label *
  106 mac_bpfdesc_label_alloc(void)
  107 {
  108         struct label *label;
  109 
  110         label = mac_labelzone_alloc(M_WAITOK);
  111         if (label == NULL)
  112                 return (NULL);
  113         MAC_PERFORM(bpfdesc_label_init, label);
  114         return (label);
  115 }
  116 
  117 void
  118 mac_bpfdesc_label_init(struct bpf_d *bpf_d)
  119 {
  120         struct label *label;
  121 
  122         label = mac_bpfdesc_label_alloc();
  123         mac_bpfdesc_label_set(bpf_d, label);
  124 }
  125 
  126 static struct label *
  127 mac_ifnet_label_alloc(void)
  128 {
  129         struct label *label;
  130 
  131         label = mac_labelzone_alloc(M_WAITOK);
  132         if (label == NULL)
  133                 return (NULL);
  134         MAC_PERFORM(ifnet_label_init, label);
  135         return (label);
  136 }
  137 
  138 void
  139 mac_ifnet_label_init(struct ifnet *ifp)
  140 {
  141 
  142         ifp->if_label = mac_ifnet_label_alloc();
  143 }
  144 
  145 /*
  146  * On failure, caller should cleanup with m_tag_free().
  147  */
  148 int
  149 mac_mbuf_tag_init(struct m_tag *tag, int flag)
  150 {
  151         struct label *label;
  152         int error;
  153 
  154         label = (struct label *) (tag + 1);
  155         mac_label_init(label);
  156 
  157         MAC_CHECK(mbuf_label_init, label, flag);
  158         if (error)
  159                 printf("%s(): mpo_mbuf_label_init() failed!\n", __func__);
  160 
  161         return (error);
  162 }
  163 
  164 static void
  165 mac_bpfdesc_label_free(struct label *label)
  166 {
  167 
  168         MAC_PERFORM(bpfdesc_label_destroy, label);
  169         mac_labelzone_free(label);
  170 }
  171 
  172 void
  173 mac_bpfdesc_label_destroy(struct bpf_d *bpf_d)
  174 {
  175         struct label *label;
  176 
  177         label = mac_bpfdesc_label_get(bpf_d);
  178         mac_bpfdesc_label_free(label);
  179         mac_bpfdesc_label_set(bpf_d, NULL);
  180 }
  181 
  182 static void
  183 mac_ifnet_label_free(struct label *label)
  184 {
  185 
  186         MAC_PERFORM(ifnet_label_destroy, label);
  187         mac_labelzone_free(label);
  188 }
  189 
  190 void
  191 mac_ifnet_label_destroy(struct ifnet *ifp)
  192 {
  193 
  194         mac_ifnet_label_free(ifp->if_label);
  195         ifp->if_label = NULL;
  196 }
  197 
  198 void
  199 mac_ifnet_label_recycle(struct ifnet *ifp)
  200 {
  201 
  202         MAC_PERFORM(ifnet_label_recycle, ifp->if_label);
  203 }
  204 
  205 void
  206 mac_mbuf_tag_destroy(struct m_tag *tag)
  207 {
  208         struct label *label;
  209 
  210         label = (struct label *)(tag + 1);
  211         MAC_PERFORM(mbuf_label_destroy, label);
  212         mac_label_destroy(label);
  213 
  214         return;
  215 }
  216 
  217 void
  218 mac_mbuf_tag_copy(struct m_tag *src, struct m_tag *dest)
  219 {
  220         struct label *src_label, *dest_label;
  221 
  222         src_label = (struct label *)(src + 1);
  223         dest_label = (struct label *)(dest + 1);
  224 
  225         if (src_label == NULL || dest_label == NULL)
  226                 return;
  227 
  228         /*
  229          * mac_mbuf_tag_init() is called on the target tag
  230          * in m_tag_copy(), so we don't need to call it here.
  231          */
  232         MAC_PERFORM(mbuf_label_copy, src_label, dest_label);
  233 
  234         return;
  235 }
  236 
  237 void
  238 mac_mbuf_label_copy(struct mbuf *m_from, struct mbuf *m_to)
  239 {
  240         struct label *src_label, *dest_label;
  241 
  242         src_label = mac_mbuf_to_label(m_from);
  243         dest_label = mac_mbuf_to_label(m_to);
  244 
  245         MAC_PERFORM(mbuf_label_copy, src_label, dest_label);
  246 }
  247 
  248 static void
  249 mac_ifnet_label_copy(struct label *src, struct label *dest)
  250 {
  251 
  252         MAC_PERFORM(ifnet_label_copy, src, dest);
  253 }
  254 
  255 static int
  256 mac_ifnet_label_externalize(struct label *label, char *elements,
  257     char *outbuf, size_t outbuflen)
  258 {
  259 
  260         return (MAC_EXTERNALIZE(ifnet, label, elements, outbuf, outbuflen));
  261 }
  262 
  263 static int
  264 mac_ifnet_label_internalize(struct label *label, char *string)
  265 {
  266 
  267         return (MAC_INTERNALIZE(ifnet, label, string));
  268 }
  269 
  270 void
  271 mac_ifnet_label_associate(struct ifnet *ifp)
  272 {
  273 
  274         MAC_PERFORM(ifnet_label_associate, ifp, ifp->if_label);
  275 }
  276 
  277 void
  278 mac_bpfdesc_label_associate(struct ucred *cred, struct bpf_d *bpf_d)
  279 {
  280         struct label *label;
  281 
  282         label = mac_bpfdesc_label_get(bpf_d);
  283         MAC_PERFORM(bpfdesc_label_associate, cred, bpf_d, label);
  284 }
  285 
  286 int
  287 mac_bpfdesc_check_receive(struct bpf_d *bpf_d, struct ifnet *ifp)
  288 {
  289         struct label *label;
  290         int error;
  291 
  292         label = mac_bpfdesc_label_get(bpf_d);
  293         ifnet_lock_shared(ifp);
  294         MAC_CHECK(bpfdesc_check_receive, bpf_d, label, ifp,
  295             ifp->if_label);
  296         ifnet_lock_done(ifp);
  297 
  298         return (error);
  299 }
  300 
  301 int
  302 mac_mbuf_label_init(struct mbuf *m, int flag)
  303 {
  304         struct m_tag *tag;
  305         int error;
  306 
  307         if (mac_label_mbufs == 0)
  308                 return (0);
  309 
  310         tag = m_tag_alloc(KERNEL_MODULE_TAG_ID, KERNEL_TAG_TYPE_MACLABEL,
  311                           sizeof(struct label), flag);
  312         if (tag == NULL) {
  313                 printf("%s(): m_tag_alloc() failed!\n", __func__);
  314                 return (ENOBUFS);
  315         }
  316         error = mac_mbuf_tag_init(tag, flag);
  317         if (error) {
  318                 printf("%s(): mac_mbuf_tag_init() failed!\n", __func__);
  319                 m_tag_free(tag);
  320                 return (error);
  321         }
  322         m_tag_prepend(m, tag);
  323         return (0);
  324 }
  325 
  326 void
  327 mac_mbuf_label_associate_bpfdesc(struct bpf_d *bpf_d, struct mbuf *mbuf)
  328 {
  329         struct label *m_label, *b_label;
  330 
  331         /* bpf_d must be locked */
  332 
  333         m_label = mac_mbuf_to_label(mbuf);
  334         b_label = mac_bpfdesc_label_get(bpf_d);
  335 
  336         MAC_PERFORM(mbuf_label_associate_bpfdesc, bpf_d, b_label, mbuf,
  337             m_label);
  338 }
  339 
  340 void
  341 mac_mbuf_label_associate_ifnet(struct ifnet *ifp, struct mbuf *mbuf)
  342 {
  343         struct label *m_label;
  344 
  345         /* ifp must be locked */
  346 
  347         m_label = mac_mbuf_to_label(mbuf);
  348 
  349         MAC_PERFORM(mbuf_label_associate_ifnet, ifp, ifp->if_label, mbuf,
  350             m_label);
  351 }
  352 
  353 void
  354 mac_mbuf_label_associate_linklayer(struct ifnet *ifp, struct mbuf *mbuf)
  355 {
  356         struct label *m_label;
  357 
  358         /* ifp must be locked */
  359 
  360         m_label = mac_mbuf_to_label(mbuf);
  361 
  362         MAC_PERFORM(mbuf_label_associate_linklayer, ifp, ifp->if_label, mbuf,
  363             m_label);
  364 }
  365 
  366 void
  367 mac_mbuf_label_associate_multicast_encap(struct mbuf *oldmbuf,
  368     struct ifnet *ifp, struct mbuf *newmbuf)
  369 {
  370         struct label *oldmbuflabel, *newmbuflabel;
  371 
  372         oldmbuflabel = mac_mbuf_to_label(oldmbuf);
  373         newmbuflabel = mac_mbuf_to_label(newmbuf);
  374 
  375         /* ifp must be locked */
  376 
  377         MAC_PERFORM(mbuf_label_associate_multicast_encap, oldmbuf, oldmbuflabel,
  378             ifp, ifp->if_label, newmbuf, newmbuflabel);
  379 }
  380 
  381 void
  382 mac_mbuf_label_associate_netlayer(struct mbuf *oldmbuf, struct mbuf *newmbuf)
  383 {
  384         struct label *oldmbuflabel, *newmbuflabel;
  385 
  386         oldmbuflabel = mac_mbuf_to_label(oldmbuf);
  387         newmbuflabel = mac_mbuf_to_label(newmbuf);
  388 
  389         MAC_PERFORM(mbuf_label_associate_netlayer, oldmbuf, oldmbuflabel,
  390             newmbuf, newmbuflabel);
  391 }
  392 
  393 void
  394 mac_mbuf_label_associate_socket(struct socket *socket, struct mbuf *mbuf)
  395 {
  396         struct label *label;
  397         struct xsocket xso;
  398 
  399         /* socket must be locked */
  400 
  401         label = mac_mbuf_to_label(mbuf);
  402 
  403         sotoxsocket(socket, &xso);
  404         MAC_PERFORM(mbuf_label_associate_socket, &xso, socket->so_label,
  405                     mbuf, label);
  406 }
  407 
  408 int
  409 mac_ifnet_check_transmit(struct ifnet *ifp, struct mbuf *mbuf, int family,
  410     int type)
  411 {
  412         struct label *label;
  413         int error;
  414 
  415         label = mac_mbuf_to_label(mbuf);
  416 
  417         ifnet_lock_shared(ifp);
  418         MAC_CHECK(ifnet_check_transmit, ifp, ifp->if_label, mbuf, label,
  419             family, type);
  420         ifnet_lock_done(ifp);
  421 
  422         return (error);
  423 }
  424 
  425 int
  426 mac_ifnet_label_get(__unused struct ucred *cred, struct ifreq *ifr,
  427     struct ifnet *ifp)
  428 {
  429         char *elements, *buffer;
  430         struct label *intlabel;
  431         struct mac mac;
  432         int error;
  433         size_t len;
  434 
  435         error = copyin(CAST_USER_ADDR_T(ifr->ifr_ifru.ifru_data),
  436             &mac, sizeof(mac));
  437         if (error)
  438                 return (error);
  439 
  440         error = mac_check_structmac_consistent(&mac);
  441         if (error)
  442                 return (error);
  443 
  444         MALLOC(elements, char *, mac.m_buflen, M_MACTEMP, M_WAITOK);
  445         error = copyinstr(CAST_USER_ADDR_T(mac.m_string), elements,
  446             mac.m_buflen, &len);
  447         if (error) {
  448                 FREE(elements, M_MACTEMP);
  449                 return (error);
  450         }
  451         AUDIT_ARG(mac_string, elements);
  452 
  453         MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
  454         intlabel = mac_ifnet_label_alloc();
  455         ifnet_lock_shared(ifp);
  456         mac_ifnet_label_copy(ifp->if_label, intlabel);
  457         ifnet_lock_done(ifp);
  458         error = mac_ifnet_label_externalize(intlabel, elements,
  459             buffer, mac.m_buflen);
  460         mac_ifnet_label_free(intlabel);
  461         FREE(elements, M_MACTEMP);
  462 
  463         if (error == 0)
  464                 error = copyout(buffer, CAST_USER_ADDR_T(mac.m_string),
  465                     strlen(buffer) + 1);
  466         FREE(buffer, M_MACTEMP);
  467 
  468         return (error);
  469 }
  470 
  471 int
  472 mac_ifnet_label_set(struct ucred *cred, struct ifreq *ifr,
  473     struct ifnet *ifp)
  474 {
  475         struct label *intlabel;
  476         struct mac mac;
  477         char *buffer;
  478         int error;
  479         size_t len;
  480 
  481         error = copyin(CAST_USER_ADDR_T(ifr->ifr_ifru.ifru_data),
  482             &mac, sizeof(mac));
  483         if (error)
  484                 return (error);
  485 
  486         error = mac_check_structmac_consistent(&mac);
  487         if (error)
  488                 return (error);
  489 
  490         MALLOC(buffer, char *, mac.m_buflen, M_MACTEMP, M_WAITOK);
  491         error = copyinstr(CAST_USER_ADDR_T(mac.m_string), buffer,
  492             mac.m_buflen, &len);
  493         if (error) {
  494                 FREE(buffer, M_MACTEMP);
  495                 return (error);
  496         }
  497         AUDIT_ARG(mac_string, buffer);
  498 
  499         intlabel = mac_ifnet_label_alloc();
  500         error = mac_ifnet_label_internalize(intlabel, buffer);
  501         FREE(buffer, M_MACTEMP);
  502         if (error) {
  503                 mac_ifnet_label_free(intlabel);
  504                 return (error);
  505         }
  506 
  507         /*
  508          * XXX: Note that this is a redundant privilege check, since
  509          * policies impose this check themselves if required by the
  510          * policy.  Eventually, this should go away.
  511          */
  512         error = suser(cred, NULL);
  513         if (error) {
  514                 mac_ifnet_label_free(intlabel);
  515                 return (error);
  516         }
  517 
  518         ifnet_lock_exclusive(ifp);
  519         MAC_CHECK(ifnet_check_label_update, cred, ifp, ifp->if_label,
  520             intlabel);
  521         if (error) {
  522                 ifnet_lock_done(ifp);
  523                 mac_ifnet_label_free(intlabel);
  524                 return (error);
  525         }
  526 
  527         MAC_PERFORM(ifnet_label_update, cred, ifp, ifp->if_label, intlabel);
  528         ifnet_lock_done(ifp);
  529         mac_ifnet_label_free(intlabel);
  530 
  531         return (0);
  532 }

Cache object: 4ff27a2309a938f3d5c7da7d0b4c1244


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