[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <1433150880-9976-1-git-send-email-zhengjunling@huawei.com>
Date: Mon, 1 Jun 2015 09:28:00 +0000
From: Junling Zheng <zhengjunling@...wei.com>
To: <gregkh@...uxfoundation.org>
CC: <lizefan@...wei.com>, <viro@...iv.linux.org.uk>,
<davem@...emloft.net>, <xuhanbing@...wei.com>,
<stable@...r.kernel.org>, <netdev@...r.kernel.org>
Subject: [RFC] [PATCH] net: socket: Fix the wrong returns for recvmsg and sendmsg
Hi, Greg:
We found that after v3.10.73, recvmsg might return -EFAULT while -EINVAL
was expected.
We tested it through the recvmsg01 testcase come from LTP testsuit. It set
msg->msg_namelen to -1 and the recvmsg syscall returned errno 14, which is
unexpected (errno 22 is expected):
recvmsg01 4 TFAIL : invalid socket length ; returned -1 (expected -1),
errno 14 (expected 22)
Linux mainline has no this bug for commit 08adb7dab fixes it accidentally.
However, it is too large and complex to be backported to LTS 3.10.
So, I made the following patch to fix the above problem for LTS 3.10.
Cheers,
Junling
============
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: Junling Zheng <zhengjunling@...wei.com>
Signed-off-by: Hanbing Xu <xuhanbing@...wei.com>
Cc: Li Zefan <lizefan@...wei.com>
Cc: Al Viro <viro@...iv.linux.org.uk>
Cc: David Miller <davem@...emloft.net>
---
net/socket.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/net/socket.c b/net/socket.c
index fc90b4f..53b6e41 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1988,14 +1988,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;
@@ -2200,14 +2198,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;
--
1.8.3.4
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists