13d903220SDoug Rabson /* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */ 29454b2d8SWarner Losh /*- 33d903220SDoug Rabson * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca> 4b12c55abSRobert Watson * Copyright (c) 2006 nCircle Network Security, Inc. 53d903220SDoug Rabson * All rights reserved. 63d903220SDoug Rabson * 7b12c55abSRobert Watson * This software was developed by Robert N. M. Watson for the TrustedBSD 8b12c55abSRobert Watson * Project under contract to nCircle Network Security, Inc. 9b12c55abSRobert Watson * 103d903220SDoug Rabson * Redistribution and use in source and binary forms, with or without 113d903220SDoug Rabson * modification, are permitted provided that the following conditions 123d903220SDoug Rabson * are met: 133d903220SDoug Rabson * 1. Redistributions of source code must retain the above copyright 143d903220SDoug Rabson * notice, this list of conditions and the following disclaimer. 153d903220SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 163d903220SDoug Rabson * notice, this list of conditions and the following disclaimer in the 173d903220SDoug Rabson * documentation and/or other materials provided with the distribution. 183d903220SDoug Rabson * 3. All advertising materials mentioning features or use of this software 193d903220SDoug Rabson * must display the following acknowledgement: 203d903220SDoug Rabson * This product includes software developed by Herb Peyerl. 213d903220SDoug Rabson * 4. The name of Herb Peyerl may not be used to endorse or promote products 223d903220SDoug Rabson * derived from this software without specific prior written permission. 233d903220SDoug Rabson * 243d903220SDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 253d903220SDoug Rabson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 263d903220SDoug Rabson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 273d903220SDoug Rabson * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 283d903220SDoug Rabson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 293d903220SDoug Rabson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 303d903220SDoug Rabson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 313d903220SDoug Rabson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 323d903220SDoug Rabson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 333d903220SDoug Rabson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 343d903220SDoug Rabson */ 353d903220SDoug Rabson 36677b542eSDavid E. O'Brien #include <sys/cdefs.h> 37677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 38677b542eSDavid E. O'Brien 39511b67b7SGarrett Wollman #include "opt_sysvipc.h" 40511b67b7SGarrett Wollman 413d903220SDoug Rabson #include <sys/param.h> 42cf9fa8e7SPoul-Henning Kamp #include <sys/systm.h> 4378525ce3SAlfred Perlstein #include <sys/sem.h> 4478525ce3SAlfred Perlstein #include <sys/shm.h> 4581090119SPeter Wemm #include <sys/ipc.h> 46b12c55abSRobert Watson #include <sys/priv.h> 471c308b81SPoul-Henning Kamp #include <sys/proc.h> 48b7f5d5b5SBruce Evans #include <sys/ucred.h> 4981090119SPeter Wemm 5078525ce3SAlfred Perlstein void (*shmfork_hook)(struct proc *, struct proc *) = NULL; 513db161e0SMatthew Dillon void (*shmexit_hook)(struct vmspace *) = NULL; 5278525ce3SAlfred Perlstein 5378525ce3SAlfred Perlstein /* called from kern_fork.c */ 5478525ce3SAlfred Perlstein void 5578525ce3SAlfred Perlstein shmfork(p1, p2) 5678525ce3SAlfred Perlstein struct proc *p1, *p2; 5778525ce3SAlfred Perlstein { 5878525ce3SAlfred Perlstein 5978525ce3SAlfred Perlstein if (shmfork_hook != NULL) 6078525ce3SAlfred Perlstein shmfork_hook(p1, p2); 6178525ce3SAlfred Perlstein return; 6278525ce3SAlfred Perlstein } 6378525ce3SAlfred Perlstein 6478525ce3SAlfred Perlstein /* called from kern_exit.c */ 6578525ce3SAlfred Perlstein void 663db161e0SMatthew Dillon shmexit(struct vmspace *vm) 6778525ce3SAlfred Perlstein { 6878525ce3SAlfred Perlstein 6978525ce3SAlfred Perlstein if (shmexit_hook != NULL) 703db161e0SMatthew Dillon shmexit_hook(vm); 7178525ce3SAlfred Perlstein return; 7278525ce3SAlfred Perlstein } 733d903220SDoug Rabson 743d903220SDoug Rabson /* 75857a6005SRobert Watson * Check for IPC permission. 76857a6005SRobert Watson * 77857a6005SRobert Watson * Note: The MAC Framework does not require any modifications to the 78857a6005SRobert Watson * ipcperm() function, as access control checks are performed throughout the 79857a6005SRobert Watson * implementation of each primitive. Those entry point calls complement the 80b12c55abSRobert Watson * ipcperm() discertionary checks. Unlike file system discretionary access 81b12c55abSRobert Watson * control, the original create of an object is given the same rights as the 82b12c55abSRobert Watson * current owner. 833d903220SDoug Rabson */ 843d903220SDoug Rabson int 85b12c55abSRobert Watson ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode) 863d903220SDoug Rabson { 87a854ed98SJohn Baldwin struct ucred *cred = td->td_ucred; 88b12c55abSRobert Watson int error, obj_mode, dac_granted, priv_granted; 893d903220SDoug Rabson 90b12c55abSRobert Watson dac_granted = 0; 91b12c55abSRobert Watson if (cred->cr_uid == perm->cuid || cred->cr_uid == perm->uid) { 92b12c55abSRobert Watson obj_mode = perm->mode; 93b12c55abSRobert Watson dac_granted |= IPC_M; 94b12c55abSRobert Watson } else if (groupmember(perm->gid, cred) || 95b12c55abSRobert Watson groupmember(perm->cgid, cred)) { 96b12c55abSRobert Watson obj_mode = perm->mode; 97b12c55abSRobert Watson obj_mode <<= 3; 98ef2e1ca5SRobert Watson } else { 99b12c55abSRobert Watson obj_mode = perm->mode; 100b12c55abSRobert Watson obj_mode <<= 6; 101acd3428bSRobert Watson } 102acd3428bSRobert Watson 103b12c55abSRobert Watson /* 104b12c55abSRobert Watson * While the System V IPC permission model allows IPC_M to be 105b12c55abSRobert Watson * granted, as part of the mode, our implementation requires 106b12c55abSRobert Watson * privilege to adminster the object if not the owner or creator. 107b12c55abSRobert Watson */ 108b12c55abSRobert Watson #if 0 109b12c55abSRobert Watson if (obj_mode & IPC_M) 110b12c55abSRobert Watson dac_granted |= IPC_M; 111b12c55abSRobert Watson #endif 112b12c55abSRobert Watson if (obj_mode & IPC_R) 113b12c55abSRobert Watson dac_granted |= IPC_R; 114b12c55abSRobert Watson if (obj_mode & IPC_W) 115b12c55abSRobert Watson dac_granted |= IPC_W; 116b12c55abSRobert Watson 117b12c55abSRobert Watson /* 118b12c55abSRobert Watson * Simple case: all required rights are granted by DAC. 119b12c55abSRobert Watson */ 120b12c55abSRobert Watson if ((dac_granted & acc_mode) == acc_mode) 1219ac57410SRobert Watson return (0); 122b12c55abSRobert Watson 123b12c55abSRobert Watson /* 124b12c55abSRobert Watson * Privilege is required to satisfy the request. 125b12c55abSRobert Watson */ 126b12c55abSRobert Watson priv_granted = 0; 127b12c55abSRobert Watson if ((acc_mode & IPC_M) && !(dac_granted & IPC_M)) { 128b12c55abSRobert Watson error = priv_check(td, PRIV_IPC_ADMIN); 129b12c55abSRobert Watson if (error == 0) 130b12c55abSRobert Watson priv_granted |= IPC_M; 131b12c55abSRobert Watson } 132b12c55abSRobert Watson 133b12c55abSRobert Watson if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) { 134b12c55abSRobert Watson error = priv_check(td, PRIV_IPC_READ); 135b12c55abSRobert Watson if (error == 0) 136b12c55abSRobert Watson priv_granted |= IPC_R; 137b12c55abSRobert Watson } 138b12c55abSRobert Watson 139b12c55abSRobert Watson if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) { 140b12c55abSRobert Watson error = priv_check(td, PRIV_IPC_WRITE); 141b12c55abSRobert Watson if (error == 0) 142b12c55abSRobert Watson priv_granted |= IPC_W; 143b12c55abSRobert Watson } 144b12c55abSRobert Watson 145b12c55abSRobert Watson if (((dac_granted | priv_granted) & acc_mode) == acc_mode) 146b12c55abSRobert Watson return (0); 147b12c55abSRobert Watson else 148b12c55abSRobert Watson return (EACCES); 1499ac57410SRobert Watson } 150