summaryrefslogtreecommitdiffstats
path: root/sys/kern/sysv_ipc.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2003-05-31 23:31:51 +0000
committerrwatson <rwatson@FreeBSD.org>2003-05-31 23:31:51 +0000
commit3a7cb1d1fd42266766c479ac4ec39d5bc134100e (patch)
tree2a61f2f25d62c245f87526671c7a5ee2173365e9 /sys/kern/sysv_ipc.c
parent55281b2df1a73b8c39406da931d4fb59b215d054 (diff)
downloadFreeBSD-src-3a7cb1d1fd42266766c479ac4ec39d5bc134100e.zip
FreeBSD-src-3a7cb1d1fd42266766c479ac4ec39d5bc134100e.tar.gz
Attempt to further comment and clarify System V IPC logic: document
why certain exceptions are made, note an inconsistency between FreeBSD and some other implementations regarding IPC_M, and let suser() generate our EPERM rather than forcing it ourselves. Remove a carriage return that crept in in the last commit. Reviewed by: gordon Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories
Diffstat (limited to 'sys/kern/sysv_ipc.c')
-rw-r--r--sys/kern/sysv_ipc.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c
index 30939e4..bf91258 100644
--- a/sys/kern/sysv_ipc.c
+++ b/sys/kern/sysv_ipc.c
@@ -76,23 +76,38 @@ ipcperm(td, perm, mode)
int mode;
{
struct ucred *cred = td->td_ucred;
+ int error;
- /* Check for user match. */
if (cred->cr_uid != perm->cuid && cred->cr_uid != perm->uid) {
- if (mode & IPC_M)
- return (suser(td) == 0 ? 0 : EPERM);
- /* Check for group match. */
+ /*
+ * For a non-create/owner, we require privilege to
+ * modify the object protections. Note: some other
+ * implementations permit IPC_M to be delegated to
+ * unprivileged non-creator/owner uids/gids.
+ */
+ if (mode & IPC_M) {
+ error = suser(td);
+ if (error)
+ return (error);
+ }
+ /*
+ * Try to match against creator/owner group; if not, fall
+ * back on other.
+ */
mode >>= 3;
if (!groupmember(perm->gid, cred) &&
!groupmember(perm->cgid, cred))
- /* Check for `other' match. */
mode >>= 3;
+ } else {
+ /*
+ * Always permit the creator/owner to update the object
+ * protections regardless of whether the object mode
+ * permits it.
+ */
+ if (mode & IPC_M)
+ return (0);
}
- if (mode & IPC_M)
- return (0);
-
-
if ((mode & perm->mode) != mode) {
if (suser(td) != 0)
return (EACCES);
OpenPOWER on IntegriCloud