aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugh Dickins <hugh@veritas.com>2004-12-12 16:30:17 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-12 16:30:17 -0800
commit2637792e3d9ae50079238615fd16384a0d393b30 (patch)
tree5da7def81f5d85c73c4fac3b93587d61432dd3e1
parent84aff047e62fabd204e8c73ea19b7ec173aa48af (diff)
downloadhistory-2637792e3d9ae50079238615fd16384a0d393b30.tar.gz
[PATCH] shmctl SHM_LOCK perms
Michael Kerrisk has observed that at present any process can SHM_LOCK any shm segment of size within process RLIMIT_MEMLOCK, despite having no permissions on the segment: surprising, though not obviously evil. And any process can SHM_UNLOCK any shm segment, despite no permissions on it: that is surely wrong. Unless CAP_IPC_LOCK, restrict both SHM_LOCK and SHM_UNLOCK to when the process euid matches the shm owner or creator: that seems the least surprising behaviour, which could be relaxed if a need appears later. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--ipc/shm.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/ipc/shm.c b/ipc/shm.c
index f5ca90c8addb5..dcdc6d5e22bcb 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -511,11 +511,6 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
case SHM_LOCK:
case SHM_UNLOCK:
{
- /* Allow superuser to lock segment in memory */
- if (!can_do_mlock() && cmd == SHM_LOCK) {
- err = -EPERM;
- goto out;
- }
shp = shm_lock(shmid);
if(shp==NULL) {
err = -EINVAL;
@@ -525,6 +520,16 @@ asmlinkage long sys_shmctl (int shmid, int cmd, struct shmid_ds __user *buf)
if(err)
goto out_unlock;
+ if (!capable(CAP_IPC_LOCK)) {
+ err = -EPERM;
+ if (current->euid != shp->shm_perm.uid &&
+ current->euid != shp->shm_perm.cuid)
+ goto out_unlock;
+ if (cmd == SHM_LOCK &&
+ !current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur)
+ goto out_unlock;
+ }
+
err = security_shm_shmctl(shp, cmd);
if (err)
goto out_unlock;