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/kern/sysv_ipc.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  * SPDX-License-Identifier: BSD-4-Clause
    3  *
    4  * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
    5  * Copyright (c) 2006 nCircle Network Security, Inc.
    6  * All rights reserved.
    7  *
    8  * This software was developed by Robert N. M. Watson for the TrustedBSD
    9  * Project under contract to nCircle Network Security, Inc.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *      This product includes software developed by Herb Peyerl.
   22  * 4. The name of Herb Peyerl may not be used to endorse or promote products
   23  *    derived from this software without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   26  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   27  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   28  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   29  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   30  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   34  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   35  *
   36  * $NetBSD: sysv_ipc.c,v 1.9 1995/06/02 19:04:22 mycroft Exp $
   37  */
   38 
   39 #include <sys/cdefs.h>
   40 __FBSDID("$FreeBSD$");
   41 
   42 #include "opt_sysvipc.h"
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/sem.h>
   47 #include <sys/shm.h>
   48 #include <sys/ipc.h>
   49 #include <sys/priv.h>
   50 #include <sys/proc.h>
   51 #include <sys/ucred.h>
   52 
   53 #ifndef SYSVSHM
   54 void (*shmfork_hook)(struct proc *, struct proc *) = NULL;
   55 void (*shmexit_hook)(struct vmspace *) = NULL;
   56 
   57 /* called from kern_fork.c */
   58 void
   59 shmfork(p1, p2)
   60         struct proc *p1, *p2;
   61 {
   62 
   63         if (shmfork_hook != NULL)
   64                 shmfork_hook(p1, p2);
   65         return;
   66 }
   67 
   68 /* called from kern_exit.c */
   69 void
   70 shmexit(struct vmspace *vm)
   71 {
   72 
   73         if (shmexit_hook != NULL)
   74                 shmexit_hook(vm);
   75         return;
   76 }
   77 #endif
   78 
   79 /*
   80  * Check for IPC permission.
   81  *
   82  * Note: The MAC Framework does not require any modifications to the
   83  * ipcperm() function, as access control checks are performed throughout the
   84  * implementation of each primitive.  Those entry point calls complement the
   85  * ipcperm() discertionary checks.  Unlike file system discretionary access
   86  * control, the original create of an object is given the same rights as the
   87  * current owner.
   88  */
   89 int
   90 ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode)
   91 {
   92         struct ucred *cred = td->td_ucred;
   93         int error, obj_mode, dac_granted, priv_granted;
   94 
   95         dac_granted = 0;
   96         if (cred->cr_uid == perm->cuid || cred->cr_uid == perm->uid) {
   97                 obj_mode = perm->mode;
   98                 dac_granted |= IPC_M;
   99         } else if (groupmember(perm->gid, cred) ||
  100             groupmember(perm->cgid, cred)) {
  101                 obj_mode = perm->mode;
  102                 obj_mode <<= 3;
  103         } else {
  104                 obj_mode = perm->mode;
  105                 obj_mode <<= 6;
  106         }
  107 
  108         /*
  109          * While the System V IPC permission model allows IPC_M to be
  110          * granted, as part of the mode, our implementation requires
  111          * privilege to adminster the object if not the owner or creator.
  112          */
  113 #if 0
  114         if (obj_mode & IPC_M)
  115                 dac_granted |= IPC_M;
  116 #endif
  117         if (obj_mode & IPC_R)
  118                 dac_granted |= IPC_R;
  119         if (obj_mode & IPC_W)
  120                 dac_granted |= IPC_W;
  121 
  122         /*
  123          * Simple case: all required rights are granted by DAC.
  124          */
  125         if ((dac_granted & acc_mode) == acc_mode)
  126                 return (0);
  127 
  128         /*
  129          * Privilege is required to satisfy the request.
  130          */
  131         priv_granted = 0;
  132         if ((acc_mode & IPC_M) && !(dac_granted & IPC_M)) {
  133                 error = priv_check(td, PRIV_IPC_ADMIN);
  134                 if (error == 0)
  135                         priv_granted |= IPC_M;
  136         }
  137 
  138         if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) {
  139                 error = priv_check(td, PRIV_IPC_READ);
  140                 if (error == 0)
  141                         priv_granted |= IPC_R;
  142         }
  143 
  144         if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) {
  145                 error = priv_check(td, PRIV_IPC_WRITE);
  146                 if (error == 0)
  147                         priv_granted |= IPC_W;
  148         }
  149 
  150         if (((dac_granted | priv_granted) & acc_mode) == acc_mode)
  151                 return (0);
  152         else
  153                 return (EACCES);
  154 }
  155 
  156 #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
  157     defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
  158 void
  159 ipcperm_old2new(struct ipc_perm_old *old, struct ipc_perm *new)
  160 {
  161 
  162         new->cuid = old->cuid;
  163         new->cgid = old->cgid;
  164         new->uid = old->uid;
  165         new->gid = old->gid;
  166         new->mode = old->mode;
  167         new->seq = old->seq;
  168         new->key = old->key;
  169 }
  170 
  171 void
  172 ipcperm_new2old(struct ipc_perm *new, struct ipc_perm_old *old)
  173 {
  174 
  175         /* XXX: How to handle ID's > USHORT_MAX? */
  176         old->cuid = new->cuid;
  177         old->cgid = new->cgid;
  178         old->uid = new->uid;
  179         old->gid = new->gid;
  180         old->mode = new->mode;
  181         old->seq = new->seq;
  182         old->key = new->key;
  183 }
  184 #endif
  185 
  186 #ifdef COMPAT_FREEBSD32
  187 #include <sys/mount.h>
  188 #include <sys/socket.h>
  189 #include <compat/freebsd32/freebsd32.h>
  190 #include <compat/freebsd32/freebsd32_ipc.h>
  191 #include <compat/freebsd32/freebsd32_proto.h>
  192 #include <compat/freebsd32/freebsd32_signal.h>
  193 #include <compat/freebsd32/freebsd32_syscall.h>
  194 #include <compat/freebsd32/freebsd32_util.h>
  195 
  196 #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
  197     defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
  198 void
  199 freebsd32_ipcperm_old_in(struct ipc_perm_old32 *ip32, struct ipc_perm *ip)
  200 {
  201 
  202         CP(*ip32, *ip, cuid);
  203         CP(*ip32, *ip, cgid);
  204         CP(*ip32, *ip, uid);
  205         CP(*ip32, *ip, gid);
  206         CP(*ip32, *ip, mode);
  207         CP(*ip32, *ip, seq);
  208         CP(*ip32, *ip, key);
  209 }
  210 
  211 void
  212 freebsd32_ipcperm_old_out(struct ipc_perm *ip, struct ipc_perm_old32 *ip32)
  213 {
  214 
  215         CP(*ip, *ip32, cuid);
  216         CP(*ip, *ip32, cgid);
  217         CP(*ip, *ip32, uid);
  218         CP(*ip, *ip32, gid);
  219         CP(*ip, *ip32, mode);
  220         CP(*ip, *ip32, seq);
  221         CP(*ip, *ip32, key);
  222 }
  223 #endif
  224 
  225 void
  226 freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip)
  227 {
  228 
  229         CP(*ip32, *ip, cuid);
  230         CP(*ip32, *ip, cgid);
  231         CP(*ip32, *ip, uid);
  232         CP(*ip32, *ip, gid);
  233         CP(*ip32, *ip, mode);
  234         CP(*ip32, *ip, seq);
  235         CP(*ip32, *ip, key);
  236 }
  237 
  238 void
  239 freebsd32_ipcperm_out(struct ipc_perm *ip, struct ipc_perm32 *ip32)
  240 {
  241 
  242         CP(*ip, *ip32, cuid);
  243         CP(*ip, *ip32, cgid);
  244         CP(*ip, *ip32, uid);
  245         CP(*ip, *ip32, gid);
  246         CP(*ip, *ip32, mode);
  247         CP(*ip, *ip32, seq);
  248         CP(*ip, *ip32, key);
  249 }
  250 #endif

Cache object: 99a7dd1a2f37534fb433b4008c228dfe


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