Received: by 10.213.65.16 with SMTP id m16csp111799imf; Sun, 11 Mar 2018 18:35:02 -0700 (PDT) X-Google-Smtp-Source: AG47ELuIkZpQU7esd9nh5l4OpQOS6jOxcQPXJvzyCn+MmqbokTx/zQddgd37envQf2Qla5EPs2x/ X-Received: by 10.98.200.80 with SMTP id z77mr6117165pff.85.1520818502310; Sun, 11 Mar 2018 18:35:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1520818502; cv=none; d=google.com; s=arc-20160816; b=sA0BntbFE/vsM1FSG/zx9jNOYSIjjHfJDNDrIEkaQOSsKcwNiJLxhjELmOiaAjFG8Y 63OLHz1icO+Z5HOjUiceyqW/G1LNj3j6w6NxkO2uRC5IkJg0PFj1okSzIIfjgoJDevf+ rBWdxpkPYwk0XQ2VE7NtbnI0EusWyuvsdLTcumCEm7xnYjISgQ0Q2hsqgo1bURwMQ7lC C9f58vb4j9QtJ1z3bc+4sQT2tLgysj7pxc8vsJzXr7Nc097xB88O5+LlB7quB01XmFAv COYzBDWF0mDaMtUh+BNliI1dM03fmmF3+wdja1s/eiKyaINw6dbZbjs3cDl8Uj/Tq3YU jJHw== 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:in-reply-to :mime-version:user-agent:date:message-id:from:cc:references:to :subject:arc-authentication-results; bh=oCzWaPoJM7S9CNKCrmHjBQAZPmDK91oSSPJW3EtX+kc=; b=vsqnBwvHecWm/1eunK18JKA7tMGRzEWlnb2Ex6UQjq8vJN/L0PNxtrM6nT7aOBYv1K PuE+nwQ8b41Z4kZyAK+MRXGjAwMGugSNxWjo8exBVc8Zu7unzoSxBJxuAXEb0tI5ImFx nQKxpO/fU/7htm/Nid10/TzDmA/ADj9WDxmywZncy+fAiXRj+c8lnqp7rtKyCZYc7WRg 7vD55wV3alOexGrREISqkcQC4Lf44oWNsSi6YA9L+wZxXFOt/edLSYn46vnI4Plz1Xl/ u9biVAnMJrZBI2fBuQILehL2O0hpLh8EZ6RFSvGAEJXT+mcM1wHGB5I6g+n+p1KHmh7D tHVA== ARC-Authentication-Results: i=1; mx.google.com; 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 c23-v6si5196035pli.306.2018.03.11.18.34.48; Sun, 11 Mar 2018 18:35:02 -0700 (PDT) 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; 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 S932503AbeCLBd4 (ORCPT + 99 others); Sun, 11 Mar 2018 21:33:56 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:6230 "EHLO huawei.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932419AbeCLBdy (ORCPT ); Sun, 11 Mar 2018 21:33:54 -0400 Received: from DGGEMS405-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 2C9C199CFA262; Mon, 12 Mar 2018 09:33:41 +0800 (CST) Received: from [127.0.0.1] (10.177.16.168) by DGGEMS405-HUB.china.huawei.com (10.3.19.205) with Microsoft SMTP Server id 14.3.361.1; Mon, 12 Mar 2018 09:33:39 +0800 Subject: Re: [PATCH] net/9p: avoid -ERESTARTSYS leak to userspace To: Greg Kurz , References: <152062809886.10599.7361006774123053312.stgit@bahia.lan> CC: , , "Eric Van Hensbergen" , Ron Minnich , "Latchesar Ionkov" , "David S. Miller" , "Andrew Morton" From: jiangyiwen Message-ID: <5AA5D8ED.2080107@huawei.com> Date: Mon, 12 Mar 2018 09:33:33 +0800 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-Version: 1.0 In-Reply-To: <152062809886.10599.7361006774123053312.stgit@bahia.lan> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Originating-IP: [10.177.16.168] X-CFilter-Loop: Reflected Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2018/3/10 4:41, Greg Kurz wrote: > If it was interrupted by a signal, the 9p client may need to send some > more requests to the server for cleanup before returning to userspace. > > To avoid such a last minute request to be interrupted right away, the > client memorizes if a signal is pending, clears TIF_SIGPENDING, handles > the request and calls recalc_sigpending() before returning. > > Unfortunately, if the transmission of this cleanup request fails for any > reason, the transport returns an error and the client propagates it right > away, without calling recalc_sigpending(). > > This ends up with -ERESTARTSYS from the initially interrupted request > crawling up to syscall exit, with TIF_SIGPENDING cleared by the cleanup > request. The specific signal handling code, which is responsible for > converting -ERESTARTSYS to -EINTR is not called, and userspace receives > the confusing errno value: > > open: Unknown error 512 (512) > > This is really hard to hit in real life. I discovered the issue while > working on hot-unplug of a virtio-9p-pci device with an instrumented > QEMU allowing to control request completion. > > Both p9_client_zc_rpc() and p9_client_rpc() functions have this buggy > error path actually. Their code flow is a bit obscure and the best > thing to do would probably be a full rewrite: to really ensure this > situation of clearing TIF_SIGPENDING and returning -ERESTARTSYS can > never happen. > > But given the general lack of interest for the 9p code, I won't risk > breaking more things. So this patch simply fixes the buggy paths in > both functions with a trivial label+goto. > > Thanks to Laurent Dufour for his help and suggestions on how to find > the root cause and how to fix it. > Looks good. Reviewed-by: Yiwen Jiang > Signed-off-by: Greg Kurz > --- > net/9p/client.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/net/9p/client.c b/net/9p/client.c > index b433aff5ff13..e6cae8332e2e 100644 > --- a/net/9p/client.c > +++ b/net/9p/client.c > @@ -769,7 +769,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) > if (err < 0) { > if (err != -ERESTARTSYS && err != -EFAULT) > c->status = Disconnected; > - goto reterr; > + goto recalc_sigpending; > } > again: > /* Wait for the response */ > @@ -804,6 +804,7 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) > if (req->status == REQ_STATUS_RCVD) > err = 0; > } > +recalc_sigpending: > if (sigpending) { > spin_lock_irqsave(¤t->sighand->siglock, flags); > recalc_sigpending(); > @@ -867,7 +868,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, > if (err == -EIO) > c->status = Disconnected; > if (err != -ERESTARTSYS) > - goto reterr; > + goto recalc_sigpending; > } > if (req->status == REQ_STATUS_ERROR) { > p9_debug(P9_DEBUG_ERROR, "req_status error %d\n", req->t_err); > @@ -885,6 +886,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, > if (req->status == REQ_STATUS_RCVD) > err = 0; > } > +recalc_sigpending: > if (sigpending) { > spin_lock_irqsave(¤t->sighand->siglock, flags); > recalc_sigpending(); > > > . >