diff options
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/net/socket.c b/net/socket.c index ebed4b68f768..c226aceee65b 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1964,6 +1964,16 @@ struct used_address { | |||
1964 | unsigned int name_len; | 1964 | unsigned int name_len; |
1965 | }; | 1965 | }; |
1966 | 1966 | ||
1967 | static int copy_msghdr_from_user(struct msghdr *kmsg, | ||
1968 | struct msghdr __user *umsg) | ||
1969 | { | ||
1970 | if (copy_from_user(kmsg, umsg, sizeof(struct msghdr))) | ||
1971 | return -EFAULT; | ||
1972 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) | ||
1973 | return -EINVAL; | ||
1974 | return 0; | ||
1975 | } | ||
1976 | |||
1967 | static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | 1977 | static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
1968 | struct msghdr *msg_sys, unsigned int flags, | 1978 | struct msghdr *msg_sys, unsigned int flags, |
1969 | struct used_address *used_address) | 1979 | struct used_address *used_address) |
@@ -1982,8 +1992,11 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | |||
1982 | if (MSG_CMSG_COMPAT & flags) { | 1992 | if (MSG_CMSG_COMPAT & flags) { |
1983 | if (get_compat_msghdr(msg_sys, msg_compat)) | 1993 | if (get_compat_msghdr(msg_sys, msg_compat)) |
1984 | return -EFAULT; | 1994 | return -EFAULT; |
1985 | } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) | 1995 | } else { |
1986 | return -EFAULT; | 1996 | err = copy_msghdr_from_user(msg_sys, msg); |
1997 | if (err) | ||
1998 | return err; | ||
1999 | } | ||
1987 | 2000 | ||
1988 | if (msg_sys->msg_iovlen > UIO_FASTIOV) { | 2001 | if (msg_sys->msg_iovlen > UIO_FASTIOV) { |
1989 | err = -EMSGSIZE; | 2002 | err = -EMSGSIZE; |
@@ -2191,8 +2204,11 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, | |||
2191 | if (MSG_CMSG_COMPAT & flags) { | 2204 | if (MSG_CMSG_COMPAT & flags) { |
2192 | if (get_compat_msghdr(msg_sys, msg_compat)) | 2205 | if (get_compat_msghdr(msg_sys, msg_compat)) |
2193 | return -EFAULT; | 2206 | return -EFAULT; |
2194 | } else if (copy_from_user(msg_sys, msg, sizeof(struct msghdr))) | 2207 | } else { |
2195 | return -EFAULT; | 2208 | err = copy_msghdr_from_user(msg_sys, msg); |
2209 | if (err) | ||
2210 | return err; | ||
2211 | } | ||
2196 | 2212 | ||
2197 | if (msg_sys->msg_iovlen > UIO_FASTIOV) { | 2213 | if (msg_sys->msg_iovlen > UIO_FASTIOV) { |
2198 | err = -EMSGSIZE; | 2214 | err = -EMSGSIZE; |