|
@@ -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;
|
|
|
}
|