diff options
author | Jean-Mickael Guerin <jean-mickael.guerin@6wind.com> | 2009-12-01 11:47:26 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-02 12:23:23 +0300 |
commit | d7256d0eb4c82b789125f610fea11c6e82b1bcff (patch) | |
tree | 60cf4d3350f16dfaba359933aa5ed9a8e97b0533 /net/socket.c | |
parent | 810c07194f6ef541625e65b53392e9f605611a1a (diff) | |
download | linux-d7256d0eb4c82b789125f610fea11c6e82b1bcff.tar.xz |
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.c | 24 |
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) { |