Received: by 10.223.185.111 with SMTP id b44csp767939wrg; Fri, 9 Mar 2018 13:21:49 -0800 (PST) X-Google-Smtp-Source: AG47ELt1CY5fZNVwbjIrxCpcO/i63nGQsF7dk5cP1c7zOoWNttDhnyJpadjgZJ55hpsMp4SQgv5r X-Received: by 10.101.101.5 with SMTP id x5mr25213119pgv.195.1520630508993; Fri, 09 Mar 2018 13:21:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520630508; cv=none; d=google.com; s=arc-20160816; b=z2n+VtDObfSKOKgWv6tRVWsLt+QP/lRf5tSx4aUSjVvKVzJpmRF+1UUX3uOaBCqPAG u8Z7fcJsCq4z+Dmc8SdHowjJosCVhDyt22Q1mvufBXSZiHjKNOoFYldHeIFIWwblVMGb Yq/cYNWoSz7C3PWg6SmzEuGgHgVu7WNX18LIDUq3PIg6JmsS2MvPO/boR1hApu8KVCXY dX2Xm4igAw/bkTm9q/YAPyXkg6N+zb6fA5ck3YwyLHBmkw5Ju0tZvkuMU05/8o5Cwwry 88WCFhprXpSbsQHAUH1ZiUSWHZsff5hYzNDExaSpMRvsDU/eoC6aMKZkn71xLQSJxpNY iKow== 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:message-id:date:cc:to:from:subject :arc-authentication-results; bh=jxEem+HN86Jjjc4qU3SQL2WqorXQo0NZnQADTd5+EBU=; b=0Ixl+5d6/L0dRNhYGdfUxAJemu5n3BGlSm3cJsIzom3XQ17UCQQCMlMzgSJzX2hpYl 5HidZU3AIaKRjukkE5WQ+Iz5qXvfvQh1Iog5Jdb1fBWEEpVonT9H3gweUitkLYJFhhq6 7+VzWSH9+PnrRbhtmYTRwDsemjYJ61LzzzVbtxoTuA0WBhRSWbhBRJdZfVpdW0tYxHA2 aKCPjGNX9xgd4kU5TDizhokhomXSOBnKcPtFD6sbt5uobzUk37v3faf5fDGpusyk6qK0 jt6SglguswQ+K9Wf9iejlxbQkGln7+YpHEFG+wjvj2FBzOQRfmiTGML4iTCCoUBP/9F6 3FbA== 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 f6si1277905pgn.165.2018.03.09.13.21.33; Fri, 09 Mar 2018 13:21:48 -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; 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 S932337AbeCIVUj (ORCPT + 99 others); Fri, 9 Mar 2018 16:20:39 -0500 Received: from 5.mo4.mail-out.ovh.net ([188.165.44.50]:54144 "EHLO 5.mo4.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751268AbeCIVUi (ORCPT ); Fri, 9 Mar 2018 16:20:38 -0500 X-Greylist: delayed 2322 seconds by postgrey-1.27 at vger.kernel.org; Fri, 09 Mar 2018 16:20:38 EST Received: from player728.ha.ovh.net (unknown [10.109.108.88]) by mo4.mail-out.ovh.net (Postfix) with ESMTP id E2F4015628B for ; Fri, 9 Mar 2018 21:41:54 +0100 (CET) Received: from bahia.lan (lns-bzn-46-82-253-208-248.adsl.proxad.net [82.253.208.248]) (Authenticated sender: groug@kaod.org) by player728.ha.ovh.net (Postfix) with ESMTPA id BC3675400A6; Fri, 9 Mar 2018 21:41:44 +0100 (CET) Subject: [PATCH] net/9p: avoid -ERESTARTSYS leak to userspace From: Greg Kurz To: linux-kernel@vger.kernel.org Cc: netdev@vger.kernel.org, v9fs-developer@lists.sourceforge.net, Eric Van Hensbergen , Ron Minnich , Latchesar Ionkov , "David S. Miller" , Andrew Morton , Yiwen Jiang Date: Fri, 09 Mar 2018 21:41:38 +0100 Message-ID: <152062809886.10599.7361006774123053312.stgit@bahia.lan> User-Agent: StGit/0.17.1-46-g6855-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Ovh-Tracer-Id: 17406975510168312198 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtfedrkeeigddufeelucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. 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();