13d903220SDoug Rabson /* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */ 23d903220SDoug Rabson /* 33d903220SDoug Rabson * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca> 43d903220SDoug Rabson * All rights reserved. 53d903220SDoug Rabson * 63d903220SDoug Rabson * Redistribution and use in source and binary forms, with or without 73d903220SDoug Rabson * modification, are permitted provided that the following conditions 83d903220SDoug Rabson * are met: 93d903220SDoug Rabson * 1. Redistributions of source code must retain the above copyright 103d903220SDoug Rabson * notice, this list of conditions and the following disclaimer. 113d903220SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 123d903220SDoug Rabson * notice, this list of conditions and the following disclaimer in the 133d903220SDoug Rabson * documentation and/or other materials provided with the distribution. 143d903220SDoug Rabson * 3. All advertising materials mentioning features or use of this software 153d903220SDoug Rabson * must display the following acknowledgement: 163d903220SDoug Rabson * This product includes software developed by Herb Peyerl. 173d903220SDoug Rabson * 4. The name of Herb Peyerl may not be used to endorse or promote products 183d903220SDoug Rabson * derived from this software without specific prior written permission. 193d903220SDoug Rabson * 203d903220SDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 213d903220SDoug Rabson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 223d903220SDoug Rabson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 233d903220SDoug Rabson * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 243d903220SDoug Rabson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 253d903220SDoug Rabson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 263d903220SDoug Rabson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 273d903220SDoug Rabson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 283d903220SDoug Rabson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 293d903220SDoug Rabson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303d903220SDoug Rabson */ 313d903220SDoug Rabson 32677b542eSDavid E. O'Brien #include <sys/cdefs.h> 33677b542eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 34677b542eSDavid E. O'Brien 35511b67b7SGarrett Wollman #include "opt_sysvipc.h" 36511b67b7SGarrett Wollman 373d903220SDoug Rabson #include <sys/param.h> 38cf9fa8e7SPoul-Henning Kamp #include <sys/systm.h> 3978525ce3SAlfred Perlstein #include <sys/sem.h> 4078525ce3SAlfred Perlstein #include <sys/shm.h> 4181090119SPeter Wemm #include <sys/ipc.h> 421c308b81SPoul-Henning Kamp #include <sys/proc.h> 43b7f5d5b5SBruce Evans #include <sys/ucred.h> 4481090119SPeter Wemm 4578525ce3SAlfred Perlstein void (*shmfork_hook)(struct proc *, struct proc *) = NULL; 463db161e0SMatthew Dillon void (*shmexit_hook)(struct vmspace *) = NULL; 4778525ce3SAlfred Perlstein 4878525ce3SAlfred Perlstein /* called from kern_fork.c */ 4978525ce3SAlfred Perlstein void 5078525ce3SAlfred Perlstein shmfork(p1, p2) 5178525ce3SAlfred Perlstein struct proc *p1, *p2; 5278525ce3SAlfred Perlstein { 5378525ce3SAlfred Perlstein 5478525ce3SAlfred Perlstein if (shmfork_hook != NULL) 5578525ce3SAlfred Perlstein shmfork_hook(p1, p2); 5678525ce3SAlfred Perlstein return; 5778525ce3SAlfred Perlstein } 5878525ce3SAlfred Perlstein 5978525ce3SAlfred Perlstein /* called from kern_exit.c */ 6078525ce3SAlfred Perlstein void 613db161e0SMatthew Dillon shmexit(struct vmspace *vm) 6278525ce3SAlfred Perlstein { 6378525ce3SAlfred Perlstein 6478525ce3SAlfred Perlstein if (shmexit_hook != NULL) 653db161e0SMatthew Dillon shmexit_hook(vm); 6678525ce3SAlfred Perlstein return; 6778525ce3SAlfred Perlstein } 683d903220SDoug Rabson 693d903220SDoug Rabson /* 70857a6005SRobert Watson * Check for IPC permission. 71857a6005SRobert Watson * 72857a6005SRobert Watson * Note: The MAC Framework does not require any modifications to the 73857a6005SRobert Watson * ipcperm() function, as access control checks are performed throughout the 74857a6005SRobert Watson * implementation of each primitive. Those entry point calls complement the 75857a6005SRobert Watson * ipcperm() discertionary checks. 763d903220SDoug Rabson */ 773d903220SDoug Rabson int 78b40ce416SJulian Elischer ipcperm(td, perm, mode) 79b40ce416SJulian Elischer struct thread *td; 803d903220SDoug Rabson struct ipc_perm *perm; 813d903220SDoug Rabson int mode; 823d903220SDoug Rabson { 83a854ed98SJohn Baldwin struct ucred *cred = td->td_ucred; 84ef2e1ca5SRobert Watson int error; 853d903220SDoug Rabson 863d903220SDoug Rabson if (cred->cr_uid != perm->cuid && cred->cr_uid != perm->uid) { 87ef2e1ca5SRobert Watson /* 88ef2e1ca5SRobert Watson * For a non-create/owner, we require privilege to 89ef2e1ca5SRobert Watson * modify the object protections. Note: some other 90ef2e1ca5SRobert Watson * implementations permit IPC_M to be delegated to 91ef2e1ca5SRobert Watson * unprivileged non-creator/owner uids/gids. 92ef2e1ca5SRobert Watson */ 93ef2e1ca5SRobert Watson if (mode & IPC_M) { 94ef2e1ca5SRobert Watson error = suser(td); 95ef2e1ca5SRobert Watson if (error) 96ef2e1ca5SRobert Watson return (error); 97ef2e1ca5SRobert Watson } 98ef2e1ca5SRobert Watson /* 99ef2e1ca5SRobert Watson * Try to match against creator/owner group; if not, fall 100ef2e1ca5SRobert Watson * back on other. 101ef2e1ca5SRobert Watson */ 1023d903220SDoug Rabson mode >>= 3; 1033d903220SDoug Rabson if (!groupmember(perm->gid, cred) && 1043d903220SDoug Rabson !groupmember(perm->cgid, cred)) 1053d903220SDoug Rabson mode >>= 3; 106ef2e1ca5SRobert Watson } else { 107ef2e1ca5SRobert Watson /* 108ef2e1ca5SRobert Watson * Always permit the creator/owner to update the object 109ef2e1ca5SRobert Watson * protections regardless of whether the object mode 110ef2e1ca5SRobert Watson * permits it. 111ef2e1ca5SRobert Watson */ 1123d903220SDoug Rabson if (mode & IPC_M) 1133d903220SDoug Rabson return (0); 114ef2e1ca5SRobert Watson } 115a0ccd3f6SRobert Watson 116a0ccd3f6SRobert Watson if ((mode & perm->mode) != mode) { 117a0ccd3f6SRobert Watson if (suser(td) != 0) 118a0ccd3f6SRobert Watson return (EACCES); 119a0ccd3f6SRobert Watson } 120a0ccd3f6SRobert Watson return (0); 1213d903220SDoug Rabson } 122