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
This commit is contained in:
Robert Watson 2003-05-31 23:31:51 +00:00
parent a0ccd3f6ad
commit ef2e1ca561
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=115580

View File

@ -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);