|
@@ -947,14 +947,14 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
|
|
|
memset(tbuf, 0, sizeof(*tbuf));
|
|
|
|
|
|
rcu_read_lock();
|
|
|
- if (cmd == SHM_STAT) {
|
|
|
+ if (cmd == SHM_STAT || cmd == SHM_STAT_ANY) {
|
|
|
shp = shm_obtain_object(ns, shmid);
|
|
|
if (IS_ERR(shp)) {
|
|
|
err = PTR_ERR(shp);
|
|
|
goto out_unlock;
|
|
|
}
|
|
|
id = shp->shm_perm.id;
|
|
|
- } else {
|
|
|
+ } else { /* IPC_STAT */
|
|
|
shp = shm_obtain_object_check(ns, shmid);
|
|
|
if (IS_ERR(shp)) {
|
|
|
err = PTR_ERR(shp);
|
|
@@ -962,9 +962,20 @@ static int shmctl_stat(struct ipc_namespace *ns, int shmid,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- err = -EACCES;
|
|
|
- if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
|
|
|
- goto out_unlock;
|
|
|
+ /*
|
|
|
+ * Semantically SHM_STAT_ANY ought to be identical to
|
|
|
+ * that functionality provided by the /proc/sysvipc/
|
|
|
+ * interface. As such, only audit these calls and
|
|
|
+ * do not do traditional S_IRUGO permission checks on
|
|
|
+ * the ipc object.
|
|
|
+ */
|
|
|
+ if (cmd == SHM_STAT_ANY)
|
|
|
+ audit_ipc_obj(&shp->shm_perm);
|
|
|
+ else {
|
|
|
+ err = -EACCES;
|
|
|
+ if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
|
|
|
+ goto out_unlock;
|
|
|
+ }
|
|
|
|
|
|
err = security_shm_shmctl(&shp->shm_perm, cmd);
|
|
|
if (err)
|
|
@@ -1104,6 +1115,7 @@ long ksys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
|
|
|
return err;
|
|
|
}
|
|
|
case SHM_STAT:
|
|
|
+ case SHM_STAT_ANY:
|
|
|
case IPC_STAT: {
|
|
|
err = shmctl_stat(ns, shmid, cmd, &sem64);
|
|
|
if (err < 0)
|
|
@@ -1282,6 +1294,7 @@ long compat_ksys_shmctl(int shmid, int cmd, void __user *uptr)
|
|
|
return err;
|
|
|
}
|
|
|
case IPC_STAT:
|
|
|
+ case SHM_STAT_ANY:
|
|
|
case SHM_STAT:
|
|
|
err = shmctl_stat(ns, shmid, cmd, &sem64);
|
|
|
if (err < 0)
|