summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/msg.h8
-rw-r--r--ipc/compat.c37
-rw-r--r--ipc/msg.c45
3 files changed, 43 insertions, 47 deletions
diff --git a/include/linux/msg.h b/include/linux/msg.h
index f3f302f9c197..4e5ec3cbf464 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -31,12 +31,4 @@ struct msg_queue {
31 struct list_head q_senders; 31 struct list_head q_senders;
32}; 32};
33 33
34/* Helper routines for sys_msgsnd and sys_msgrcv */
35extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
36 size_t msgsz, int msgflg);
37extern long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
38 int msgflg,
39 long (*msg_fill)(void __user *, struct msg_msg *,
40 size_t));
41
42#endif /* _LINUX_MSG_H */ 34#endif /* _LINUX_MSG_H */
diff --git a/ipc/compat.c b/ipc/compat.c
index 00c2e3beccc8..0586687c3e31 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -34,11 +34,6 @@
34 34
35#include "util.h" 35#include "util.h"
36 36
37struct compat_msgbuf {
38 compat_long_t mtype;
39 char mtext[1];
40};
41
42int get_compat_ipc64_perm(struct ipc64_perm *to, 37int get_compat_ipc64_perm(struct ipc64_perm *to,
43 struct compat_ipc64_perm __user *from) 38 struct compat_ipc64_perm __user *from)
44{ 39{
@@ -85,38 +80,6 @@ void to_compat_ipc_perm(struct compat_ipc_perm *to, struct ipc64_perm *from)
85 to->seq = from->seq; 80 to->seq = from->seq;
86} 81}
87 82
88static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
89{
90 struct compat_msgbuf __user *msgp = dest;
91 size_t msgsz;
92
93 if (put_user(msg->m_type, &msgp->mtype))
94 return -EFAULT;
95
96 msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
97 if (store_msg(msgp->mtext, msg, msgsz))
98 return -EFAULT;
99 return msgsz;
100}
101
102COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
103 compat_ssize_t, msgsz, int, msgflg)
104{
105 struct compat_msgbuf __user *up = compat_ptr(msgp);
106 compat_long_t mtype;
107
108 if (get_user(mtype, &up->mtype))
109 return -EFAULT;
110 return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg);
111}
112
113COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
114 compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg)
115{
116 return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
117 msgflg, compat_do_msg_fill);
118}
119
120#ifndef COMPAT_SHMLBA 83#ifndef COMPAT_SHMLBA
121#define COMPAT_SHMLBA SHMLBA 84#define COMPAT_SHMLBA SHMLBA
122#endif 85#endif
diff --git a/ipc/msg.c b/ipc/msg.c
index 94690fb53f66..855da19c765a 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -730,7 +730,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg,
730 return 0; 730 return 0;
731} 731}
732 732
733long do_msgsnd(int msqid, long mtype, void __user *mtext, 733static long do_msgsnd(int msqid, long mtype, void __user *mtext,
734 size_t msgsz, int msgflg) 734 size_t msgsz, int msgflg)
735{ 735{
736 struct msg_queue *msq; 736 struct msg_queue *msq;
@@ -853,6 +853,25 @@ SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
853 return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg); 853 return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
854} 854}
855 855
856#ifdef CONFIG_COMPAT
857
858struct compat_msgbuf {
859 compat_long_t mtype;
860 char mtext[1];
861};
862
863COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
864 compat_ssize_t, msgsz, int, msgflg)
865{
866 struct compat_msgbuf __user *up = compat_ptr(msgp);
867 compat_long_t mtype;
868
869 if (get_user(mtype, &up->mtype))
870 return -EFAULT;
871 return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg);
872}
873#endif
874
856static inline int convert_mode(long *msgtyp, int msgflg) 875static inline int convert_mode(long *msgtyp, int msgflg)
857{ 876{
858 if (msgflg & MSG_COPY) 877 if (msgflg & MSG_COPY)
@@ -949,7 +968,7 @@ static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode)
949 return found ?: ERR_PTR(-EAGAIN); 968 return found ?: ERR_PTR(-EAGAIN);
950} 969}
951 970
952long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg, 971static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg,
953 long (*msg_handler)(void __user *, struct msg_msg *, size_t)) 972 long (*msg_handler)(void __user *, struct msg_msg *, size_t))
954{ 973{
955 int mode; 974 int mode;
@@ -1113,6 +1132,28 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
1113 return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill); 1132 return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
1114} 1133}
1115 1134
1135#ifdef CONFIG_COMPAT
1136static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
1137{
1138 struct compat_msgbuf __user *msgp = dest;
1139 size_t msgsz;
1140
1141 if (put_user(msg->m_type, &msgp->mtype))
1142 return -EFAULT;
1143
1144 msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
1145 if (store_msg(msgp->mtext, msg, msgsz))
1146 return -EFAULT;
1147 return msgsz;
1148}
1149
1150COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
1151 compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg)
1152{
1153 return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
1154 msgflg, compat_do_msg_fill);
1155}
1156#endif
1116 1157
1117void msg_init_ns(struct ipc_namespace *ns) 1158void msg_init_ns(struct ipc_namespace *ns)
1118{ 1159{