|
@@ -1220,14 +1220,14 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
|
|
memset(semid64, 0, sizeof(*semid64));
|
|
memset(semid64, 0, sizeof(*semid64));
|
|
|
|
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
- if (cmd == SEM_STAT) {
|
|
|
|
|
|
+ if (cmd == SEM_STAT || cmd == SEM_STAT_ANY) {
|
|
sma = sem_obtain_object(ns, semid);
|
|
sma = sem_obtain_object(ns, semid);
|
|
if (IS_ERR(sma)) {
|
|
if (IS_ERR(sma)) {
|
|
err = PTR_ERR(sma);
|
|
err = PTR_ERR(sma);
|
|
goto out_unlock;
|
|
goto out_unlock;
|
|
}
|
|
}
|
|
id = sma->sem_perm.id;
|
|
id = sma->sem_perm.id;
|
|
- } else {
|
|
|
|
|
|
+ } else { /* IPC_STAT */
|
|
sma = sem_obtain_object_check(ns, semid);
|
|
sma = sem_obtain_object_check(ns, semid);
|
|
if (IS_ERR(sma)) {
|
|
if (IS_ERR(sma)) {
|
|
err = PTR_ERR(sma);
|
|
err = PTR_ERR(sma);
|
|
@@ -1235,9 +1235,14 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- err = -EACCES;
|
|
|
|
- if (ipcperms(ns, &sma->sem_perm, S_IRUGO))
|
|
|
|
- goto out_unlock;
|
|
|
|
|
|
+ /* see comment for SHM_STAT_ANY */
|
|
|
|
+ if (cmd == SEM_STAT_ANY)
|
|
|
|
+ audit_ipc_obj(&sma->sem_perm);
|
|
|
|
+ else {
|
|
|
|
+ err = -EACCES;
|
|
|
|
+ if (ipcperms(ns, &sma->sem_perm, S_IRUGO))
|
|
|
|
+ goto out_unlock;
|
|
|
|
+ }
|
|
|
|
|
|
err = security_sem_semctl(&sma->sem_perm, cmd);
|
|
err = security_sem_semctl(&sma->sem_perm, cmd);
|
|
if (err)
|
|
if (err)
|
|
@@ -1626,6 +1631,7 @@ long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg)
|
|
return semctl_info(ns, semid, cmd, p);
|
|
return semctl_info(ns, semid, cmd, p);
|
|
case IPC_STAT:
|
|
case IPC_STAT:
|
|
case SEM_STAT:
|
|
case SEM_STAT:
|
|
|
|
+ case SEM_STAT_ANY:
|
|
err = semctl_stat(ns, semid, cmd, &semid64);
|
|
err = semctl_stat(ns, semid, cmd, &semid64);
|
|
if (err < 0)
|
|
if (err < 0)
|
|
return err;
|
|
return err;
|
|
@@ -1732,6 +1738,7 @@ long compat_ksys_semctl(int semid, int semnum, int cmd, int arg)
|
|
return semctl_info(ns, semid, cmd, p);
|
|
return semctl_info(ns, semid, cmd, p);
|
|
case IPC_STAT:
|
|
case IPC_STAT:
|
|
case SEM_STAT:
|
|
case SEM_STAT:
|
|
|
|
+ case SEM_STAT_ANY:
|
|
err = semctl_stat(ns, semid, cmd, &semid64);
|
|
err = semctl_stat(ns, semid, cmd, &semid64);
|
|
if (err < 0)
|
|
if (err < 0)
|
|
return err;
|
|
return err;
|