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> 4acd3428bSRobert Watson * Copyright (c) 2006 nCircle Network Security, Inc. 53d903220SDoug Rabson * All rights reserved. 63d903220SDoug Rabson * 7acd3428bSRobert Watson * This software was developed by Robert N. M. Watson for the TrustedBSD 8acd3428bSRobert Watson * Project under contract to nCircle Network Security, Inc. 9acd3428bSRobert 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> 46acd3428bSRobert 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 80acd3428bSRobert Watson * ipcperm() discertionary checks. Unlike file system discretionary access 81acd3428bSRobert Watson * control, the original create of an object is given the same rights as the 82acd3428bSRobert Watson * current owner. 833d903220SDoug Rabson */ 843d903220SDoug Rabson int 85acd3428bSRobert Watson ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode) 863d903220SDoug Rabson { 87a854ed98SJohn Baldwin struct ucred *cred = td->td_ucred; 88acd3428bSRobert Watson int error, obj_mode, dac_granted, priv_granted; 893d903220SDoug Rabson 90acd3428bSRobert Watson dac_granted = 0; 91acd3428bSRobert Watson if (cred->cr_uid == perm->cuid || cred->cr_uid == perm->uid) { 92acd3428bSRobert Watson obj_mode = perm->mode; 93acd3428bSRobert Watson dac_granted |= IPC_M; 94acd3428bSRobert Watson } else if (groupmember(perm->gid, cred) || 95acd3428bSRobert Watson groupmember(perm->cgid, cred)) { 96acd3428bSRobert Watson obj_mode = perm->mode; 97acd3428bSRobert Watson obj_mode <<= 3; 98ef2e1ca5SRobert Watson } else { 99acd3428bSRobert Watson obj_mode = perm->mode; 100acd3428bSRobert Watson obj_mode <<= 6; 101ef2e1ca5SRobert Watson } 102a0ccd3f6SRobert Watson 103acd3428bSRobert Watson /* 104acd3428bSRobert Watson * While the System V IPC permission model allows IPC_M to be 105acd3428bSRobert Watson * granted, as part of the mode, our implementation requires 106acd3428bSRobert Watson * privilege to adminster the object if not the owner or creator. 107acd3428bSRobert Watson */ 108acd3428bSRobert Watson #if 0 109acd3428bSRobert Watson if (obj_mode & IPC_M) 110acd3428bSRobert Watson dac_granted |= IPC_M; 111acd3428bSRobert Watson #endif 112acd3428bSRobert Watson if (obj_mode & IPC_R) 113acd3428bSRobert Watson dac_granted |= IPC_R; 114acd3428bSRobert Watson if (obj_mode & IPC_W) 115acd3428bSRobert Watson dac_granted |= IPC_W; 116acd3428bSRobert Watson 117acd3428bSRobert Watson /* 118acd3428bSRobert Watson * Simple case: all required rights are granted by DAC. 119acd3428bSRobert Watson */ 120acd3428bSRobert Watson if ((dac_granted & acc_mode) == acc_mode) 121a0ccd3f6SRobert Watson return (0); 122acd3428bSRobert Watson 123acd3428bSRobert Watson /* 124acd3428bSRobert Watson * Privilege is required to satisfy the request. 125acd3428bSRobert Watson */ 126acd3428bSRobert Watson priv_granted = 0; 127acd3428bSRobert Watson if ((acc_mode & IPC_M) && !(dac_granted & IPC_M)) { 128acd3428bSRobert Watson error = priv_check(td, PRIV_IPC_ADMIN); 129acd3428bSRobert Watson if (error == 0) 130acd3428bSRobert Watson priv_granted |= IPC_M; 131acd3428bSRobert Watson } 132acd3428bSRobert Watson 133acd3428bSRobert Watson if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) { 134acd3428bSRobert Watson error = priv_check(td, PRIV_IPC_READ); 135acd3428bSRobert Watson if (error == 0) 136acd3428bSRobert Watson priv_granted |= IPC_R; 137acd3428bSRobert Watson } 138acd3428bSRobert Watson 139acd3428bSRobert Watson if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) { 140acd3428bSRobert Watson error = priv_check(td, PRIV_IPC_WRITE); 141acd3428bSRobert Watson if (error == 0) 142acd3428bSRobert Watson priv_granted |= IPC_W; 143acd3428bSRobert Watson } 144acd3428bSRobert Watson 145acd3428bSRobert Watson if (((dac_granted | priv_granted) & acc_mode) == acc_mode) 146acd3428bSRobert Watson return (0); 147acd3428bSRobert Watson else 148acd3428bSRobert Watson return (EACCES); 1493d903220SDoug Rabson } 150