summaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorJean-Mickael Guerin <jean-mickael.guerin@6wind.com>2009-12-01 09:47:26 +0100
committerDavid S. Miller <davem@davemloft.net>2009-12-02 10:23:23 +0100
commitd7256d0eb4c82b789125f610fea11c6e82b1bcff (patch)
tree60cf4d3350f16dfaba359933aa5ed9a8e97b0533 /net/socket.c
parentsctp: fix sctp_setsockopt_autoclose compile warning (diff)
downloadlinux-d7256d0eb4c82b789125f610fea11c6e82b1bcff.tar.xz
linux-d7256d0eb4c82b789125f610fea11c6e82b1bcff.zip
net: compat_mmsghdr must be used in sys_recvmmsg
Both to traverse the entries and to set the msg_len field. Commiter note: folded two patches and avoided one branch repeating the compat test. Signed-off-by: Jean-Mickael Guerin <jean-mickael.guerin@6wind.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/net/socket.c b/net/socket.c
index 402abb39cbfe..b94c3dd71015 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2144,6 +2144,7 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
int fput_needed, err, datagrams;
struct socket *sock;
struct mmsghdr __user *entry;
+ struct compat_mmsghdr __user *compat_entry;
struct msghdr msg_sys;
struct timespec end_time;
@@ -2163,19 +2164,30 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
goto out_put;
entry = mmsg;
+ compat_entry = (struct compat_mmsghdr __user *)mmsg;
while (datagrams < vlen) {
/*
* No need to ask LSM for more than the first datagram.
*/
- err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
- &msg_sys, flags, datagrams);
- if (err < 0)
- break;
- err = put_user(err, &entry->msg_len);
+ if (MSG_CMSG_COMPAT & flags) {
+ err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry,
+ &msg_sys, flags, datagrams);
+ if (err < 0)
+ break;
+ err = __put_user(err, &compat_entry->msg_len);
+ ++compat_entry;
+ } else {
+ err = __sys_recvmsg(sock, (struct msghdr __user *)entry,
+ &msg_sys, flags, datagrams);
+ if (err < 0)
+ break;
+ err = put_user(err, &entry->msg_len);
+ ++entry;
+ }
+
if (err)
break;
- ++entry;
++datagrams;
if (timeout) {