xref: /freebsd/sys/kern/sysv_ipc.c (revision 857a600580685f08dc13e7ffc4f01745e8501049)
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