From ef2e1ca5612b8bc42198c9c34d6447578099945a Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Sat, 31 May 2003 23:31:51 +0000 Subject: [PATCH] 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 --- sys/kern/sysv_ipc.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c index 30939e4bd015..bf91258fb15d 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);