From 2637792e3d9ae50079238615fd16384a0d393b30 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Sun, 12 Dec 2004 16:30:17 -0800 Subject: [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 Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- ipc/shm.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ipc/shm.c b/ipc/shm.c index f5ca90c8addb5d..dcdc6d5e22bcb0 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; -- cgit 1.2.3-korg