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:
parent
a0ccd3f6ad
commit
ef2e1ca561
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user