]>
Commit | Line | Data |
---|---|---|
d66c7e8f GKH |
1 | From c2c737a0461e61a34676bd0bd1bc1a70a1b4e396 Mon Sep 17 00:00:00 2001 |
2 | From: Davidlohr Bueso <davidlohr.bueso@hp.com> | |
3 | Date: Wed, 11 Sep 2013 14:26:23 -0700 | |
4 | Subject: ipc,shm: shorten critical region for shmat | |
5 | ||
6 | From: Davidlohr Bueso <davidlohr.bueso@hp.com> | |
7 | ||
8 | commit c2c737a0461e61a34676bd0bd1bc1a70a1b4e396 upstream. | |
9 | ||
10 | Similar to other system calls, acquire the kern_ipc_perm lock after doing | |
11 | the initial permission and security checks. | |
12 | ||
13 | [sasha.levin@oracle.com: dont leave do_shmat with rcu lock held] | |
14 | Signed-off-by: Davidlohr Bueso <davidlohr.bueso@hp.com> | |
15 | Tested-by: Sedat Dilek <sedat.dilek@gmail.com> | |
16 | Cc: Rik van Riel <riel@redhat.com> | |
17 | Cc: Manfred Spraul <manfred@colorfullife.com> | |
18 | Signed-off-by: Sasha Levin <sasha.levin@oracle.com> | |
19 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
20 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
21 | Cc: Mike Galbraith <efault@gmx.de> | |
22 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
23 | ||
24 | --- | |
25 | ipc/shm.c | 14 ++++++++++---- | |
26 | 1 file changed, 10 insertions(+), 4 deletions(-) | |
27 | ||
28 | --- a/ipc/shm.c | |
29 | +++ b/ipc/shm.c | |
30 | @@ -19,6 +19,9 @@ | |
31 | * namespaces support | |
32 | * OpenVZ, SWsoft Inc. | |
33 | * Pavel Emelianov <xemul@openvz.org> | |
34 | + * | |
35 | + * Better ipc lock (kern_ipc_perm.lock) handling | |
36 | + * Davidlohr Bueso <davidlohr.bueso@hp.com>, June 2013. | |
37 | */ | |
38 | ||
39 | #include <linux/slab.h> | |
40 | @@ -1093,10 +1096,11 @@ long do_shmat(int shmid, char __user *sh | |
41 | * additional creator id... | |
42 | */ | |
43 | ns = current->nsproxy->ipc_ns; | |
44 | - shp = shm_lock_check(ns, shmid); | |
45 | + rcu_read_lock(); | |
46 | + shp = shm_obtain_object_check(ns, shmid); | |
47 | if (IS_ERR(shp)) { | |
48 | err = PTR_ERR(shp); | |
49 | - goto out; | |
50 | + goto out_unlock; | |
51 | } | |
52 | ||
53 | err = -EACCES; | |
54 | @@ -1107,11 +1111,13 @@ long do_shmat(int shmid, char __user *sh | |
55 | if (err) | |
56 | goto out_unlock; | |
57 | ||
58 | + ipc_lock_object(&shp->shm_perm); | |
59 | path = shp->shm_file->f_path; | |
60 | path_get(&path); | |
61 | shp->shm_nattch++; | |
62 | size = i_size_read(path.dentry->d_inode); | |
63 | - shm_unlock(shp); | |
64 | + ipc_unlock_object(&shp->shm_perm); | |
65 | + rcu_read_unlock(); | |
66 | ||
67 | err = -ENOMEM; | |
68 | sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); | |
69 | @@ -1182,7 +1188,7 @@ out_nattch: | |
70 | return err; | |
71 | ||
72 | out_unlock: | |
73 | - shm_unlock(shp); | |
74 | + rcu_read_unlock(); | |
75 | out: | |
76 | return err; | |
77 | } |