blob: 66e4520909ed1a14415c45872371aa01e3abaca8 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
# 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 <hugh@veritas.com>
# Signed-off-by: Andrew Morton <akpm@osdl.org>
# Signed-off-by: Linus Torvalds <torvalds@osdl.org>
#
# 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)
|