aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStanislav Kinsbursky <skinsbursky@parallels.com>2013-01-04 18:34:52 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-01-04 19:11:45 -0500
commitf9dd87f4738c7555aca2cdf8cb2b2326cafb0cad (patch)
tree4fb581910eaee4309ae6befeef8c4f921b274c5d
parent03f595668017f1a1fb971c02fc37140bc6e7bb1c (diff)
ipc: message queue receive cleanup
Move all message related manipulation into one function msg_fill(). Actually, two functions because of the compat one. [akpm@linux-foundation.org: checkpatch fixes] Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com> Cc: Serge Hallyn <serge.hallyn@canonical.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Cc: Pavel Emelyanov <xemul@parallels.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/msg.h5
-rw-r--r--ipc/compat.c45
-rw-r--r--ipc/msg.c44
3 files changed, 45 insertions, 49 deletions
diff --git a/include/linux/msg.h b/include/linux/msg.h
index 7a4b9e97d29a..fc5743a554e6 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -34,7 +34,8 @@ struct msg_queue {
34/* Helper routines for sys_msgsnd and sys_msgrcv */ 34/* Helper routines for sys_msgsnd and sys_msgrcv */
35extern long do_msgsnd(int msqid, long mtype, void __user *mtext, 35extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
36 size_t msgsz, int msgflg); 36 size_t msgsz, int msgflg);
37extern long do_msgrcv(int msqid, long *pmtype, void __user *mtext, 37extern long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
38 size_t msgsz, long msgtyp, int msgflg); 38 int msgflg,
39 long (*msg_fill)(void __user *, struct msg_msg *, size_t));
39 40
40#endif /* _LINUX_MSG_H */ 41#endif /* _LINUX_MSG_H */
diff --git a/ipc/compat.c b/ipc/compat.c
index ad9518eb26e0..eb3ea16d2d1d 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -306,6 +306,20 @@ static long do_compat_semctl(int first, int second, int third, u32 pad)
306 return err; 306 return err;
307} 307}
308 308
309long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
310{
311 struct compat_msgbuf __user *msgp = dest;
312 size_t msgsz;
313
314 if (put_user(msg->m_type, &msgp->mtype))
315 return -EFAULT;
316
317 msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
318 if (store_msg(msgp->mtext, msg, msgsz))
319 return -EFAULT;
320 return msgsz;
321}
322
309#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC 323#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
310long compat_sys_semctl(int first, int second, int third, void __user *uptr) 324long compat_sys_semctl(int first, int second, int third, void __user *uptr)
311{ 325{
@@ -337,10 +351,6 @@ long compat_sys_msgsnd(int first, int second, int third, void __user *uptr)
337long compat_sys_msgrcv(int first, int second, int msgtyp, int third, 351long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
338 int version, void __user *uptr) 352 int version, void __user *uptr)
339{ 353{
340 struct compat_msgbuf __user *up;
341 long type;
342 int err;
343
344 if (first < 0) 354 if (first < 0)
345 return -EINVAL; 355 return -EINVAL;
346 if (second < 0) 356 if (second < 0)
@@ -348,23 +358,14 @@ long compat_sys_msgrcv(int first, int second, int msgtyp, int third,
348 358
349 if (!version) { 359 if (!version) {
350 struct compat_ipc_kludge ipck; 360 struct compat_ipc_kludge ipck;
351 err = -EINVAL;
352 if (!uptr) 361 if (!uptr)
353 goto out; 362 return -EINVAL;
354 err = -EFAULT;
355 if (copy_from_user (&ipck, uptr, sizeof(ipck))) 363 if (copy_from_user (&ipck, uptr, sizeof(ipck)))
356 goto out; 364 return -EFAULT;
357 uptr = compat_ptr(ipck.msgp); 365 uptr = compat_ptr(ipck.msgp);
358 msgtyp = ipck.msgtyp; 366 msgtyp = ipck.msgtyp;
359 } 367 }
360 up = uptr; 368 return do_msgrcv(first, uptr, second, msgtyp, third, compat_do_msg_fill);
361 err = do_msgrcv(first, &type, up->mtext, second, msgtyp, third);
362 if (err < 0)
363 goto out;
364 if (put_user(type, &up->mtype))
365 err = -EFAULT;
366out:
367 return err;
368} 369}
369#else 370#else
370long compat_sys_semctl(int semid, int semnum, int cmd, int arg) 371long compat_sys_semctl(int semid, int semnum, int cmd, int arg)
@@ -385,16 +386,8 @@ long compat_sys_msgsnd(int msqid, struct compat_msgbuf __user *msgp,
385long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp, 386long compat_sys_msgrcv(int msqid, struct compat_msgbuf __user *msgp,
386 compat_ssize_t msgsz, long msgtyp, int msgflg) 387 compat_ssize_t msgsz, long msgtyp, int msgflg)
387{ 388{
388 long err, mtype; 389 return do_msgrcv(msqid, msgp, (ssize_t)msgsz, msgtyp, msgflg,
389 390 compat_do_msg_fill);
390 err = do_msgrcv(msqid, &mtype, msgp->mtext, (ssize_t)msgsz, msgtyp, msgflg);
391 if (err < 0)
392 goto out;
393
394 if (put_user(mtype, &msgp->mtype))
395 err = -EFAULT;
396 out:
397 return err;
398} 391}
399#endif 392#endif
400 393
diff --git a/ipc/msg.c b/ipc/msg.c
index 2f272fa76595..cefc24f46e3e 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -755,15 +755,30 @@ static inline int convert_mode(long *msgtyp, int msgflg)
755 return SEARCH_EQUAL; 755 return SEARCH_EQUAL;
756} 756}
757 757
758long do_msgrcv(int msqid, long *pmtype, void __user *mtext, 758static long do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
759 size_t msgsz, long msgtyp, int msgflg) 759{
760 struct msgbuf __user *msgp = dest;
761 size_t msgsz;
762
763 if (put_user(msg->m_type, &msgp->mtype))
764 return -EFAULT;
765
766 msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
767 if (store_msg(msgp->mtext, msg, msgsz))
768 return -EFAULT;
769 return msgsz;
770}
771
772long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
773 int msgflg,
774 long (*msg_handler)(void __user *, struct msg_msg *, size_t))
760{ 775{
761 struct msg_queue *msq; 776 struct msg_queue *msq;
762 struct msg_msg *msg; 777 struct msg_msg *msg;
763 int mode; 778 int mode;
764 struct ipc_namespace *ns; 779 struct ipc_namespace *ns;
765 780
766 if (msqid < 0 || (long) msgsz < 0) 781 if (msqid < 0 || (long) bufsz < 0)
767 return -EINVAL; 782 return -EINVAL;
768 mode = convert_mode(&msgtyp, msgflg); 783 mode = convert_mode(&msgtyp, msgflg);
769 ns = current->nsproxy->ipc_ns; 784 ns = current->nsproxy->ipc_ns;
@@ -804,7 +819,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
804 * Found a suitable message. 819 * Found a suitable message.
805 * Unlink it from the queue. 820 * Unlink it from the queue.
806 */ 821 */
807 if ((msgsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) { 822 if ((bufsz < msg->m_ts) && !(msgflg & MSG_NOERROR)) {
808 msg = ERR_PTR(-E2BIG); 823 msg = ERR_PTR(-E2BIG);
809 goto out_unlock; 824 goto out_unlock;
810 } 825 }
@@ -831,7 +846,7 @@ long do_msgrcv(int msqid, long *pmtype, void __user *mtext,
831 if (msgflg & MSG_NOERROR) 846 if (msgflg & MSG_NOERROR)
832 msr_d.r_maxsize = INT_MAX; 847 msr_d.r_maxsize = INT_MAX;
833 else 848 else
834 msr_d.r_maxsize = msgsz; 849 msr_d.r_maxsize = bufsz;
835 msr_d.r_msg = ERR_PTR(-EAGAIN); 850 msr_d.r_msg = ERR_PTR(-EAGAIN);
836 current->state = TASK_INTERRUPTIBLE; 851 current->state = TASK_INTERRUPTIBLE;
837 msg_unlock(msq); 852 msg_unlock(msq);
@@ -894,29 +909,16 @@ out_unlock:
894 if (IS_ERR(msg)) 909 if (IS_ERR(msg))
895 return PTR_ERR(msg); 910 return PTR_ERR(msg);
896 911
897 msgsz = (msgsz > msg->m_ts) ? msg->m_ts : msgsz; 912 bufsz = msg_handler(buf, msg, bufsz);
898 *pmtype = msg->m_type;
899 if (store_msg(mtext, msg, msgsz))
900 msgsz = -EFAULT;
901
902 free_msg(msg); 913 free_msg(msg);
903 914
904 return msgsz; 915 return bufsz;
905} 916}
906 917
907SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz, 918SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
908 long, msgtyp, int, msgflg) 919 long, msgtyp, int, msgflg)
909{ 920{
910 long err, mtype; 921 return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
911
912 err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
913 if (err < 0)
914 goto out;
915
916 if (put_user(mtype, &msgp->mtype))
917 err = -EFAULT;
918out:
919 return err;
920} 922}
921 923
922#ifdef CONFIG_PROC_FS 924#ifdef CONFIG_PROC_FS