diff options
author | Davidlohr Bueso <davidlohr.bueso@hp.com> | 2013-09-11 17:26:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-11 18:59:42 -0400 |
commit | c2c737a0461e61a34676bd0bd1bc1a70a1b4e396 (patch) | |
tree | f8d9d21cbc43ac12a67bbc428cab083adb31cd30 /ipc/shm.c | |
parent | f42569b1388b1408b574a5e93a23a663647d4181 (diff) |
ipc,shm: shorten critical region for shmat
Similar to other system calls, acquire the kern_ipc_perm lock after doing
the initial permission and security checks.
[sasha.levin@oracle.com: dont leave do_shmat with rcu lock held]
Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Cc: Rik van Riel <riel@redhat.com>
Cc: Manfred Spraul <manfred@colorfullife.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'ipc/shm.c')
-rw-r--r-- | ipc/shm.c | 14 |
1 files changed, 10 insertions, 4 deletions
@@ -19,6 +19,9 @@ | |||
19 | * namespaces support | 19 | * namespaces support |
20 | * OpenVZ, SWsoft Inc. | 20 | * OpenVZ, SWsoft Inc. |
21 | * Pavel Emelianov <xemul@openvz.org> | 21 | * Pavel Emelianov <xemul@openvz.org> |
22 | * | ||
23 | * Better ipc lock (kern_ipc_perm.lock) handling | ||
24 | * Davidlohr Bueso <davidlohr.bueso@hp.com>, June 2013. | ||
22 | */ | 25 | */ |
23 | 26 | ||
24 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
@@ -1086,10 +1089,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, | |||
1086 | * additional creator id... | 1089 | * additional creator id... |
1087 | */ | 1090 | */ |
1088 | ns = current->nsproxy->ipc_ns; | 1091 | ns = current->nsproxy->ipc_ns; |
1089 | shp = shm_lock_check(ns, shmid); | 1092 | rcu_read_lock(); |
1093 | shp = shm_obtain_object_check(ns, shmid); | ||
1090 | if (IS_ERR(shp)) { | 1094 | if (IS_ERR(shp)) { |
1091 | err = PTR_ERR(shp); | 1095 | err = PTR_ERR(shp); |
1092 | goto out; | 1096 | goto out_unlock; |
1093 | } | 1097 | } |
1094 | 1098 | ||
1095 | err = -EACCES; | 1099 | err = -EACCES; |
@@ -1100,11 +1104,13 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr, | |||
1100 | if (err) | 1104 | if (err) |
1101 | goto out_unlock; | 1105 | goto out_unlock; |
1102 | 1106 | ||
1107 | ipc_lock_object(&shp->shm_perm); | ||
1103 | path = shp->shm_file->f_path; | 1108 | path = shp->shm_file->f_path; |
1104 | path_get(&path); | 1109 | path_get(&path); |
1105 | shp->shm_nattch++; | 1110 | shp->shm_nattch++; |
1106 | size = i_size_read(path.dentry->d_inode); | 1111 | size = i_size_read(path.dentry->d_inode); |
1107 | shm_unlock(shp); | 1112 | ipc_unlock_object(&shp->shm_perm); |
1113 | rcu_read_unlock(); | ||
1108 | 1114 | ||
1109 | err = -ENOMEM; | 1115 | err = -ENOMEM; |
1110 | sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); | 1116 | sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); |
@@ -1175,7 +1181,7 @@ out_nattch: | |||
1175 | return err; | 1181 | return err; |
1176 | 1182 | ||
1177 | out_unlock: | 1183 | out_unlock: |
1178 | shm_unlock(shp); | 1184 | rcu_read_unlock(); |
1179 | out: | 1185 | out: |
1180 | return err; | 1186 | return err; |
1181 | } | 1187 | } |