diff options
Diffstat (limited to 'ipc/msg.c')
-rw-r--r-- | ipc/msg.c | 44 |
1 files changed, 33 insertions, 11 deletions
@@ -626,12 +626,11 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg) | |||
626 | return 0; | 626 | return 0; |
627 | } | 627 | } |
628 | 628 | ||
629 | asmlinkage long | 629 | long do_msgsnd(int msqid, long mtype, void __user *mtext, |
630 | sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) | 630 | size_t msgsz, int msgflg) |
631 | { | 631 | { |
632 | struct msg_queue *msq; | 632 | struct msg_queue *msq; |
633 | struct msg_msg *msg; | 633 | struct msg_msg *msg; |
634 | long mtype; | ||
635 | int err; | 634 | int err; |
636 | struct ipc_namespace *ns; | 635 | struct ipc_namespace *ns; |
637 | 636 | ||
@@ -639,12 +638,10 @@ sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) | |||
639 | 638 | ||
640 | if (msgsz > ns->msg_ctlmax || (long) msgsz < 0 || msqid < 0) | 639 | if (msgsz > ns->msg_ctlmax || (long) msgsz < 0 || msqid < 0) |
641 | return -EINVAL; | 640 | return -EINVAL; |
642 | if (get_user(mtype, &msgp->mtype)) | ||
643 | return -EFAULT; | ||
644 | if (mtype < 1) | 641 | if (mtype < 1) |
645 | return -EINVAL; | 642 | return -EINVAL; |
646 | 643 | ||
647 | msg = load_msg(msgp->mtext, msgsz); | 644 | msg = load_msg(mtext, msgsz); |
648 | if (IS_ERR(msg)) | 645 | if (IS_ERR(msg)) |
649 | return PTR_ERR(msg); | 646 | return PTR_ERR(msg); |
650 | 647 | ||
@@ -723,6 +720,16 @@ out_free: | |||
723 | return err; | 720 | return err; |
724 | } | 721 | } |
725 | 722 | ||
723 | asmlinkage long | ||
724 | sys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz, int msgflg) | ||
725 | { | ||
726 | long mtype; | ||
727 | |||
728 | if (get_user(mtype, &msgp->mtype)) | ||
729 | return -EFAULT; | ||
730 | return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); | ||
731 | } | ||
732 | |||
726 | static inline int convert_mode(long *msgtyp, int msgflg) | 733 | static inline int convert_mode(long *msgtyp, int msgflg) |
727 | { | 734 | { |
728 | /* | 735 | /* |
@@ -742,8 +749,8 @@ static inline int convert_mode(long *msgtyp, int msgflg) | |||
742 | return SEARCH_EQUAL; | 749 | return SEARCH_EQUAL; |
743 | } | 750 | } |
744 | 751 | ||
745 | asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, | 752 | long do_msgrcv(int msqid, long *pmtype, void __user *mtext, |
746 | long msgtyp, int msgflg) | 753 | size_t msgsz, long msgtyp, int msgflg) |
747 | { | 754 | { |
748 | struct msg_queue *msq; | 755 | struct msg_queue *msq; |
749 | struct msg_msg *msg; | 756 | struct msg_msg *msg; |
@@ -889,15 +896,30 @@ out_unlock: | |||
889 | return PTR_ERR(msg); | 896 | return PTR_ERR(msg); |
890 | 897 | ||
891 | msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz; | 898 | msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz; |
892 | if (put_user (msg->m_type, &msgp->mtype) || | 899 | *pmtype = msg->m_type; |
893 | store_msg(msgp->mtext, msg, msgsz)) { | 900 | if (store_msg(mtext, msg, msgsz)) |
894 | msgsz = -EFAULT; | 901 | msgsz = -EFAULT; |
895 | } | 902 | |
896 | free_msg(msg); | 903 | free_msg(msg); |
897 | 904 | ||
898 | return msgsz; | 905 | return msgsz; |
899 | } | 906 | } |
900 | 907 | ||
908 | asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, | ||
909 | long msgtyp, int msgflg) | ||
910 | { | ||
911 | long err, mtype; | ||
912 | |||
913 | err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg); | ||
914 | if (err < 0) | ||
915 | goto out; | ||
916 | |||
917 | if (put_user(mtype, &msgp->mtype)) | ||
918 | err = -EFAULT; | ||
919 | out: | ||
920 | return err; | ||
921 | } | ||
922 | |||
901 | #ifdef CONFIG_PROC_FS | 923 | #ifdef CONFIG_PROC_FS |
902 | static int sysvipc_msg_proc_show(struct seq_file *s, void *it) | 924 | static int sysvipc_msg_proc_show(struct seq_file *s, void *it) |
903 | { | 925 | { |