Commit a45424f2 authored by Junling Zheng's avatar Junling Zheng Committed by Luis Henriques

net: socket: Fix the wrong returns for recvmsg and sendmsg

Based on 08adb7da upstream.

Commit 281c9c36 (net: compat: Update get_compat_msghdr() to match
copy_msghdr_from_user() behaviour) made get_compat_msghdr() return
error if msg_sys->msg_namelen was negative, which changed the behaviors
of recvmsg and sendmsg syscall in a lib32 system:

Before commit 281c9c36, get_compat_msghdr() wouldn't fail and it would
return -EINVAL in move_addr_to_user() or somewhere if msg_sys->msg_namelen
was invalid and then syscall returned -EINVAL, which is correct.

And now, when msg_sys->msg_namelen is negative, get_compat_msghdr() will
fail and wants to return -EINVAL, however, the outer syscall will return
-EFAULT directly, which is unexpected.

This patch gets the return value of get_compat_msghdr() as well as
copy_msghdr_from_user(), then returns this expected value if
get_compat_msghdr() fails.

Fixes: 281c9c36 (net: compat: Update get_compat_msghdr() to match copy_msghdr_from_user() behaviour)
Signed-off-by: default avatarJunling Zheng <zhengjunling@huawei.com>
Signed-off-by: default avatarHanbing Xu <xuhanbing@huawei.com>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
parent 3a5f8103
......@@ -2011,14 +2011,12 @@ static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg,
int err, ctl_len, total_len;
err = -EFAULT;
if (MSG_CMSG_COMPAT & flags) {
if (get_compat_msghdr(msg_sys, msg_compat))
return -EFAULT;
} else {
if (MSG_CMSG_COMPAT & flags)
err = get_compat_msghdr(msg_sys, msg_compat);
else
err = copy_msghdr_from_user(msg_sys, msg);
if (err)
return err;
}
if (err)
return err;
if (msg_sys->msg_iovlen > UIO_FASTIOV) {
err = -EMSGSIZE;
......@@ -2223,14 +2221,12 @@ static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg,
struct sockaddr __user *uaddr;
int __user *uaddr_len;
if (MSG_CMSG_COMPAT & flags) {
if (get_compat_msghdr(msg_sys, msg_compat))
return -EFAULT;
} else {
if (MSG_CMSG_COMPAT & flags)
err = get_compat_msghdr(msg_sys, msg_compat);
else
err = copy_msghdr_from_user(msg_sys, msg);
if (err)
return err;
}
if (err)
return err;
if (msg_sys->msg_iovlen > UIO_FASTIOV) {
err = -EMSGSIZE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment