1c3aac50fSPeter Wemm /* $FreeBSD$ */ 23d903220SDoug Rabson /* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */ 33d903220SDoug Rabson 43d903220SDoug Rabson /* 53d903220SDoug Rabson * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca> 63d903220SDoug Rabson * All rights reserved. 73d903220SDoug Rabson * 83d903220SDoug Rabson * Redistribution and use in source and binary forms, with or without 93d903220SDoug Rabson * modification, are permitted provided that the following conditions 103d903220SDoug Rabson * are met: 113d903220SDoug Rabson * 1. Redistributions of source code must retain the above copyright 123d903220SDoug Rabson * notice, this list of conditions and the following disclaimer. 133d903220SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 143d903220SDoug Rabson * notice, this list of conditions and the following disclaimer in the 153d903220SDoug Rabson * documentation and/or other materials provided with the distribution. 163d903220SDoug Rabson * 3. All advertising materials mentioning features or use of this software 173d903220SDoug Rabson * must display the following acknowledgement: 183d903220SDoug Rabson * This product includes software developed by Herb Peyerl. 193d903220SDoug Rabson * 4. The name of Herb Peyerl may not be used to endorse or promote products 203d903220SDoug Rabson * derived from this software without specific prior written permission. 213d903220SDoug Rabson * 223d903220SDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 233d903220SDoug Rabson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 243d903220SDoug Rabson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 253d903220SDoug Rabson * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 263d903220SDoug Rabson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 273d903220SDoug Rabson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 283d903220SDoug Rabson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 293d903220SDoug Rabson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 303d903220SDoug Rabson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 313d903220SDoug Rabson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 323d903220SDoug Rabson */ 333d903220SDoug Rabson 34511b67b7SGarrett Wollman #include "opt_sysvipc.h" 35511b67b7SGarrett Wollman 363d903220SDoug Rabson #include <sys/param.h> 37cf9fa8e7SPoul-Henning Kamp #include <sys/systm.h> 3878525ce3SAlfred Perlstein #include <sys/sem.h> 3978525ce3SAlfred Perlstein #include <sys/shm.h> 4081090119SPeter Wemm #include <sys/ipc.h> 411c308b81SPoul-Henning Kamp #include <sys/proc.h> 42b7f5d5b5SBruce Evans #include <sys/ucred.h> 4381090119SPeter Wemm 4478525ce3SAlfred Perlstein void (*shmfork_hook)(struct proc *, struct proc *) = NULL; 453db161e0SMatthew Dillon void (*shmexit_hook)(struct vmspace *) = NULL; 4678525ce3SAlfred Perlstein 4778525ce3SAlfred Perlstein /* called from kern_fork.c */ 4878525ce3SAlfred Perlstein void 4978525ce3SAlfred Perlstein shmfork(p1, p2) 5078525ce3SAlfred Perlstein struct proc *p1, *p2; 5178525ce3SAlfred Perlstein { 5278525ce3SAlfred Perlstein 5378525ce3SAlfred Perlstein if (shmfork_hook != NULL) 5478525ce3SAlfred Perlstein shmfork_hook(p1, p2); 5578525ce3SAlfred Perlstein return; 5678525ce3SAlfred Perlstein } 5778525ce3SAlfred Perlstein 5878525ce3SAlfred Perlstein /* called from kern_exit.c */ 5978525ce3SAlfred Perlstein void 603db161e0SMatthew Dillon shmexit(struct vmspace *vm) 6178525ce3SAlfred Perlstein { 6278525ce3SAlfred Perlstein 6378525ce3SAlfred Perlstein if (shmexit_hook != NULL) 643db161e0SMatthew Dillon shmexit_hook(vm); 6578525ce3SAlfred Perlstein return; 6678525ce3SAlfred Perlstein } 673d903220SDoug Rabson 683d903220SDoug Rabson /* 693d903220SDoug Rabson * Check for ipc permission 703d903220SDoug Rabson */ 713d903220SDoug Rabson 723d903220SDoug Rabson int 73b40ce416SJulian Elischer ipcperm(td, perm, mode) 74b40ce416SJulian Elischer struct thread *td; 753d903220SDoug Rabson struct ipc_perm *perm; 763d903220SDoug Rabson int mode; 773d903220SDoug Rabson { 78a854ed98SJohn Baldwin struct ucred *cred = td->td_ucred; 79ef2e1ca5SRobert Watson int error; 803d903220SDoug Rabson 813d903220SDoug Rabson if (cred->cr_uid != perm->cuid && cred->cr_uid != perm->uid) { 82ef2e1ca5SRobert Watson /* 83ef2e1ca5SRobert Watson * For a non-create/owner, we require privilege to 84ef2e1ca5SRobert Watson * modify the object protections. Note: some other 85ef2e1ca5SRobert Watson * implementations permit IPC_M to be delegated to 86ef2e1ca5SRobert Watson * unprivileged non-creator/owner uids/gids. 87ef2e1ca5SRobert Watson */ 88ef2e1ca5SRobert Watson if (mode & IPC_M) { 89ef2e1ca5SRobert Watson error = suser(td); 90ef2e1ca5SRobert Watson if (error) 91ef2e1ca5SRobert Watson return (error); 92ef2e1ca5SRobert Watson } 93ef2e1ca5SRobert Watson /* 94ef2e1ca5SRobert Watson * Try to match against creator/owner group; if not, fall 95ef2e1ca5SRobert Watson * back on other. 96ef2e1ca5SRobert Watson */ 973d903220SDoug Rabson mode >>= 3; 983d903220SDoug Rabson if (!groupmember(perm->gid, cred) && 993d903220SDoug Rabson !groupmember(perm->cgid, cred)) 1003d903220SDoug Rabson mode >>= 3; 101ef2e1ca5SRobert Watson } else { 102ef2e1ca5SRobert Watson /* 103ef2e1ca5SRobert Watson * Always permit the creator/owner to update the object 104ef2e1ca5SRobert Watson * protections regardless of whether the object mode 105ef2e1ca5SRobert Watson * permits it. 106ef2e1ca5SRobert Watson */ 1073d903220SDoug Rabson if (mode & IPC_M) 1083d903220SDoug Rabson return (0); 109ef2e1ca5SRobert Watson } 110a0ccd3f6SRobert Watson 111a0ccd3f6SRobert Watson if ((mode & perm->mode) != mode) { 112a0ccd3f6SRobert Watson if (suser(td) != 0) 113a0ccd3f6SRobert Watson return (EACCES); 114a0ccd3f6SRobert Watson } 115a0ccd3f6SRobert Watson return (0); 1163d903220SDoug Rabson } 117