ipc,shm: make shmctl_nolock lockless
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>
This commit is contained in:
parent
68eccc1dc3
commit
c97cb9ccab
19
ipc/shm.c
19
ipc/shm.c
@ -882,27 +882,31 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
|
||||
struct shmid64_ds tbuf;
|
||||
int result;
|
||||
|
||||
rcu_read_lock();
|
||||
if (cmd == SHM_STAT) {
|
||||
shp = shm_lock(ns, shmid);
|
||||
shp = shm_obtain_object(ns, shmid);
|
||||
if (IS_ERR(shp)) {
|
||||
err = PTR_ERR(shp);
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
}
|
||||
result = shp->shm_perm.id;
|
||||
} else {
|
||||
shp = shm_lock_check(ns, shmid);
|
||||
shp = shm_obtain_object_check(ns, shmid);
|
||||
if (IS_ERR(shp)) {
|
||||
err = PTR_ERR(shp);
|
||||
goto out;
|
||||
goto out_unlock;
|
||||
}
|
||||
result = 0;
|
||||
}
|
||||
|
||||
err = -EACCES;
|
||||
if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
|
||||
goto out_unlock;
|
||||
|
||||
err = security_shm_shmctl(shp, cmd);
|
||||
if (err)
|
||||
goto out_unlock;
|
||||
|
||||
memset(&tbuf, 0, sizeof(tbuf));
|
||||
kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
|
||||
tbuf.shm_segsz = shp->shm_segsz;
|
||||
@ -912,8 +916,9 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
|
||||
tbuf.shm_cpid = shp->shm_cprid;
|
||||
tbuf.shm_lpid = shp->shm_lprid;
|
||||
tbuf.shm_nattch = shp->shm_nattch;
|
||||
shm_unlock(shp);
|
||||
if(copy_shmid_to_user (buf, &tbuf, version))
|
||||
rcu_read_unlock();
|
||||
|
||||
if (copy_shmid_to_user(buf, &tbuf, version))
|
||||
err = -EFAULT;
|
||||
else
|
||||
err = result;
|
||||
@ -924,7 +929,7 @@ static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
shm_unlock(shp);
|
||||
rcu_read_unlock();
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user