Received: by 10.223.176.5 with SMTP id f5csp2180595wra; Thu, 8 Feb 2018 09:40:22 -0800 (PST) X-Google-Smtp-Source: AH8x225MoCPFi6TZVAldYqnxtIzantGJLRQzKrBiP9R9ZIAFVQliKE/5ru9KHREqS9wsDqs27o8+ X-Received: by 10.99.159.10 with SMTP id g10mr1112444pge.27.1518111622303; Thu, 08 Feb 2018 09:40:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518111622; cv=none; d=google.com; s=arc-20160816; b=lwKfziITWhc94AI7pt8qaDcctMdsWr1GwuGCnrNvK720wU/rwBTuY7z2dUUlyv5yeV PaqdTvNiNmczF3Ks+azZTnJfXCeNGoIiKQm0vkipq6crvY/01Y2by4jo9rzZe2GOEghf SzOT/wvLO4w10VvEbrN8aJgLBq6dxVqIuPGqTNBCsWYGdSCc7Gniebv46r8hCWhuR+g5 8BBr64hPUdbecxLS4xWs/8lpHmL/ShD+tk8c/Pj1/bxsEl8rZYkNqONpbVnKJZS2z5Eu Tu9jVBX92Nvn59jtxi52WjWylz6z05raqQVWQJKWjhsKYvzp4+o1JWvCMdtABjpjaYn+ h8KQ== 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=618eqEX1mTlif8L9/dyaf0fQYgruzKCF8REFE03Ujww=; b=rg/URoEfhVu2urC/q5hFJ66sjab3ax8H2UuEHqVHGNQGcF8LrDojKTOEkQlnuUWuIs 6avUwGj1zwRVamY7JEKtQWlDQk54YUexQkAbzVo2rEq2iVoaKXY/3gW3wvLCGqJjFpUg 5rkYH/hA76ErVWWYhHizixwKWqe/XMGfY+VIXaMz6cI9i3MVEX3N78KhXptHsIHHc1Ux wF54uz49wTCU6NHaYwWxxgYFncBGQDQg3qVz89cpC/aamE19zj/1QOyKUneahCB9giMC S1p/3931+p5MDY9ZulmcxY4Mrv3oJEm8lE7Uf5l0iT+jBSgJZ2cMnleRvbaeJrnwzB8f L+qw== 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 60-v6si235655plc.444.2018.02.08.09.40.06; Thu, 08 Feb 2018 09:40:22 -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 S1752185AbeBHRjH (ORCPT + 99 others); Thu, 8 Feb 2018 12:39:07 -0500 Received: from 6.mo68.mail-out.ovh.net ([46.105.63.100]:42301 "EHLO 6.mo68.mail-out.ovh.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751700AbeBHRjG (ORCPT ); Thu, 8 Feb 2018 12:39:06 -0500 Received: from player711.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo68.mail-out.ovh.net (Postfix) with ESMTP id 80063C12DF for ; Thu, 8 Feb 2018 18:39:03 +0100 (CET) Received: from bahia.lab.toulouse-stg.fr.ibm.com (deibp9eh1--blueice1n3.emea.ibm.com [195.212.29.165]) (Authenticated sender: groug@kaod.org) by player711.ha.ovh.net (Postfix) with ESMTPA id 8FB913800AE; Thu, 8 Feb 2018 18:38:55 +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" , Al Viro Date: Thu, 08 Feb 2018 18:38:49 +0100 Message-ID: <151811152925.12219.16418114797025615002.stgit@bahia.lab.toulouse-stg.fr.ibm.com> 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: 10031486696758942086 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedtfedrudekgddutdefucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuqfggjfdpvefjgfevmfevgfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddm 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, clear TIF_SIGPENDING, handle the request and call 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 fix 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 4c8cf9c1631a..5154eaf19fff 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();