From: Hugh Dickins 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 --- 25-akpm/ipc/shm.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-) diff -puN ipc/shm.c~shmctl-shm_lock-perms ipc/shm.c --- 25/ipc/shm.c~shmctl-shm_lock-perms Mon Nov 29 13:17:11 2004 +++ 25-akpm/ipc/shm.c Mon Nov 29 13:17:11 2004 @@ -511,11 +511,6 @@ asmlinkage long sys_shmctl (int shmid, i 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, i 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; _