diff options
-rw-r--r-- | include/linux/msg.h | 8 | ||||
-rw-r--r-- | ipc/compat.c | 37 | ||||
-rw-r--r-- | ipc/msg.c | 45 |
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 */ | ||
35 | extern long do_msgsnd(int msqid, long mtype, void __user *mtext, | ||
36 | size_t msgsz, int msgflg); | ||
37 | extern 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 | ||
37 | struct compat_msgbuf { | ||
38 | compat_long_t mtype; | ||
39 | char mtext[1]; | ||
40 | }; | ||
41 | |||
42 | int get_compat_ipc64_perm(struct ipc64_perm *to, | 37 | int 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 | ||
88 | static 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 | |||
102 | COMPAT_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 | |||
113 | COMPAT_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 |
@@ -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 | ||
733 | long do_msgsnd(int msqid, long mtype, void __user *mtext, | 733 | static 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 | |||
858 | struct compat_msgbuf { | ||
859 | compat_long_t mtype; | ||
860 | char mtext[1]; | ||
861 | }; | ||
862 | |||
863 | COMPAT_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 | |||
856 | static inline int convert_mode(long *msgtyp, int msgflg) | 875 | static 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 | ||
952 | long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg, | 971 | static 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 | ||
1136 | static 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 | |||
1150 | COMPAT_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 | ||
1117 | void msg_init_ns(struct ipc_namespace *ns) | 1158 | void msg_init_ns(struct ipc_namespace *ns) |
1118 | { | 1159 | { |