aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/uapi/linux/msg.h1
-rw-r--r--ipc/msg.c17
-rw-r--r--security/selinux/hooks.c1
-rw-r--r--security/smack/smack_lsm.c1
4 files changed, 15 insertions, 5 deletions
diff --git a/include/uapi/linux/msg.h b/include/uapi/linux/msg.h
index 5d5ab81dc9be..e4a0d9a9a9e8 100644
--- a/include/uapi/linux/msg.h
+++ b/include/uapi/linux/msg.h
@@ -7,6 +7,7 @@
/* ipcs ctl commands */
#define MSG_STAT 11
#define MSG_INFO 12
+#define MSG_STAT_ANY 13
/* msgrcv options */
#define MSG_NOERROR 010000 /* no error if message is too big */
diff --git a/ipc/msg.c b/ipc/msg.c
index 114a21189613..56fd1c73eedc 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -497,14 +497,14 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
memset(p, 0, sizeof(*p));
rcu_read_lock();
- if (cmd == MSG_STAT) {
+ if (cmd == MSG_STAT || cmd == MSG_STAT_ANY) {
msq = msq_obtain_object(ns, msqid);
if (IS_ERR(msq)) {
err = PTR_ERR(msq);
goto out_unlock;
}
id = msq->q_perm.id;
- } else {
+ } else { /* IPC_STAT */
msq = msq_obtain_object_check(ns, msqid);
if (IS_ERR(msq)) {
err = PTR_ERR(msq);
@@ -512,9 +512,14 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid,
}
}
- err = -EACCES;
- if (ipcperms(ns, &msq->q_perm, S_IRUGO))
- goto out_unlock;
+ /* see comment for SHM_STAT_ANY */
+ if (cmd == MSG_STAT_ANY)
+ audit_ipc_obj(&msq->q_perm);
+ else {
+ err = -EACCES;
+ if (ipcperms(ns, &msq->q_perm, S_IRUGO))
+ goto out_unlock;
+ }
err = security_msg_queue_msgctl(&msq->q_perm, cmd);
if (err)
@@ -572,6 +577,7 @@ long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf)
return err;
}
case MSG_STAT: /* msqid is an index rather than a msg queue id */
+ case MSG_STAT_ANY:
case IPC_STAT:
err = msgctl_stat(ns, msqid, cmd, &msqid64);
if (err < 0)
@@ -690,6 +696,7 @@ long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr)
}
case IPC_STAT:
case MSG_STAT:
+ case MSG_STAT_ANY:
err = msgctl_stat(ns, msqid, cmd, &msqid64);
if (err < 0)
return err;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 927904d0f115..4cafe6a19167 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6006,6 +6006,7 @@ static int selinux_msg_queue_msgctl(struct kern_ipc_perm *msq, int cmd)
SECCLASS_SYSTEM, SYSTEM__IPC_INFO, NULL);
case IPC_STAT:
case MSG_STAT:
+ case MSG_STAT_ANY:
perms = MSGQ__GETATTR | MSGQ__ASSOCIATE;
break;
case IPC_SET:
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index cb36498a5076..0b414836bebd 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3230,6 +3230,7 @@ static int smack_msg_queue_msgctl(struct kern_ipc_perm *isp, int cmd)
switch (cmd) {
case IPC_STAT:
case MSG_STAT:
+ case MSG_STAT_ANY:
may = MAY_READ;
break;
case IPC_SET: