From patchwork Thu Nov 10 20:42:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petr Vandrovec X-Patchwork-Id: 9422067 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 E259760484 for ; Thu, 10 Nov 2016 20:42:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DFC3729491 for ; Thu, 10 Nov 2016 20:42:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D2B30295C3; Thu, 10 Nov 2016 20:42:33 +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 vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6333B29491 for ; Thu, 10 Nov 2016 20:42:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936186AbcKJUmc (ORCPT ); Thu, 10 Nov 2016 15:42:32 -0500 Received: from ex13-edg-ou-001.vmware.com ([208.91.0.189]:36691 "EHLO EX13-EDG-OU-001.vmware.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935817AbcKJUmb (ORCPT ); Thu, 10 Nov 2016 15:42:31 -0500 Received: from sc9-mailhost2.vmware.com (10.113.161.72) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Thu, 10 Nov 2016 12:42:05 -0800 Received: from petr-dev3.eng.vmware.com (petr-dev2.eng.vmware.com [10.20.93.186]) by sc9-mailhost2.vmware.com (Postfix) with ESMTP id EBE57B01EB; Thu, 10 Nov 2016 12:42:29 -0800 (PST) Received: by petr-dev3.eng.vmware.com (Postfix, from userid 884) id 8DB38A00180; Thu, 10 Nov 2016 12:42:24 -0800 (PST) Date: Thu, 10 Nov 2016 12:42:24 -0800 From: Petr Vandrovec To: CC: , Subject: [PATCH] Do not dereference ERR_PTR(-EINVAL) in NFS client code Message-ID: <20161110204224.xcbu3ttyk7codgqi@petr-dev3.eng.vmware.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: NeoMutt/20161104 (1.7.1) Received-SPF: None (EX13-EDG-OU-001.vmware.com: petr@vandrovec.name does not designate permitted sender hosts) Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi, Andy Adamson's change added code that unconditionally calls rpc_clnt_xptr_switch_has_addr() with clp->cl_rpcclient from place where clp->cl_rpcclient may be still set to its initial ERR_PTR(-EINVAL) value, rather than to real RPC client. This then causes dereference of ERR_PTR(-EINVAL) + offsetof(rpc_clnt, cl_xpi.xpi_xpswitch) in net/sunrpc/clnt.c at line 2773. There seems to be other code that accesses cl_rpcclient, but as far as I can tell, all remaining sites cannot encounter clp that is in the middle of initializing. Problem is also tracked in bugzilla.kernel.org as bug 182171. As it is regression in 4.9.0, it would be great if it can be fixed before 4.9.0 is final. Thanks, Petr Vandrovec commit d2d51793392a176aaba7fe2ea3edb3c6f62d5e68 Author: Petr Vandrovec Date: Mon Nov 7 12:11:29 2016 -0800 Ignore connections that have cl_rpcclient uninitialized cl_rpcclient starts as ERR_PTR(-EINVAL), and connections like that are floating freely through the system. Most places check whether pointer is valid before dereferencing it, but newly added code in nfs_match_client does not. Which causes crashes when more than one NFS mount point is present. Signed-off-by: Petr Vandrovec --- To unsubscribe from this list: send the line "unsubscribe linux-nfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 7555ba8..ebecfb8 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -314,7 +314,8 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat /* Match the full socket address */ if (!rpc_cmp_addr_port(sap, clap)) /* Match all xprt_switch full socket addresses */ - if (!rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient, + if (IS_ERR(clp->cl_rpcclient) || + !rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient, sap)) continue;