From patchwork Fri Jul 15 13:57:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 9232151 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 302CD60865 for ; Fri, 15 Jul 2016 14:27:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 215801FF8F for ; Fri, 15 Jul 2016 14:27:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1586E27F86; Fri, 15 Jul 2016 14:27:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8CFFC1FF8F for ; Fri, 15 Jul 2016 14:27:28 +0000 (UTC) Received: from localhost ([::1]:32865 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bO45P-0000zI-N1 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 15 Jul 2016 10:27:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43821) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bO42Q-0005n8-9J for qemu-devel@nongnu.org; Fri, 15 Jul 2016 10:24:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bO42P-0005T3-7J for qemu-devel@nongnu.org; Fri, 15 Jul 2016 10:24:22 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:58310) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bO42P-0005Sm-0A for qemu-devel@nongnu.org; Fri, 15 Jul 2016 10:24:21 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84_2) (envelope-from ) id 1bO3cQ-0000sP-Qy; Fri, 15 Jul 2016 14:57:30 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 15 Jul 2016 14:57:28 +0100 Message-Id: <1468591048-30230-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1468591048-30230-1-git-send-email-peter.maydell@linaro.org> References: <1468591048-30230-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PATCH 3/3] linux-user: Allow bad msg_name for recvfrom on connected socket X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Riku Voipio , patches@linaro.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The POSIX standard mandates that for a connected socket recvfrom() must ignore the msg_name and msg_namelen fields. This is awkward for QEMU because we will attempt to copy them from guest address space. Handle this by not immediately returning a TARGET_EFAULT if the copy failed, but instead passing a known-bad address to the host kernel, which can then return EFAULT or ignore the value appropriately. Signed-off-by: Peter Maydell --- linux-user/syscall.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index a21ee59..33b5cb6 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2972,7 +2972,14 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, ret = target_to_host_sockaddr(fd, msg.msg_name, tswapal(msgp->msg_name), msg.msg_namelen); - if (ret) { + if (ret == -TARGET_EFAULT) { + /* For connected sockets msg_name and msg_namelen must + * be ignored, so returning EFAULT immediately is wrong. + * Instead, pass a bad msg_name to the host kernel, and + * let it decide whether to return EFAULT or not. + */ + msg.msg_name = (void *)-1; + } else if (ret) { goto out2; } } else { @@ -3025,7 +3032,7 @@ static abi_long do_sendrecvmsg_locked(int fd, struct target_msghdr *msgp, } if (!is_error(ret)) { msgp->msg_namelen = tswap32(msg.msg_namelen); - if (msg.msg_name != NULL) { + if (msg.msg_name != NULL && msg.msg_name != (void *)-1) { ret = host_to_target_sockaddr(tswapal(msgp->msg_name), msg.msg_name, msg.msg_namelen); if (ret) {