# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/12/13 08:30:17-08:00 hugh@veritas.com # [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 # 2004/12/13 02:47:27-08:00 hugh@veritas.com +10 -5 # shmctl SHM_LOCK perms # diff -Nru a/ipc/shm.c b/ipc/shm.c --- a/ipc/shm.c 2004-12-20 10:32:59 -08:00 +++ b/ipc/shm.c 2004-12-20 10:32:59 -08:00 @@ -511,11 +511,6 @@ 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; @@ -524,6 +519,16 @@ err = shm_checkid(shp,shmid); 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->rlim[RLIMIT_MEMLOCK].rlim_cur) + goto out_unlock; + } err = security_shm_shmctl(shp, cmd); if (err)