summaryrefslogtreecommitdiffstats
path: root/sys/kern/sysv_ipc.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-12-16 11:30:54 +0000
committerrwatson <rwatson@FreeBSD.org>2006-12-16 11:30:54 +0000
commit4d1fe0d4258ab77e3ac80848b6209a996f1f3c57 (patch)
tree449da2a473388d25f5b3f180f8b7daea92cbf338 /sys/kern/sysv_ipc.c
parent38887bc05dfc35770cb63b5b74433a3da62f4c62 (diff)
downloadFreeBSD-src-4d1fe0d4258ab77e3ac80848b6209a996f1f3c57.zip
FreeBSD-src-4d1fe0d4258ab77e3ac80848b6209a996f1f3c57.tar.gz
For now, back out sysv_ipc.c:1.30, which caused shmget() with odd mode
arguments to fail. The mode field for shmget() appears to have undefined meaning in the context of an already-present IPC object, but applications appear to assume any arbitrary passed value will be ignored. I had hoped to revisit this more quickly, but am removing the change for now to prevent toe-stubbing. Reported by: JAroslav Suchanek <jarda at grisoft dot cz> PR: kern/106078
Diffstat (limited to 'sys/kern/sysv_ipc.c')
-rw-r--r--sys/kern/sysv_ipc.c104
1 files changed, 38 insertions, 66 deletions
diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c
index 0cbb4bb..8fec1da 100644
--- a/sys/kern/sysv_ipc.c
+++ b/sys/kern/sysv_ipc.c
@@ -1,12 +1,8 @@
/* $NetBSD: sysv_ipc.c,v 1.7 1994/06/29 06:33:11 cgd Exp $ */
/*-
* Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
- * Copyright (c) 2006 nCircle Network Security, Inc.
* All rights reserved.
*
- * This software was developed by Robert N. M. Watson for the TrustedBSD
- * Project under contract to nCircle Network Security, Inc.
- *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -43,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/ipc.h>
-#include <sys/priv.h>
#include <sys/proc.h>
#include <sys/ucred.h>
@@ -77,73 +72,50 @@ shmexit(struct vmspace *vm)
* 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. Unlike file system discretionary access
- * control, the original create of an object is given the same rights as the
- * current owner.
+ * ipcperm() discertionary checks.
*/
int
-ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode)
+ipcperm(td, perm, mode)
+ struct thread *td;
+ struct ipc_perm *perm;
+ int mode;
{
struct ucred *cred = td->td_ucred;
- int error, obj_mode, dac_granted, priv_granted;
-
- 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;
+ int error;
+
+ 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;
} else {
- obj_mode = perm->mode;
- obj_mode <<= 6;
+ /*
+ * Always permit the creator/owner to update the object
+ * protections regardless of whether the object mode
+ * permits it.
+ */
+ if (mode & IPC_M)
+ return (0);
}
- /*
- * 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 ((mode & perm->mode) != mode) {
+ if (suser(td) != 0)
+ return (EACCES);
}
-
- if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) {
- error = priv_check(td, PRIV_IPC_READ);
- if (error == 0)
- priv_granted |= IPC_R;
- }
-
- if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) {
- error = priv_check(td, PRIV_IPC_WRITE);
- if (error == 0)
- priv_granted |= IPC_W;
- }
-
- if (((dac_granted | priv_granted) & acc_mode) == acc_mode)
- return (0);
- else
- return (EACCES);
+ return (0);
}
OpenPOWER on IntegriCloud