From owner-p4-projects@FreeBSD.ORG Thu Sep 28 19:38:19 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 8CA9216A60A; Thu, 28 Sep 2006 19:38:19 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4225C16A604 for ; Thu, 28 Sep 2006 19:38:19 +0000 (UTC) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id D054043D4C for ; Thu, 28 Sep 2006 19:38:18 +0000 (GMT) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k8SJcIKs038394 for ; Thu, 28 Sep 2006 19:38:18 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k8SJcI2G038387 for perforce@freebsd.org; Thu, 28 Sep 2006 19:38:18 GMT (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Date: Thu, 28 Sep 2006 19:38:18 GMT Message-Id: <200609281938.k8SJcI2G038387@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Cc: Subject: PERFORCE change 106842 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 28 Sep 2006 19:38:19 -0000 http://perforce.freebsd.org/chv.cgi?CH=106842 Change 106842 by rwatson@rwatson_zoo on 2006/09/28 19:38:05 First cut at revised ipcperm(). Untested. Affected files ... .. //depot/projects/trustedbsd/priv/sys/kern/sysv_ipc.c#2 edit Differences ... ==== //depot/projects/trustedbsd/priv/sys/kern/sysv_ipc.c#2 (text+ko) ==== @@ -1,6 +1,7 @@ /* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */ /*- * Copyright (c) 1994 Herb Peyerl + * Copyright (c) 2006 Robert N. M. Watson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,6 +40,7 @@ #include #include #include +#include #include #include @@ -72,50 +74,73 @@ * Note: The MAC Framework does not require any modifications to the * ipcperm() function, as access control checks are performed throughout the * implementation of each primitive. Those entry point calls complement the - * ipcperm() discertionary checks. + * ipcperm() discertionary checks. Unlike file system discretionary access + * control, the original create of an object is given the same rights as the + * current owner. */ int -ipcperm(td, perm, mode) - struct thread *td; - struct ipc_perm *perm; - int mode; +ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode) { struct ucred *cred = td->td_ucred; - int error; + int error, obj_mode, dac_granted, priv_granted; - if (cred->cr_uid != perm->cuid && cred->cr_uid != perm->uid) { - /* - * 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)) - mode >>= 3; + dac_granted = 0; + if (cred->cr_uid == perm->cuid || cred->cr_uid == perm->uid) { + obj_mode = perm->mode; + dac_granted |= IPC_M; + } else if (groupmember(perm->gid, cred) || + groupmember(perm->cgid, cred)) { + obj_mode = perm->mode; + obj_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); + obj_mode = perm->mode; + obj_mode <<= 6; + } + + /* + * While the System V IPC permission model allows IPC_M to be + * granted, as part of the mode, our implementation requires + * privilege to adminster the object if not the owner or creator. + */ +#if 0 + if (obj_mode & IPC_M) + dac_granted |= IPC_M; +#endif + if (obj_mode & IPC_R) + dac_granted |= IPC_R; + if (obj_mode & IPC_W) + dac_granted |= IPC_W; + + /* + * Simple case: all required rights are granted by DAC. + */ + if ((dac_granted & acc_mode) == acc_mode) + return (0); + + /* + * Privilege is required to satisfy the request. + */ + priv_granted = 0; + if ((acc_mode & IPC_M) && !(dac_granted & IPC_M)) { + error = priv_check(td, PRIV_IPC_ADMIN); + if (error == 0) + priv_granted |= IPC_M; + } + + if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) { + error = priv_check(td, PRIV_IPC_READ); + if (error == 0) + priv_granted |= IPC_R; } - if ((mode & perm->mode) != mode) { - if (suser(td) != 0) - return (EACCES); + if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) { + error = priv_check(td, PRIV_IPC_WRITE); + if (error == 0) + priv_granted |= IPC_W; } - return (0); + + if (((dac_granted | priv_granted) & acc_mode) == acc_mode) + return (0); + else + return (EACCES); }