|
@@ -467,17 +467,11 @@ out_up:
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
|
|
|
+static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
|
|
|
+ int cmd, int version, void __user *buf)
|
|
|
{
|
|
|
+ int err;
|
|
|
struct msg_queue *msq;
|
|
|
- int err, version;
|
|
|
- struct ipc_namespace *ns;
|
|
|
-
|
|
|
- if (msqid < 0 || cmd < 0)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- version = ipc_parse_version(&cmd);
|
|
|
- ns = current->nsproxy->ipc_ns;
|
|
|
|
|
|
switch (cmd) {
|
|
|
case IPC_INFO:
|
|
@@ -488,6 +482,7 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
|
|
|
|
|
|
if (!buf)
|
|
|
return -EFAULT;
|
|
|
+
|
|
|
/*
|
|
|
* We must not return kernel stack data.
|
|
|
* due to padding, it's not enough
|
|
@@ -519,7 +514,8 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
|
|
|
return -EFAULT;
|
|
|
return (max_id < 0) ? 0 : max_id;
|
|
|
}
|
|
|
- case MSG_STAT: /* msqid is an index rather than a msg queue id */
|
|
|
+
|
|
|
+ case MSG_STAT:
|
|
|
case IPC_STAT:
|
|
|
{
|
|
|
struct msqid64_ds tbuf;
|
|
@@ -563,19 +559,42 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
|
|
|
return -EFAULT;
|
|
|
return success_return;
|
|
|
}
|
|
|
- case IPC_SET:
|
|
|
- case IPC_RMID:
|
|
|
- err = msgctl_down(ns, msqid, cmd, buf, version);
|
|
|
- return err;
|
|
|
+
|
|
|
default:
|
|
|
- return -EINVAL;
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ return err;
|
|
|
out_unlock:
|
|
|
msg_unlock(msq);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
+SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
|
|
|
+{
|
|
|
+ int version;
|
|
|
+ struct ipc_namespace *ns;
|
|
|
+
|
|
|
+ if (msqid < 0 || cmd < 0)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ version = ipc_parse_version(&cmd);
|
|
|
+ ns = current->nsproxy->ipc_ns;
|
|
|
+
|
|
|
+ switch (cmd) {
|
|
|
+ case IPC_INFO:
|
|
|
+ case MSG_INFO:
|
|
|
+ case MSG_STAT: /* msqid is an index rather than a msg queue id */
|
|
|
+ case IPC_STAT:
|
|
|
+ return msgctl_nolock(ns, msqid, cmd, version, buf);
|
|
|
+ case IPC_SET:
|
|
|
+ case IPC_RMID:
|
|
|
+ return msgctl_down(ns, msqid, cmd, buf, version);
|
|
|
+ default:
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int testmsg(struct msg_msg *msg, long type, int mode)
|
|
|
{
|
|
|
switch(mode)
|