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_socket.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, 2009 Robert N. M. Watson
    3  * Copyright (c) 2001 Ilmar S. Habibulin
    4  * Copyright (c) 2001-2005 Networks Associates Technology, Inc.
    5  * Copyright (c) 2005-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 McAfee
   13  * Research, the Technology Research Division of Network Associates, Inc.
   14  * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
   15  * 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/10.0/sys/security/mac/mac_socket.c 193391 2009-06-03 18:46:28Z rwatson $");
   47 
   48 #include "opt_kdtrace.h"
   49 #include "opt_mac.h"
   50 
   51 #include <sys/param.h>
   52 #include <sys/kernel.h>
   53 #include <sys/lock.h>
   54 #include <sys/malloc.h>
   55 #include <sys/mutex.h>
   56 #include <sys/mac.h>
   57 #include <sys/sbuf.h>
   58 #include <sys/sdt.h>
   59 #include <sys/systm.h>
   60 #include <sys/mount.h>
   61 #include <sys/file.h>
   62 #include <sys/namei.h>
   63 #include <sys/protosw.h>
   64 #include <sys/socket.h>
   65 #include <sys/socketvar.h>
   66 #include <sys/sysctl.h>
   67 
   68 #include <net/bpfdesc.h>
   69 #include <net/if.h>
   70 #include <net/if_var.h>
   71 
   72 #include <netinet/in.h>
   73 #include <netinet/in_pcb.h>
   74 #include <netinet/ip_var.h>
   75 
   76 #include <security/mac/mac_framework.h>
   77 #include <security/mac/mac_internal.h>
   78 #include <security/mac/mac_policy.h>
   79 
   80 /*
   81  * Currently, sockets hold two labels: the label of the socket itself, and a
   82  * peer label, which may be used by policies to hold a copy of the label of
   83  * any remote endpoint.
   84  *
   85  * Possibly, this peer label should be maintained at the protocol layer
   86  * (inpcb, unpcb, etc), as this would allow protocol-aware code to maintain
   87  * the label consistently.  For example, it might be copied live from a
   88  * remote socket for UNIX domain sockets rather than keeping a local copy on
   89  * this endpoint, but be cached and updated based on packets received for
   90  * TCP/IP.
   91  *
   92  * Unlike with many other object types, the lock protecting MAC labels on
   93  * sockets (the socket lock) is not frequently held at the points in code
   94  * where socket-related checks are called.  The MAC Framework acquires the
   95  * lock over some entry points in order to enforce atomicity (such as label
   96  * copies) but in other cases the policy modules will have to acquire the
   97  * lock themselves if they use labels.  This approach (a) avoids lock
   98  * acquisitions when policies don't require labels and (b) solves a number of
   99  * potential lock order issues when multiple sockets are used in the same
  100  * entry point.
  101  */
  102 
  103 struct label *
  104 mac_socket_label_alloc(int flag)
  105 {
  106         struct label *label;
  107         int error;
  108 
  109         label = mac_labelzone_alloc(flag);
  110         if (label == NULL)
  111                 return (NULL);
  112 
  113         if (flag & M_WAITOK)
  114                 MAC_POLICY_CHECK(socket_init_label, label, flag);
  115         else
  116                 MAC_POLICY_CHECK_NOSLEEP(socket_init_label, label, flag);
  117         if (error) {
  118                 MAC_POLICY_PERFORM_NOSLEEP(socket_destroy_label, label);
  119                 mac_labelzone_free(label);
  120                 return (NULL);
  121         }
  122         return (label);
  123 }
  124 
  125 static struct label *
  126 mac_socketpeer_label_alloc(int flag)
  127 {
  128         struct label *label;
  129         int error;
  130 
  131         label = mac_labelzone_alloc(flag);
  132         if (label == NULL)
  133                 return (NULL);
  134 
  135         if (flag & M_WAITOK)
  136                 MAC_POLICY_CHECK(socketpeer_init_label, label, flag);
  137         else
  138                 MAC_POLICY_CHECK_NOSLEEP(socketpeer_init_label, label, flag);
  139         if (error) {
  140                 MAC_POLICY_PERFORM_NOSLEEP(socketpeer_destroy_label, label);
  141                 mac_labelzone_free(label);
  142                 return (NULL);
  143         }
  144         return (label);
  145 }
  146 
  147 int
  148 mac_socket_init(struct socket *so, int flag)
  149 {
  150 
  151         if (mac_labeled & MPC_OBJECT_SOCKET) {
  152                 so->so_label = mac_socket_label_alloc(flag);
  153                 if (so->so_label == NULL)
  154                         return (ENOMEM);
  155                 so->so_peerlabel = mac_socketpeer_label_alloc(flag);
  156                 if (so->so_peerlabel == NULL) {
  157                         mac_socket_label_free(so->so_label);
  158                         so->so_label = NULL;
  159                         return (ENOMEM);
  160                 }
  161         } else {
  162                 so->so_label = NULL;
  163                 so->so_peerlabel = NULL;
  164         }
  165         return (0);
  166 }
  167 
  168 void
  169 mac_socket_label_free(struct label *label)
  170 {
  171 
  172         MAC_POLICY_PERFORM_NOSLEEP(socket_destroy_label, label);
  173         mac_labelzone_free(label);
  174 }
  175 
  176 static void
  177 mac_socketpeer_label_free(struct label *label)
  178 {
  179 
  180         MAC_POLICY_PERFORM_NOSLEEP(socketpeer_destroy_label, label);
  181         mac_labelzone_free(label);
  182 }
  183 
  184 void
  185 mac_socket_destroy(struct socket *so)
  186 {
  187 
  188         if (so->so_label != NULL) {
  189                 mac_socket_label_free(so->so_label);
  190                 so->so_label = NULL;
  191                 mac_socketpeer_label_free(so->so_peerlabel);
  192                 so->so_peerlabel = NULL;
  193         }
  194 }
  195 
  196 void
  197 mac_socket_copy_label(struct label *src, struct label *dest)
  198 {
  199 
  200         MAC_POLICY_PERFORM_NOSLEEP(socket_copy_label, src, dest);
  201 }
  202 
  203 int
  204 mac_socket_externalize_label(struct label *label, char *elements,
  205     char *outbuf, size_t outbuflen)
  206 {
  207         int error;
  208 
  209         MAC_POLICY_EXTERNALIZE(socket, label, elements, outbuf, outbuflen);
  210 
  211         return (error);
  212 }
  213 
  214 static int
  215 mac_socketpeer_externalize_label(struct label *label, char *elements,
  216     char *outbuf, size_t outbuflen)
  217 {
  218         int error;
  219 
  220         MAC_POLICY_EXTERNALIZE(socketpeer, label, elements, outbuf,
  221             outbuflen);
  222 
  223         return (error);
  224 }
  225 
  226 int
  227 mac_socket_internalize_label(struct label *label, char *string)
  228 {
  229         int error;
  230 
  231         MAC_POLICY_INTERNALIZE(socket, label, string);
  232 
  233         return (error);
  234 }
  235 
  236 void
  237 mac_socket_create(struct ucred *cred, struct socket *so)
  238 {
  239 
  240         MAC_POLICY_PERFORM_NOSLEEP(socket_create, cred, so, so->so_label);
  241 }
  242 
  243 void
  244 mac_socket_newconn(struct socket *oldso, struct socket *newso)
  245 {
  246 
  247         MAC_POLICY_PERFORM_NOSLEEP(socket_newconn, oldso, oldso->so_label,
  248             newso, newso->so_label);
  249 }
  250 
  251 static void
  252 mac_socket_relabel(struct ucred *cred, struct socket *so,
  253     struct label *newlabel)
  254 {
  255 
  256         SOCK_LOCK_ASSERT(so);
  257 
  258         MAC_POLICY_PERFORM_NOSLEEP(socket_relabel, cred, so, so->so_label,
  259             newlabel);
  260 }
  261 
  262 void
  263 mac_socketpeer_set_from_mbuf(struct mbuf *m, struct socket *so)
  264 {
  265         struct label *label;
  266 
  267         if (mac_policy_count == 0)
  268                 return;
  269 
  270         label = mac_mbuf_to_label(m);
  271 
  272         MAC_POLICY_PERFORM_NOSLEEP(socketpeer_set_from_mbuf, m, label, so,
  273             so->so_peerlabel);
  274 }
  275 
  276 void
  277 mac_socketpeer_set_from_socket(struct socket *oldso, struct socket *newso)
  278 {
  279         
  280         if (mac_policy_count == 0)
  281                 return;
  282 
  283         MAC_POLICY_PERFORM_NOSLEEP(socketpeer_set_from_socket, oldso,
  284             oldso->so_label, newso, newso->so_peerlabel);
  285 }
  286 
  287 void
  288 mac_socket_create_mbuf(struct socket *so, struct mbuf *m)
  289 {
  290         struct label *label;
  291 
  292         if (mac_policy_count == 0)
  293                 return;
  294 
  295         label = mac_mbuf_to_label(m);
  296 
  297         MAC_POLICY_PERFORM_NOSLEEP(socket_create_mbuf, so, so->so_label, m,
  298             label);
  299 }
  300 
  301 MAC_CHECK_PROBE_DEFINE2(socket_check_accept, "struct ucred *",
  302     "struct socket *");
  303 
  304 int
  305 mac_socket_check_accept(struct ucred *cred, struct socket *so)
  306 {
  307         int error;
  308 
  309         MAC_POLICY_CHECK_NOSLEEP(socket_check_accept, cred, so,
  310             so->so_label);
  311         MAC_CHECK_PROBE2(socket_check_accept, error, cred, so);
  312 
  313         return (error);
  314 }
  315 
  316 MAC_CHECK_PROBE_DEFINE3(socket_check_bind, "struct ucred *",
  317     "struct socket *", "struct sockaddr *");
  318 
  319 int
  320 mac_socket_check_bind(struct ucred *cred, struct socket *so,
  321     struct sockaddr *sa)
  322 {
  323         int error;
  324 
  325         MAC_POLICY_CHECK_NOSLEEP(socket_check_bind, cred, so, so->so_label,
  326             sa);
  327         MAC_CHECK_PROBE3(socket_check_bind, error, cred, so, sa);
  328 
  329         return (error);
  330 }
  331 
  332 MAC_CHECK_PROBE_DEFINE3(socket_check_connect, "struct ucred *",
  333     "struct socket *", "struct sockaddr *");
  334 
  335 int
  336 mac_socket_check_connect(struct ucred *cred, struct socket *so,
  337     struct sockaddr *sa)
  338 {
  339         int error;
  340 
  341         MAC_POLICY_CHECK_NOSLEEP(socket_check_connect, cred, so,
  342             so->so_label, sa);
  343         MAC_CHECK_PROBE3(socket_check_connect, error, cred, so, sa);
  344 
  345         return (error);
  346 }
  347 
  348 MAC_CHECK_PROBE_DEFINE4(socket_check_create, "struct ucred *", "int", "int",
  349     "int");
  350 
  351 int
  352 mac_socket_check_create(struct ucred *cred, int domain, int type, int proto)
  353 {
  354         int error;
  355 
  356         MAC_POLICY_CHECK_NOSLEEP(socket_check_create, cred, domain, type,
  357             proto);
  358         MAC_CHECK_PROBE4(socket_check_create, error, cred, domain, type,
  359             proto);
  360 
  361         return (error);
  362 }
  363 
  364 MAC_CHECK_PROBE_DEFINE2(socket_check_deliver, "struct socket *",
  365     "struct mbuf *");
  366 
  367 int
  368 mac_socket_check_deliver(struct socket *so, struct mbuf *m)
  369 {
  370         struct label *label;
  371         int error;
  372 
  373         if (mac_policy_count == 0)
  374                 return (0);
  375 
  376         label = mac_mbuf_to_label(m);
  377 
  378         MAC_POLICY_CHECK_NOSLEEP(socket_check_deliver, so, so->so_label, m,
  379             label);
  380         MAC_CHECK_PROBE2(socket_check_deliver, error, so, m);
  381 
  382         return (error);
  383 }
  384 
  385 MAC_CHECK_PROBE_DEFINE2(socket_check_listen, "struct ucred *",
  386     "struct socket *");
  387 
  388 int
  389 mac_socket_check_listen(struct ucred *cred, struct socket *so)
  390 {
  391         int error;
  392 
  393         MAC_POLICY_CHECK_NOSLEEP(socket_check_listen, cred, so,
  394             so->so_label);
  395         MAC_CHECK_PROBE2(socket_check_listen, error, cred, so);
  396 
  397         return (error);
  398 }
  399 
  400 MAC_CHECK_PROBE_DEFINE2(socket_check_poll, "struct ucred *",
  401     "struct socket *");
  402 
  403 int
  404 mac_socket_check_poll(struct ucred *cred, struct socket *so)
  405 {
  406         int error;
  407 
  408         MAC_POLICY_CHECK_NOSLEEP(socket_check_poll, cred, so, so->so_label);
  409         MAC_CHECK_PROBE2(socket_check_poll, error, cred, so);
  410 
  411         return (error);
  412 }
  413 
  414 MAC_CHECK_PROBE_DEFINE2(socket_check_receive, "struct ucred *",
  415     "struct socket *");
  416 
  417 int
  418 mac_socket_check_receive(struct ucred *cred, struct socket *so)
  419 {
  420         int error;
  421 
  422         MAC_POLICY_CHECK_NOSLEEP(socket_check_receive, cred, so,
  423             so->so_label);
  424         MAC_CHECK_PROBE2(socket_check_receive, error, cred, so);
  425 
  426         return (error);
  427 }
  428 
  429 MAC_CHECK_PROBE_DEFINE3(socket_check_relabel, "struct ucred *",
  430     "struct socket *", "struct label *");
  431 
  432 static int
  433 mac_socket_check_relabel(struct ucred *cred, struct socket *so,
  434     struct label *newlabel)
  435 {
  436         int error;
  437 
  438         SOCK_LOCK_ASSERT(so);
  439 
  440         MAC_POLICY_CHECK_NOSLEEP(socket_check_relabel, cred, so,
  441             so->so_label, newlabel);
  442         MAC_CHECK_PROBE3(socket_check_relabel, error, cred, so, newlabel);
  443 
  444         return (error);
  445 }
  446 
  447 MAC_CHECK_PROBE_DEFINE2(socket_check_send, "struct ucred *",
  448     "struct socket *");
  449 
  450 int
  451 mac_socket_check_send(struct ucred *cred, struct socket *so)
  452 {
  453         int error;
  454 
  455         MAC_POLICY_CHECK_NOSLEEP(socket_check_send, cred, so, so->so_label);
  456         MAC_CHECK_PROBE2(socket_check_send, error, cred, so);
  457 
  458         return (error);
  459 }
  460 
  461 MAC_CHECK_PROBE_DEFINE2(socket_check_stat, "struct ucred *",
  462     "struct socket *");
  463 
  464 int
  465 mac_socket_check_stat(struct ucred *cred, struct socket *so)
  466 {
  467         int error;
  468 
  469         MAC_POLICY_CHECK_NOSLEEP(socket_check_stat, cred, so, so->so_label);
  470         MAC_CHECK_PROBE2(socket_check_stat, error, cred, so);
  471 
  472         return (error);
  473 }
  474 
  475 MAC_CHECK_PROBE_DEFINE2(socket_check_visible, "struct ucred *",
  476     "struct socket *");
  477 
  478 int
  479 mac_socket_check_visible(struct ucred *cred, struct socket *so)
  480 {
  481         int error;
  482 
  483         MAC_POLICY_CHECK_NOSLEEP(socket_check_visible, cred, so,
  484             so->so_label);
  485         MAC_CHECK_PROBE2(socket_check_visible, error, cred, so);
  486 
  487         return (error);
  488 }
  489 
  490 int
  491 mac_socket_label_set(struct ucred *cred, struct socket *so,
  492     struct label *label)
  493 {
  494         int error;
  495 
  496         /*
  497          * We acquire the socket lock when we perform the test and set, but
  498          * have to release it as the pcb code needs to acquire the pcb lock,
  499          * which will precede the socket lock in the lock order.  However,
  500          * this is fine, as any race will simply result in the inpcb being
  501          * refreshed twice, but still consistently, as the inpcb code will
  502          * acquire the socket lock before refreshing, holding both locks.
  503          */
  504         SOCK_LOCK(so);
  505         error = mac_socket_check_relabel(cred, so, label);
  506         if (error) {
  507                 SOCK_UNLOCK(so);
  508                 return (error);
  509         }
  510 
  511         mac_socket_relabel(cred, so, label);
  512         SOCK_UNLOCK(so);
  513 
  514         /*
  515          * If the protocol has expressed interest in socket layer changes,
  516          * such as if it needs to propagate changes to a cached pcb label
  517          * from the socket, notify it of the label change while holding the
  518          * socket lock.
  519          */
  520         if (so->so_proto->pr_usrreqs->pru_sosetlabel != NULL)
  521                 (so->so_proto->pr_usrreqs->pru_sosetlabel)(so);
  522 
  523         return (0);
  524 }
  525 
  526 int
  527 mac_setsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac)
  528 {
  529         struct label *intlabel;
  530         char *buffer;
  531         int error;
  532 
  533         if (!(mac_labeled & MPC_OBJECT_SOCKET))
  534                 return (EINVAL);
  535 
  536         error = mac_check_structmac_consistent(mac);
  537         if (error)
  538                 return (error);
  539 
  540         buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
  541         error = copyinstr(mac->m_string, buffer, mac->m_buflen, NULL);
  542         if (error) {
  543                 free(buffer, M_MACTEMP);
  544                 return (error);
  545         }
  546 
  547         intlabel = mac_socket_label_alloc(M_WAITOK);
  548         error = mac_socket_internalize_label(intlabel, buffer);
  549         free(buffer, M_MACTEMP);
  550         if (error)
  551                 goto out;
  552 
  553         error = mac_socket_label_set(cred, so, intlabel);
  554 out:
  555         mac_socket_label_free(intlabel);
  556         return (error);
  557 }
  558 
  559 int
  560 mac_getsockopt_label(struct ucred *cred, struct socket *so, struct mac *mac)
  561 {
  562         char *buffer, *elements;
  563         struct label *intlabel;
  564         int error;
  565 
  566         if (!(mac_labeled & MPC_OBJECT_SOCKET))
  567                 return (EINVAL);
  568 
  569         error = mac_check_structmac_consistent(mac);
  570         if (error)
  571                 return (error);
  572 
  573         elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
  574         error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
  575         if (error) {
  576                 free(elements, M_MACTEMP);
  577                 return (error);
  578         }
  579 
  580         buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
  581         intlabel = mac_socket_label_alloc(M_WAITOK);
  582         SOCK_LOCK(so);
  583         mac_socket_copy_label(so->so_label, intlabel);
  584         SOCK_UNLOCK(so);
  585         error = mac_socket_externalize_label(intlabel, elements, buffer,
  586             mac->m_buflen);
  587         mac_socket_label_free(intlabel);
  588         if (error == 0)
  589                 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
  590 
  591         free(buffer, M_MACTEMP);
  592         free(elements, M_MACTEMP);
  593 
  594         return (error);
  595 }
  596 
  597 int
  598 mac_getsockopt_peerlabel(struct ucred *cred, struct socket *so,
  599     struct mac *mac)
  600 {
  601         char *elements, *buffer;
  602         struct label *intlabel;
  603         int error;
  604 
  605         if (!(mac_labeled & MPC_OBJECT_SOCKET))
  606                 return (EINVAL);
  607 
  608         error = mac_check_structmac_consistent(mac);
  609         if (error)
  610                 return (error);
  611 
  612         elements = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK);
  613         error = copyinstr(mac->m_string, elements, mac->m_buflen, NULL);
  614         if (error) {
  615                 free(elements, M_MACTEMP);
  616                 return (error);
  617         }
  618 
  619         buffer = malloc(mac->m_buflen, M_MACTEMP, M_WAITOK | M_ZERO);
  620         intlabel = mac_socket_label_alloc(M_WAITOK);
  621         SOCK_LOCK(so);
  622         mac_socket_copy_label(so->so_peerlabel, intlabel);
  623         SOCK_UNLOCK(so);
  624         error = mac_socketpeer_externalize_label(intlabel, elements, buffer,
  625             mac->m_buflen);
  626         mac_socket_label_free(intlabel);
  627         if (error == 0)
  628                 error = copyout(buffer, mac->m_string, strlen(buffer)+1);
  629 
  630         free(buffer, M_MACTEMP);
  631         free(elements, M_MACTEMP);
  632 
  633         return (error);
  634 }

Cache object: 6846995472f34633813fd25cbf7d9300


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