aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/msg.c
diff options
context:
space:
mode:
authorsuzuki <suzuki@linux.vnet.ibm.com>2006-12-06 23:37:48 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-07 11:39:38 -0500
commit651971cb7242e8f6d7ebd153e69bd271cb731223 (patch)
tree38c8bd3c461cb09a538664ddc78e5452fdf28f29 /ipc/msg.c
parent19e5d9c0d2194b4b47189cbec2921cbf72b0bd1c (diff)
[PATCH] Fix the size limit of compat space msgsize
Currently we allocate 64k space on the user stack and use it the msgbuf for sys_{msgrcv,msgsnd} for compat and the results are later copied in user [ by copy_in_user]. This patch introduces helper routines for sys_{msgrcv,msgsnd} as below: do_msgsnd() : Accepts the mtype and user space ptr to the buffer along with the msqid and msgflg. do_msgrcv() : Accepts a kernel space ptr to mtype and a userspace ptr to the buffer. The mtype has to be copied back the user space msgbuf by the caller. These changes avoid the need to allocate the msgsize on the userspace ( thus removing the size limt ) and the overhead of an extra copy_in_user(). Signed-off-by: Suzuki K P <suzuki@in.ibm.com> Cc: Arnd Bergmann <arnd@arndb.de> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'ipc/msg.c')
-rw-r--r--ipc/msg.c44
1 files changed, 33 insertions, 11 deletions
diff --git a/ipc/msg.c b/ipc/msg.c
index 1266b1d0c8e3..a388824740e7 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -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
629asmlinkage long 629long do_msgsnd(int msqid, long mtype, void __user *mtext,
630sys_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
723asmlinkage long
724sys_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
726static inline int convert_mode(long *msgtyp, int msgflg) 733static 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
745asmlinkage long sys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz, 752long 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
908asmlinkage 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;
919out:
920 return err;
921}
922
901#ifdef CONFIG_PROC_FS 923#ifdef CONFIG_PROC_FS
902static int sysvipc_msg_proc_show(struct seq_file *s, void *it) 924static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
903{ 925{