diff options
author | Jean-Mickael Guerin <jean-mickael.guerin@6wind.com> | 2009-12-01 03:47:26 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-02 04:23:23 -0500 |
commit | d7256d0eb4c82b789125f610fea11c6e82b1bcff (patch) | |
tree | 60cf4d3350f16dfaba359933aa5ed9a8e97b0533 /net/socket.c | |
parent | 810c07194f6ef541625e65b53392e9f605611a1a (diff) |
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, | |||
2144 | int fput_needed, err, datagrams; | 2144 | int fput_needed, err, datagrams; |
2145 | struct socket *sock; | 2145 | struct socket *sock; |
2146 | struct mmsghdr __user *entry; | 2146 | struct mmsghdr __user *entry; |
2147 | struct compat_mmsghdr __user *compat_entry; | ||
2147 | struct msghdr msg_sys; | 2148 | struct msghdr msg_sys; |
2148 | struct timespec end_time; | 2149 | struct timespec end_time; |
2149 | 2150 | ||
@@ -2163,19 +2164,30 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2163 | goto out_put; | 2164 | goto out_put; |
2164 | 2165 | ||
2165 | entry = mmsg; | 2166 | entry = mmsg; |
2167 | compat_entry = (struct compat_mmsghdr __user *)mmsg; | ||
2166 | 2168 | ||
2167 | while (datagrams < vlen) { | 2169 | while (datagrams < vlen) { |
2168 | /* | 2170 | /* |
2169 | * No need to ask LSM for more than the first datagram. | 2171 | * No need to ask LSM for more than the first datagram. |
2170 | */ | 2172 | */ |
2171 | err = __sys_recvmsg(sock, (struct msghdr __user *)entry, | 2173 | if (MSG_CMSG_COMPAT & flags) { |
2172 | &msg_sys, flags, datagrams); | 2174 | err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry, |
2173 | if (err < 0) | 2175 | &msg_sys, flags, datagrams); |
2174 | break; | 2176 | if (err < 0) |
2175 | err = put_user(err, &entry->msg_len); | 2177 | break; |
2178 | err = __put_user(err, &compat_entry->msg_len); | ||
2179 | ++compat_entry; | ||
2180 | } else { | ||
2181 | err = __sys_recvmsg(sock, (struct msghdr __user *)entry, | ||
2182 | &msg_sys, flags, datagrams); | ||
2183 | if (err < 0) | ||
2184 | break; | ||
2185 | err = put_user(err, &entry->msg_len); | ||
2186 | ++entry; | ||
2187 | } | ||
2188 | |||
2176 | if (err) | 2189 | if (err) |
2177 | break; | 2190 | break; |
2178 | ++entry; | ||
2179 | ++datagrams; | 2191 | ++datagrams; |
2180 | 2192 | ||
2181 | if (timeout) { | 2193 | if (timeout) { |