diff options
author | rwatson <rwatson@FreeBSD.org> | 2003-05-31 23:31:51 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2003-05-31 23:31:51 +0000 |
commit | 3a7cb1d1fd42266766c479ac4ec39d5bc134100e (patch) | |
tree | 2a61f2f25d62c245f87526671c7a5ee2173365e9 /sys/kern/sysv_ipc.c | |
parent | 55281b2df1a73b8c39406da931d4fb59b215d054 (diff) | |
download | FreeBSD-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.c | 33 |
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); |