Commit 1c7ee8a0cc8ba17b5f99133b004edfe64fb496fb
Committed by
Greg Kroah-Hartman
1 parent
dafeda2a91
ipc,shm: make shmctl_nolock lockless
commit c97cb9ccab8c85428ec21eff690642ad2ce1fa8a upstream. While the INFO cmd doesn't take the ipc lock, the STAT commands do acquire it unnecessarily. We can do the permissions and security checks only holding the rcu lock. [akpm@linux-foundation.org: coding-style fixes] 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: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mike Galbraith <efault@gmx.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 12 additions and 7 deletions Side-by-side Diff
ipc/shm.c
... | ... | @@ -889,27 +889,31 @@ |
889 | 889 | struct shmid64_ds tbuf; |
890 | 890 | int result; |
891 | 891 | |
892 | + rcu_read_lock(); | |
892 | 893 | if (cmd == SHM_STAT) { |
893 | - shp = shm_lock(ns, shmid); | |
894 | + shp = shm_obtain_object(ns, shmid); | |
894 | 895 | if (IS_ERR(shp)) { |
895 | 896 | err = PTR_ERR(shp); |
896 | - goto out; | |
897 | + goto out_unlock; | |
897 | 898 | } |
898 | 899 | result = shp->shm_perm.id; |
899 | 900 | } else { |
900 | - shp = shm_lock_check(ns, shmid); | |
901 | + shp = shm_obtain_object_check(ns, shmid); | |
901 | 902 | if (IS_ERR(shp)) { |
902 | 903 | err = PTR_ERR(shp); |
903 | - goto out; | |
904 | + goto out_unlock; | |
904 | 905 | } |
905 | 906 | result = 0; |
906 | 907 | } |
908 | + | |
907 | 909 | err = -EACCES; |
908 | 910 | if (ipcperms(ns, &shp->shm_perm, S_IRUGO)) |
909 | 911 | goto out_unlock; |
912 | + | |
910 | 913 | err = security_shm_shmctl(shp, cmd); |
911 | 914 | if (err) |
912 | 915 | goto out_unlock; |
916 | + | |
913 | 917 | memset(&tbuf, 0, sizeof(tbuf)); |
914 | 918 | kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm); |
915 | 919 | tbuf.shm_segsz = shp->shm_segsz; |
... | ... | @@ -919,8 +923,9 @@ |
919 | 923 | tbuf.shm_cpid = shp->shm_cprid; |
920 | 924 | tbuf.shm_lpid = shp->shm_lprid; |
921 | 925 | tbuf.shm_nattch = shp->shm_nattch; |
922 | - shm_unlock(shp); | |
923 | - if(copy_shmid_to_user (buf, &tbuf, version)) | |
926 | + rcu_read_unlock(); | |
927 | + | |
928 | + if (copy_shmid_to_user(buf, &tbuf, version)) | |
924 | 929 | err = -EFAULT; |
925 | 930 | else |
926 | 931 | err = result; |
... | ... | @@ -931,7 +936,7 @@ |
931 | 936 | } |
932 | 937 | |
933 | 938 | out_unlock: |
934 | - shm_unlock(shp); | |
939 | + rcu_read_unlock(); | |
935 | 940 | out: |
936 | 941 | return err; |
937 | 942 | } |