25 #include <linux/capability.h>
26 #include <linux/msg.h>
31 #include <linux/list.h>
33 #include <linux/sched.h>
35 #include <linux/audit.h>
41 #include <asm/current.h>
42 #include <asm/uaccess.h>
66 #define SEARCH_EQUAL 2
67 #define SEARCH_NOTEQUAL 3
68 #define SEARCH_LESSEQUAL 4
70 #define msg_ids(ns) ((ns)->ids[IPC_MSG_IDS])
72 #define msg_unlock(msq) ipc_unlock(&(msq)->q_perm)
77 static int sysvipc_msg_proc_show(
struct seq_file *
s,
void *it);
89 unsigned long allowed;
103 if (allowed >
IPCMNI / nb_ns) {
139 " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n",
185 int msgflg = params->
flg;
238 static void ss_wakeup(
struct list_head *
h,
int kill)
267 msr->
r_msg = ERR_PTR(res);
284 expunge_all(msq, -
EIDRM);
305 static inline int msg_security(
struct kern_ipc_perm *ipcp,
int msgflg)
325 msg_params.
flg = msgflg;
330 static inline unsigned long
375 static inline unsigned long
376 copy_msqid_from_user(
struct msqid64_ds *
out,
void __user *buf,
int version)
390 out->
msg_perm.uid = tbuf_old.msg_perm.uid;
391 out->
msg_perm.gid = tbuf_old.msg_perm.gid;
392 out->
msg_perm.mode = tbuf_old.msg_perm.mode;
394 if (tbuf_old.msg_qbytes == 0)
412 struct msqid_ds __user *buf,
int version)
420 if (copy_msqid_from_user(&msqid64, buf, version))
425 &msqid64.msg_perm, msqid64.msg_qbytes);
427 return PTR_ERR(ipcp);
456 expunge_all(msq, -
EAGAIN);
478 if (msqid < 0 || cmd < 0)
502 memset(&msginfo, 0,
sizeof(msginfo));
520 if (
copy_to_user(buf, &msginfo,
sizeof(
struct msginfo)))
522 return (max_id < 0) ? 0 : max_id;
534 msq = msg_lock(ns, msqid);
537 success_return = msq->
q_perm.id;
539 msq = msg_lock_check(ns, msqid);
552 memset(&tbuf, 0,
sizeof(tbuf));
564 if (copy_msqid_to_user(buf, &tbuf, version))
566 return success_return;
570 err = msgctl_down(ns, msqid, cmd, buf, version);
603 static inline int pipelined_send(
struct msg_queue *msq,
struct msg_msg *msg)
638 long do_msgsnd(
int msqid,
long mtype,
void __user *mtext,
639 size_t msgsz,
int msgflg)
648 if (msgsz > ns->
msg_ctlmax || (
long) msgsz < 0 || msqid < 0)
660 msq = msg_lock_check(ns, msqid);
671 goto out_unlock_free;
675 goto out_unlock_free;
685 goto out_unlock_free;
692 ipc_lock_by_ptr(&msq->
q_perm);
694 if (msq->
q_perm.deleted) {
696 goto out_unlock_free;
702 goto out_unlock_free;
709 if (!pipelined_send(msq, msg)) {
736 return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
739 static inline int convert_mode(
long *msgtyp,
int msgflg)
758 long do_msgrcv(
int msqid,
long *pmtype,
void __user *mtext,
759 size_t msgsz,
long msgtyp,
int msgflg)
766 if (msqid < 0 || (
long) msgsz < 0)
768 mode = convert_mode(&msgtyp, msgflg);
771 msq = msg_lock_check(ns, msqid);
789 if (testmsg(walk_msg, msgtyp, mode) &&
797 msgtyp = walk_msg->
m_type - 1;
811 msg = ERR_PTR(-
E2BIG);
862 while (msg ==
NULL) {
871 if (msg != ERR_PTR(-
EAGAIN)) {
879 ipc_lock_by_ptr(&msq->
q_perm);
900 msgsz = (msgsz > msg->
m_ts) ? msg->
m_ts : msgsz;
911 long, msgtyp,
int, msgflg)
915 err =
do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
925 #ifdef CONFIG_PROC_FS
926 static int sysvipc_msg_proc_show(
struct seq_file *s,
void *it)
932 "%10d %10d %4o %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",