Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp17928534ybl; Thu, 2 Jan 2020 15:00:59 -0800 (PST) X-Google-Smtp-Source: APXvYqz5MV5YdDMIn6VLgA2ld9vHW0nzGnAU5kVWbogdJqF4n2zakJtUliyBKHoUMN4xsk/6NZB7 X-Received: by 2002:a05:6830:174e:: with SMTP id 14mr68495928otz.142.1578006059540; Thu, 02 Jan 2020 15:00:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1578006059; cv=none; d=google.com; s=arc-20160816; b=xvikF3nITXYaYvc5gp4T3R2bYkrSkm9n4c7VB7uXeKYE9angMCd+cyo9Rm/tMX5KeB 95JUbmwN1xOAxeNBmiJ9GCSD9AwT+Wd2UQPUP9bTlywtK2Z38m/R+Y8Ynm10ahqEJ/VI jOqS0ZgI6eL5wiqiqvKMmwBMq1OeROWHvxtmXExSelE3QQA8bD3xvjPMS7g2ZmzV1KKC Gg4U8A9jP4toiFQlun+VKgzp1wLSVjKFIxBuP/3HaQyfPeN9A9NzDMaF9xR5yCNBx2t4 lGzPxZV28xZqKHZJmrKIVtFGbxA5lVNGlCY4IM8xka6C6PJaSn93b+b+zF+1lBFEP4u3 eNnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=kJptfafyEsiMgX36l6iJL31KUCW8cDEZ8IWqLWiA+WQ=; b=Awdk901PABsyz7R2x4gVcEJTIb9JO9EChY/socQSl2PUZMcLf7v14Sg0nBzsp6BNBv 0JGSCj2u+qk8ZTvN8STe1aglaW+jv3ayJ/6M5ZxhaH2/TcsTncnOdMe88SV7JAMEwbvq bT3nzJVFRq+aJgrOg4jfyJrqZ3ZD4UTaFqZ8tkQ7e9Ag9Wfz0VjkuryhOUlBRZPI1AyQ uoKVco4b+9Rrj2Z6gpBzPCL7PsFJp8h8GHDz0Xzcx4GoFnVWKi5PUEseDI0mJbkoXMQF XltvuVA3M5B3opTnjrFiPQ4ndb0SSGWSEKz7qkaVCuAHIR0j9btkd26orsQ8PR8gI+ji 2ALA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=BUVTtNJP; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j20si28950630otp.147.2020.01.02.15.00.47; Thu, 02 Jan 2020 15:00:59 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=BUVTtNJP; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727790AbgABWPY (ORCPT + 99 others); Thu, 2 Jan 2020 17:15:24 -0500 Received: from mail.kernel.org ([198.145.29.99]:56064 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728049AbgABWPT (ORCPT ); Thu, 2 Jan 2020 17:15:19 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D0ABF227BF; Thu, 2 Jan 2020 22:15:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1578003318; bh=7XcAk6WwlPZiHwrNeSvnm56FOXEsLlHpDvmdPRl2cqQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BUVTtNJPk/Iy3ZQAfl20yvepQSdT2c8CeuSIG+XyNWpYXXe9JbjmTHs6CLEmU+qB/ 6oxPa553Y3nfJRmy3l4+gt33kA0uLwZmavAwjI/aLrBMUP/ZVRKq6Mp7qEwhB+a9Xy /5WWPo8gii2E7e/TmwsFktoCxDNJQWEfTK+NI73U= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Johannes Berg , Richard Weinberger , Sasha Levin Subject: [PATCH 5.4 110/191] um: virtio: Keep reading on -EAGAIN Date: Thu, 2 Jan 2020 23:06:32 +0100 Message-Id: <20200102215841.663236426@linuxfoundation.org> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200102215829.911231638@linuxfoundation.org> References: <20200102215829.911231638@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Johannes Berg [ Upstream commit 7e60746005573a06149cdee7acedf428906f3a59 ] When we get an interrupt from the socket getting readable, and start reading, there's a possibility for a race. This depends on the implementation of the device, but e.g. with qemu's libvhost-user, we can see: device virtio_uml --------------------------------------- write header get interrupt read header read body -> returns -EAGAIN write body The -EAGAIN return is because the socket is non-blocking, and then this leads us to abandon this message. In fact, we've already read the header, so when the get another signal/interrupt for the body, we again read it as though it's a new message header, and also abandon it for the same reason (wrong size etc.) This essentially breaks things, and if that message was one that required a response, it leads to a deadlock as the device is waiting for the response but we'll never reply. Fix this by spinning on -EAGAIN as well when we read the message body. We need to handle -EAGAIN as "no message" while reading the header, since we share an interrupt. Note that this situation is highly unlikely to occur in normal usage, since there will be very few messages and only in the startup phase. With the inband call feature this does tend to happen (eventually) though. Signed-off-by: Johannes Berg Signed-off-by: Richard Weinberger Signed-off-by: Sasha Levin --- arch/um/drivers/virtio_uml.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index fc8c52cff5aa..c5643a59a8c7 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -83,7 +83,7 @@ static int full_sendmsg_fds(int fd, const void *buf, unsigned int len, return 0; } -static int full_read(int fd, void *buf, int len) +static int full_read(int fd, void *buf, int len, bool abortable) { int rc; @@ -93,7 +93,7 @@ static int full_read(int fd, void *buf, int len) buf += rc; len -= rc; } - } while (len && (rc > 0 || rc == -EINTR)); + } while (len && (rc > 0 || rc == -EINTR || (!abortable && rc == -EAGAIN))); if (rc < 0) return rc; @@ -104,7 +104,7 @@ static int full_read(int fd, void *buf, int len) static int vhost_user_recv_header(int fd, struct vhost_user_msg *msg) { - return full_read(fd, msg, sizeof(msg->header)); + return full_read(fd, msg, sizeof(msg->header), true); } static int vhost_user_recv(int fd, struct vhost_user_msg *msg, @@ -118,7 +118,7 @@ static int vhost_user_recv(int fd, struct vhost_user_msg *msg, size = msg->header.size; if (size > max_payload_size) return -EPROTO; - return full_read(fd, &msg->payload, size); + return full_read(fd, &msg->payload, size, false); } static int vhost_user_recv_resp(struct virtio_uml_device *vu_dev, -- 2.20.1