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>
This commit is contained in:
parent
810c07194f
commit
d7256d0eb4
14
net/socket.c
14
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.
|
||||
*/
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue