From patchwork Wed Aug 28 00:44:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13780263 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3B96A18D for ; Wed, 28 Aug 2024 00:44:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805892; cv=none; b=fJCLpNp3dISYTUuOWAhdzjwKFH+x4ZgtGZ6vx6SwtfF/zpzQ9WIyiTzEQ9u11TpCin+CT5DVL9w8QHDwUot4hacrzf55GEeqm/wK4GRZRaVFNy8zfQznmL97aSrzvgxcPlO9TkxQTFsGA3THJya6FSpjSusWh1D2N4+8TMTDb2Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805892; c=relaxed/simple; bh=ut9N99Mf3TfW0dNvgE1WXcpvz+4rjxdLbddrpcSa7IA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uO1Ib6cJg6VoB4mNoN8ZcSPpWJriw8uQzL9EE5HR97ZVxe1SjV3lbrdD+LSE0vY6j82y347T3OrA3dzJUdIXjMNQf6kjb+PdK8/jUjy6FH2m5r0Jnx0xRsPdWBcxiHW0RqlLih5mH8ZQk2tDDWtY7atoc5A9mIYdbDV4lxS/4oo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HwOzL4gb; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HwOzL4gb" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AAF34C4DDED; Wed, 28 Aug 2024 00:44:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724805892; bh=ut9N99Mf3TfW0dNvgE1WXcpvz+4rjxdLbddrpcSa7IA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HwOzL4gbs8NXDcGQXreJDw/caQZwUBSMzJVbgakiMQ92Xvk34Gji/3OfWO69fIKvv 7PFkuUzHpPCwsrT9x0ravxEmMyDCEw9p68U5INk4twY9oEIM8rIEr13cnu4erniILd QBjWwxrSY2pGnSb2sEm+EOjetRi2SuLMngfJ1MoCIaFoODKmjKMA+0tcVKf9+F0vlH 6T0EwfgGnXXZfK3O2rPfOAiglITBN5cqYIKHtFV/jGw2Js19cYKRIwrcj9NU0w6GFn kdjHhIy/dmpmWaSW9biWT9qqGtRckZQjFU639qZvAoSrdiKAz7u6lWKca/rKW3PV+r FfN8O3pBeSEmw== From: cel@kernel.org To: Neil Brown , Mike Snitzer Cc: Subject: [RFC PATCH 1/6] NFSD: Handle @rqstp == NULL in check_nfsd_access() Date: Tue, 27 Aug 2024 20:44:40 -0400 Message-ID: <20240828004445.22634-2-cel@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240828004445.22634-1-cel@kernel.org> References: <20240828004445.22634-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown LOCALIO-initiated open operations are not running in an nfsd thread and thus do not have an associated svc_rqst context. Signed-off-by: NeilBrown Co-developed-by: Mike Snitzer Signed-off-by: Mike Snitzer Signed-off-by: Chuck Lever --- fs/nfsd/export.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 7bb4f2075ac5..46a4d989c850 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -1074,10 +1074,29 @@ static struct svc_export *exp_find(struct cache_detail *cd, return exp; } +/** + * check_nfsd_access - check if access to export is allowed. + * @exp: svc_export that is being accessed. + * @rqstp: svc_rqst attempting to access @exp (will be NULL for LOCALIO). + * + * Return values: + * %nfs_ok if access is granted, or + * %nfserr_wrongsec if access is denied + */ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp) { struct exp_flavor_info *f, *end = exp->ex_flavors + exp->ex_nflavors; - struct svc_xprt *xprt = rqstp->rq_xprt; + struct svc_xprt *xprt; + + /* + * The target use case for rqstp being NULL is LOCALIO, which + * currently only supports AUTH_UNIX. The behavior for LOCALIO + * is therefore the same as the AUTH_UNIX check below. + */ + if (!rqstp) + return nfs_ok; + + xprt = rqstp->rq_xprt; if (exp->ex_xprtsec_modes & NFSEXP_XPRTSEC_NONE) { if (!test_bit(XPT_TLS_SESSION, &xprt->xpt_flags)) @@ -1098,17 +1117,17 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp) ok: /* legacy gss-only clients are always OK: */ if (exp->ex_client == rqstp->rq_gssclient) - return 0; + return nfs_ok; /* ip-address based client; check sec= export option: */ for (f = exp->ex_flavors; f < end; f++) { if (f->pseudoflavor == rqstp->rq_cred.cr_flavor) - return 0; + return nfs_ok; } /* defaults in absence of sec= options: */ if (exp->ex_nflavors == 0) { if (rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL || rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX) - return 0; + return nfs_ok; } /* If the compound op contains a spo_must_allowed op, @@ -1118,7 +1137,7 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp) */ if (nfsd4_spo_must_allow(rqstp)) - return 0; + return nfs_ok; denied: return nfserr_wrongsec; From patchwork Wed Aug 28 00:44:41 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13780264 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1547217C7C for ; Wed, 28 Aug 2024 00:44:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805894; cv=none; b=A82iqXg/MJi20Tc9kT9TpVqYXFGepvq3zrhl7bXWeTG2gJcKNnyjZMkfhHuU6uxY/E1A35C0EpLCdjcs26uXNtgGDVNFOKs9rZ5bF5zbjLDw0ovjiYDqT9C6TU08QoXKOaquMnEnKa1CwYTfP0iKLIOdf7HpRpNOQqCpLOFe1aE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805894; c=relaxed/simple; bh=zQlI4DI4zHhcv21oEfLRiwfFWAei0sV+Ptbq/I5/kyw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HLOmN6nU8QMofUx/XcOFa9TKZy324r5FkiQzzJpTcxw1dUC0GR1Yqam8a+FLCLvroXlhy6FX95UtQvBxhSm7sGZazwK0h0HWyy5KNIeZop/3cu9npt46x7p1JCfjQyMohBRG9M9TVEzhbwYY1nTmYVswiy6GPHNGveHyIM7TNhM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RzKf59Ya; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RzKf59Ya" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5B2A9C4DDED; Wed, 28 Aug 2024 00:44:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724805893; bh=zQlI4DI4zHhcv21oEfLRiwfFWAei0sV+Ptbq/I5/kyw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RzKf59Yab/NTqZRFLmKtXyq+MwZ0Vf8+knKQVsjpWjlr7Q8p3CfrYYxkvBRdX2ITs oeYzZCqhF8LYNmGa/XzdZCRTC3K6qWkYW9uvFmJYG+djo9/WfK7Ca8t8spIOsld08r 0cOnP7jR3I5MXIZ4vt/JQ+afomS3a74hpglHrvpiAbPvAb6QDAHL5MN3M0IXZkE07P GI5wijBzvegMtLwW3FvHAmVlT9hroA2bkYflYLq9gibYK/NZOFPxXX/o01azL5WJJo i1uJNuLniXbYjE/THRdIaIo+AY7Xa5g9tzePeutFXf5x72TmdmcNIBvAxiuUVlChAJ BZx/75mFTPw1A== From: cel@kernel.org To: Neil Brown , Mike Snitzer Cc: Subject: [RFC PATCH 2/6] NFSD: Refactor nfsd_setuser_and_check_port() Date: Tue, 27 Aug 2024 20:44:41 -0400 Message-ID: <20240828004445.22634-3-cel@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240828004445.22634-1-cel@kernel.org> References: <20240828004445.22634-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown There are several places where __fh_verify unconditionally dereferences rqstp to check that the connection is suitably secure. They look at rqstp->rq_xprt which is not meaningful in the target use case of "localio" NFS in which the client talks directly to the local server. Prepare these to always succeed when rqstp is NULL. Signed-off-by: NeilBrown Co-developed-by: Mike Snitzer Signed-off-by: Mike Snitzer Signed-off-by: Chuck Lever --- fs/nfsd/nfsfh.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 50d23d56f403..4b964a71a504 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -87,23 +87,24 @@ nfsd_mode_check(struct dentry *dentry, umode_t requested) return nfserr_wrong_type; } -static bool nfsd_originating_port_ok(struct svc_rqst *rqstp, int flags) +static bool nfsd_originating_port_ok(struct svc_rqst *rqstp, + struct svc_cred *cred, + struct svc_export *exp) { - if (flags & NFSEXP_INSECURE_PORT) + if (nfsexp_flags(cred, exp) & NFSEXP_INSECURE_PORT) return true; /* We don't require gss requests to use low ports: */ - if (rqstp->rq_cred.cr_flavor >= RPC_AUTH_GSS) + if (cred->cr_flavor >= RPC_AUTH_GSS) return true; return test_bit(RQ_SECURE, &rqstp->rq_flags); } static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, + struct svc_cred *cred, struct svc_export *exp) { - int flags = nfsexp_flags(&rqstp->rq_cred, exp); - /* Check if the request originated from a secure port. */ - if (!nfsd_originating_port_ok(rqstp, flags)) { + if (rqstp && !nfsd_originating_port_ok(rqstp, cred, exp)) { RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); dprintk("nfsd: request from insecure port %s!\n", svc_print_addr(rqstp, buf, sizeof(buf))); @@ -111,7 +112,7 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, } /* Set user creds for this exportpoint */ - return nfserrno(nfsd_setuser(&rqstp->rq_cred, exp)); + return nfserrno(nfsd_setuser(cred, exp)); } static inline __be32 check_pseudo_root(struct dentry *dentry, @@ -219,7 +220,7 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) put_cred(override_creds(new)); put_cred(new); } else { - error = nfsd_setuser_and_check_port(rqstp, exp); + error = nfsd_setuser_and_check_port(rqstp, &rqstp->rq_cred, exp); if (error) goto out; } @@ -358,7 +359,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) if (error) goto out; - error = nfsd_setuser_and_check_port(rqstp, exp); + error = nfsd_setuser_and_check_port(rqstp, &rqstp->rq_cred, exp); if (error) goto out; From patchwork Wed Aug 28 00:44:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13780265 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF6391BC20 for ; Wed, 28 Aug 2024 00:44:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805895; cv=none; b=njzBL69XEffbhSAmRpnOlmxmqWetE/H54VJOeUHeJW0JzhRGnsLoFzg1w31tPMIwotOPUt8J0iEKfDgKe9HmVlevKDfWOrDSOKRexaGF9Q31r1mqlUE0um9lRRwkxrVkIUYPjRIjWMAYOGCWJMnT6BXKvHJWI26YbQryttfCPmw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805895; c=relaxed/simple; bh=F3RAP/hBjRM+UQdSbzvK7oOy6hXSEi0TIKMvdG/FRGg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VhnKlXY5wvZEhtXYqB9QMPS5HzTiYXuQc7nKzwsFfn+5mpiXLrIkLVag+IM/YeB0n7cn8eqiCPc+mvpqWpoayZ1z+FV0n2H7gInyrk7G8pV/DM40gJVjTfbvRo25XyI4Wq1YfLDeYcCQcIcot69cXbD8wK8YPif9MN3i3E7z3Rg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Bk+FtEgH; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Bk+FtEgH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9E33C4DDEE; Wed, 28 Aug 2024 00:44:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724805895; bh=F3RAP/hBjRM+UQdSbzvK7oOy6hXSEi0TIKMvdG/FRGg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Bk+FtEgHPvqsHfHeeCxnbbRppkhtYQjmgMY4OzIF7YW//17IYhzQR5Kd/faQHOeRY v71VvgSP/DG+MxRiI828KpKgeQvjoDnK6Awdwq/rHIrqY9y3Q7osqI65UngJGBxBOU EV4KxTVp4c2e/byPOhGh2V1rwIhzKorSDzq0/TBrpi1md9HlgMA7enVSQlw8ZcM1CX p5AY5sY7uZ7cV59rV+vPfJDdIQgvXSODXoKMLeDgpxUCshH7kuwqEvQwdRn+JM4FOH 8xTkNMsaEXWUkFFhi2ggi+Vvswe4dUwYJ27BLaU9Ga18ezndbAHH7JZ/sFv8lwOwX2 wbHTC9//2IwaA== From: cel@kernel.org To: Neil Brown , Mike Snitzer Cc: , Chuck Lever Subject: [RFC PATCH 3/6] NFSD: Avoid using rqstp->rq_vers in nfsd_set_fh_dentry() Date: Tue, 27 Aug 2024 20:44:42 -0400 Message-ID: <20240828004445.22634-4-cel@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240828004445.22634-1-cel@kernel.org> References: <20240828004445.22634-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Chuck Lever Currently, fh_verify() makes some daring assumptions about which version of file handle the caller wants, based on the things it can find in the passed-in rqstp. The about-to-be-introduced LOCALIO use case sometimes has no svc_rqst context, so this logic won't work in that case. Instead, examine the passed-in file handle. It's .max_size field should carry information to allow nfsd_set_fh_dentry() to initialize the file handle appropriately. lockd appears to be the only kernel consumer that does not set the file handle .max_size when during initialization. write_filehandle() is the other question mark, as it looks possible to specify a maxsize between NFS_FHSIZE and NFS3_FHSIZE here. Signed-off-by: Chuck Lever --- fs/nfsd/lockd.c | 6 ++++-- fs/nfsd/nfsfh.c | 11 +++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index 46a7f9b813e5..e636d2a1e664 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c @@ -32,8 +32,10 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp, int access; struct svc_fh fh; - /* must initialize before using! but maxsize doesn't matter */ - fh_init(&fh,0); + if (rqstp->rq_vers == 4) + fh_init(&fh, NFS3_FHSIZE); + else + fh_init(&fh, NFS_FHSIZE); fh.fh_handle.fh_size = f->size; memcpy(&fh.fh_handle.fh_raw, f->data, f->size); fh.fh_export = NULL; diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 4b964a71a504..77acc26e8b02 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -267,25 +267,28 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) fhp->fh_dentry = dentry; fhp->fh_export = exp; - switch (rqstp->rq_vers) { - case 4: + switch (fhp->fh_maxsize) { + case NFS4_FHSIZE: if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOATOMIC_ATTR) fhp->fh_no_atomic_attr = true; fhp->fh_64bit_cookies = true; break; - case 3: + case NFS3_FHSIZE: if (dentry->d_sb->s_export_op->flags & EXPORT_OP_NOWCC) fhp->fh_no_wcc = true; fhp->fh_64bit_cookies = true; if (exp->ex_flags & NFSEXP_V4ROOT) goto out; break; - case 2: + case NFS_FHSIZE: fhp->fh_no_wcc = true; if (EX_WGATHER(exp)) fhp->fh_use_wgather = true; if (exp->ex_flags & NFSEXP_V4ROOT) goto out; + break; + case 0: + WARN_ONCE(1, "Uninitialized file handle"); } return 0; From patchwork Wed Aug 28 00:44:43 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13780266 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 051871CF93 for ; Wed, 28 Aug 2024 00:44:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805897; cv=none; b=coayWIcvvqqQYqLpf76MXlKLkIw6rJEDLfjAHxE96hkF1YFYNy9J+JuQ8/fNmqBtqY/A/VuAuR01/aHrE03EQFNxZ635L4k3HWLj13mGpM5pLLhDKT3FnOa4oDah1iu+qtZyMPcNiFohTJUBg8vEuJFrdbTVDp60lO7vwwrr2dY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805897; c=relaxed/simple; bh=VBy+JHbinWQ0xd2jq5yGIOcOnjx8lz7dIPmKPuWr71c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U9HDXvvgF9Egom3KSf6F/ackDE9cmu01JIPsmkgMj7uxoadxYAQLFNUUMOlOQGOj8R09+Qa/s/nl3OFaxmIlQGQIiQVm4YdWHa5bDp962BmSaBfPc0d83ps2lFXoxhHd9dMczEzgKDqBEcGOl57CZNfqaDiTKCXR0NWqp1TL4o4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MVkXkJyl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MVkXkJyl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 707EDC4DDED; Wed, 28 Aug 2024 00:44:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724805896; bh=VBy+JHbinWQ0xd2jq5yGIOcOnjx8lz7dIPmKPuWr71c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MVkXkJylBcqqit0oWzFODSnbxLpQnDGjfPVjtgsxehXQg/+gmsCHOslE55X6dqohw VPO/vXUQIzDbf7T7ur5/OSBa7b389SbCOx2FqUvmBXVUB1IfgROIDOrvGg1QFmvTau l+HR1wKtNkOj0qEeD35/OtkKUfMRQMd3E2mJa3xLmLjk1vM3jm2VMDYhmVrvdZXT8b asetJNIE/ns8IjIzoNbQitZsqgykxa+vzhSUdFt3msx2smvyER54pVlYWEGnF/sGxl 0wYcX+LYemYhDigpZhmGxhojDpzpPC24zLWyGJYUZN4iU7qRrtQ5pDaP+jlMQ2DNsz lDMm1/9TBTFRQ== From: cel@kernel.org To: Neil Brown , Mike Snitzer Cc: , Chuck Lever Subject: [RFC PATCH 4/6] NFSD: Short-circuit fh_verify tracepoints for LOCALIO Date: Tue, 27 Aug 2024 20:44:43 -0400 Message-ID: <20240828004445.22634-5-cel@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240828004445.22634-1-cel@kernel.org> References: <20240828004445.22634-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Chuck Lever LOCALIO will be able to call fh_verify() with a NULL rqstp. In this case, the existing trace points need to be skipped because they want to dereference the address fields in the passed-in rqstp. Temporarily make these trace points conditional to avoid a seg fault in this case. Putting the "rqstp != NULL" check in the trace points themselves makes the check more efficient. Signed-off-by: Chuck Lever --- fs/nfsd/trace.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 77bbd23aa150..d22027e23761 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h @@ -193,7 +193,7 @@ TRACE_EVENT(nfsd_compound_encode_err, { S_IFIFO, "FIFO" }, \ { S_IFSOCK, "SOCK" }) -TRACE_EVENT(nfsd_fh_verify, +TRACE_EVENT_CONDITION(nfsd_fh_verify, TP_PROTO( const struct svc_rqst *rqstp, const struct svc_fh *fhp, @@ -201,6 +201,7 @@ TRACE_EVENT(nfsd_fh_verify, int access ), TP_ARGS(rqstp, fhp, type, access), + TP_CONDITION(rqstp != NULL), TP_STRUCT__entry( __field(unsigned int, netns_ino) __sockaddr(server, rqstp->rq_xprt->xpt_remotelen) @@ -239,7 +240,7 @@ TRACE_EVENT_CONDITION(nfsd_fh_verify_err, __be32 error ), TP_ARGS(rqstp, fhp, type, access, error), - TP_CONDITION(error), + TP_CONDITION(rqstp != NULL && error), TP_STRUCT__entry( __field(unsigned int, netns_ino) __sockaddr(server, rqstp->rq_xprt->xpt_remotelen) @@ -295,12 +296,13 @@ DECLARE_EVENT_CLASS(nfsd_fh_err_class, __entry->status) ) -#define DEFINE_NFSD_FH_ERR_EVENT(name) \ -DEFINE_EVENT(nfsd_fh_err_class, nfsd_##name, \ - TP_PROTO(struct svc_rqst *rqstp, \ - struct svc_fh *fhp, \ - int status), \ - TP_ARGS(rqstp, fhp, status)) +#define DEFINE_NFSD_FH_ERR_EVENT(name) \ +DEFINE_EVENT_CONDITION(nfsd_fh_err_class, nfsd_##name, \ + TP_PROTO(struct svc_rqst *rqstp, \ + struct svc_fh *fhp, \ + int status), \ + TP_ARGS(rqstp, fhp, status), \ + TP_CONDITION(rqstp != NULL)) DEFINE_NFSD_FH_ERR_EVENT(set_fh_dentry_badexport); DEFINE_NFSD_FH_ERR_EVENT(set_fh_dentry_badhandle); From patchwork Wed Aug 28 00:44:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13780267 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5B62A20309 for ; Wed, 28 Aug 2024 00:44:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805898; cv=none; b=NmzJMKfSXA+bfHBUGrx/ZVgWftk9hkBW4XfAwA+iWMtdT6feDD7srPOWqNazi1Fa17YR9nYp0utiIy2YqwDNqjy+HS6byzIXMSh0w+Kqv0yKSBZQEEzTdg6jn01T3Kf7pfGVh61bY3xo9PKifmUADDw/GHqBq0/L19M9EgZ9ox0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805898; c=relaxed/simple; bh=QnKDORUSvLCatXW4RbakFrDklzp3Jn46+bnxhkkju20=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RKyuyHtW6P0laYgbztC5a0+KkbysRp7dQqUwBVSPb1QrdZ9en3bOhBGRMIWVOallqmMwY19JQXA6M4Dihrs3xeMmAnA+uNGf1P0ySUixK5rqzirPfZlgwL9fKmHh175SyTJAsJkf1yalia9m57vxaCvmVUx0RX0odaisVFmYm6M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QG1unXne; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QG1unXne" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D8D60C4DDF1; Wed, 28 Aug 2024 00:44:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724805898; bh=QnKDORUSvLCatXW4RbakFrDklzp3Jn46+bnxhkkju20=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QG1unXnesEaUHj79WV56LnN0sSMVyObFesfjxxpDpUV0Z2sD7gkMfrC3IZbjTpPr6 2Vv4xTC6bv7NJ/sQTMunaLBXFLFfWSQlq0hp59jvZPAdIkzbe1R+QR9j9ko4c2kBwb fYhWPO0RTwzCB9KE0DZT0Oq/0Vf4fsFPPdL0xbwMb42kav1rtBH6xFcEKwogFIw92c S6t+6ujorZHNH7YgKglMI+wYtNzNq22ebV1FBLYHXvpiq1KnX0lorryudSm8oqn1UQ Cgp7sjnDQWyH50NX8EPi5aaGYxSuPtLX1tchmK1jfQcZGwAkRp+UXx7LNATsHfoHHp +vowxZGP4Jf2Q== From: cel@kernel.org To: Neil Brown , Mike Snitzer Cc: Subject: [RFC PATCH 5/6] nfsd: factor out __fh_verify to allow NULL rqstp to be passed Date: Tue, 27 Aug 2024 20:44:44 -0400 Message-ID: <20240828004445.22634-6-cel@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240828004445.22634-1-cel@kernel.org> References: <20240828004445.22634-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown __fh_verify() offers an interface like fh_verify() but doesn't require a struct svc_rqst *, instead it also takes the specific parts as explicit required arguments. So it is safe to call __fh_verify() with a NULL rqstp, but the net, cred, and client args must not be NULL. __fh_verify() does not use SVC_NET(), nor does the functions it calls. Rather then depending on rqstp->rq_vers to determine nfs version, pass it in explicitly. This removes another dependency on rqstp and ensures the correct version is checked. The rqstp can be for an NLM request and while some code tests that, other code does not. Rather than using rqstp->rq_client pass the client and gssclient explicitly to __fh_verify and then to nfsd_set_fh_dentry(). Lastly, 4 associated tracepoints are only used if rqstp is not NULL (this is a stop-gap that should be properly fixed so localio also benefits from the utility these tracepoints provide when debugging fh_verify issues). Signed-off-by: NeilBrown Co-developed-by: Mike Snitzer Signed-off-by: Mike Snitzer Signed-off-by: Chuck Lever --- fs/nfsd/nfsfh.c | 168 ++++++++++++++++++++++++++---------------------- 1 file changed, 92 insertions(+), 76 deletions(-) diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 77acc26e8b02..80c06e170e9a 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -142,7 +142,11 @@ static inline __be32 check_pseudo_root(struct dentry *dentry, * dentry. On success, the results are used to set fh_export and * fh_dentry. */ -static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) +static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net, + struct svc_cred *cred, + struct auth_domain *client, + struct auth_domain *gssclient, + struct svc_fh *fhp) { struct knfsd_fh *fh = &fhp->fh_handle; struct fid *fid = NULL; @@ -184,8 +188,8 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) data_left -= len; if (data_left < 0) return error; - exp = rqst_exp_find(&rqstp->rq_chandle, SVC_NET(rqstp), - rqstp->rq_client, rqstp->rq_gssclient, + exp = rqst_exp_find(rqstp ? &rqstp->rq_chandle : NULL, + net, client, gssclient, fh->fh_fsid_type, fh->fh_fsid); fid = (struct fid *)(fh->fh_fsid + len); @@ -220,7 +224,7 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) put_cred(override_creds(new)); put_cred(new); } else { - error = nfsd_setuser_and_check_port(rqstp, &rqstp->rq_cred, exp); + error = nfsd_setuser_and_check_port(rqstp, cred, exp); if (error) goto out; } @@ -297,6 +301,87 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) return error; } +static __be32 +__fh_verify(struct svc_rqst *rqstp, + struct net *net, struct svc_cred *cred, + struct auth_domain *client, + struct auth_domain *gssclient, + struct svc_fh *fhp, umode_t type, int access) +{ + struct nfsd_net *nn = net_generic(net, nfsd_net_id); + struct svc_export *exp = NULL; + struct dentry *dentry; + __be32 error; + + if (!fhp->fh_dentry) { + error = nfsd_set_fh_dentry(rqstp, net, cred, client, + gssclient, fhp); + if (error) + goto out; + } + dentry = fhp->fh_dentry; + exp = fhp->fh_export; + + trace_nfsd_fh_verify(rqstp, fhp, type, access); + + /* + * We still have to do all these permission checks, even when + * fh_dentry is already set: + * - fh_verify may be called multiple times with different + * "access" arguments (e.g. nfsd_proc_create calls + * fh_verify(...,NFSD_MAY_EXEC) first, then later (in + * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE). + * - in the NFSv4 case, the filehandle may have been filled + * in by fh_compose, and given a dentry, but further + * compound operations performed with that filehandle + * still need permissions checks. In the worst case, a + * mountpoint crossing may have changed the export + * options, and we may now need to use a different uid + * (for example, if different id-squashing options are in + * effect on the new filesystem). + */ + error = check_pseudo_root(dentry, exp); + if (error) + goto out; + + error = nfsd_setuser_and_check_port(rqstp, cred, exp); + if (error) + goto out; + + error = nfsd_mode_check(dentry, type); + if (error) + goto out; + + /* + * pseudoflavor restrictions are not enforced on NLM, + * which clients virtually always use auth_sys for, + * even while using RPCSEC_GSS for NFS. + */ + if (access & NFSD_MAY_LOCK || access & NFSD_MAY_BYPASS_GSS) + goto skip_pseudoflavor_check; + /* + * Clients may expect to be able to use auth_sys during mount, + * even if they use gss for everything else; see section 2.3.2 + * of rfc 2623. + */ + if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT + && exp->ex_path.dentry == dentry) + goto skip_pseudoflavor_check; + + error = check_nfsd_access(exp, rqstp); + if (error) + goto out; + +skip_pseudoflavor_check: + /* Finally, check access permissions. */ + error = nfsd_permission(cred, exp, dentry, access); +out: + trace_nfsd_fh_verify_err(rqstp, fhp, type, access, error); + if (error == nfserr_stale) + nfsd_stats_fh_stale_inc(nn, exp); + return error; +} + /** * fh_verify - filehandle lookup and access checking * @rqstp: pointer to current rpc request @@ -327,80 +412,11 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) __be32 fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) { - struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); - struct svc_export *exp = NULL; - struct dentry *dentry; - __be32 error; - - if (!fhp->fh_dentry) { - error = nfsd_set_fh_dentry(rqstp, fhp); - if (error) - goto out; - } - dentry = fhp->fh_dentry; - exp = fhp->fh_export; - - trace_nfsd_fh_verify(rqstp, fhp, type, access); - - /* - * We still have to do all these permission checks, even when - * fh_dentry is already set: - * - fh_verify may be called multiple times with different - * "access" arguments (e.g. nfsd_proc_create calls - * fh_verify(...,NFSD_MAY_EXEC) first, then later (in - * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE). - * - in the NFSv4 case, the filehandle may have been filled - * in by fh_compose, and given a dentry, but further - * compound operations performed with that filehandle - * still need permissions checks. In the worst case, a - * mountpoint crossing may have changed the export - * options, and we may now need to use a different uid - * (for example, if different id-squashing options are in - * effect on the new filesystem). - */ - error = check_pseudo_root(dentry, exp); - if (error) - goto out; - - error = nfsd_setuser_and_check_port(rqstp, &rqstp->rq_cred, exp); - if (error) - goto out; - - error = nfsd_mode_check(dentry, type); - if (error) - goto out; - - /* - * pseudoflavor restrictions are not enforced on NLM, - * which clients virtually always use auth_sys for, - * even while using RPCSEC_GSS for NFS. - */ - if (access & NFSD_MAY_LOCK || access & NFSD_MAY_BYPASS_GSS) - goto skip_pseudoflavor_check; - /* - * Clients may expect to be able to use auth_sys during mount, - * even if they use gss for everything else; see section 2.3.2 - * of rfc 2623. - */ - if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT - && exp->ex_path.dentry == dentry) - goto skip_pseudoflavor_check; - - error = check_nfsd_access(exp, rqstp); - if (error) - goto out; - -skip_pseudoflavor_check: - /* Finally, check access permissions. */ - error = nfsd_permission(&rqstp->rq_cred, exp, dentry, access); -out: - trace_nfsd_fh_verify_err(rqstp, fhp, type, access, error); - if (error == nfserr_stale) - nfsd_stats_fh_stale_inc(nn, exp); - return error; + return __fh_verify(rqstp, SVC_NET(rqstp), &rqstp->rq_cred, + rqstp->rq_client, rqstp->rq_gssclient, + fhp, type, access); } - /* * Compose a file handle for an NFS reply. * From patchwork Wed Aug 28 00:44:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13780268 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3B03A2209F for ; Wed, 28 Aug 2024 00:44:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805900; cv=none; b=eRQHamkA2tXjYaJsJpwfLyWf/xKQEdvrMcTnsUGj+HHdnzwyLOd56qZ6op2vdj2BeIO19MQuarnOfgfrcESzEPVWYtmKzkKN8DScctQQOExTfEBppfe+vO125b9HEFSPvhRYAdQFriiaDY9+23kq1hBwYSsV+AvP0mIZUpllB8g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1724805900; c=relaxed/simple; bh=85ElrjjR5Logdy2BRXlJvXTOLHEHEN457LOkNoEcOyE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p8IWJ/0Ydt8mpLaGKq4ejdCAA8cSzJp2ojv+DFsrJhlJf6SZpD3BHqphEF0wVH6V55r9w+MdQX/4hHEg6QLeqvaAUfZ+9r9WH6BCJAHoRotp2DTSrpbBRSZuT5h+VVWoYATklxUm66McQklbntHEz3CSmbi0gvD+zSuIGODZjmg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=cdUXPf0g; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="cdUXPf0g" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4A520C4DDED; Wed, 28 Aug 2024 00:44:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1724805899; bh=85ElrjjR5Logdy2BRXlJvXTOLHEHEN457LOkNoEcOyE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cdUXPf0gUI4UEBhjdUq2ZHOglH72pBAFxUFMT7wS/1W7TqNVU4i+WdHGeYetisxHk h1jZodeaCl1b+RkA2aYu7AcKB9t701Fa+/kKEB55raYmAnDxdwCJ/IOPHBMZCk8R2Y m/B+DrpsIa0GfiQcRYRiaq8Mw3Hw8i9snjD5ul1t7485DQ2JL1X1EdzFOlOsEnD/ic WHprwsLL++6458FTmU1bA7AJHgNGJnNffJf98YeLl+0CI1vhibHxbBeei6jhymjeg+ 64comczG0o6DFFG9Bmz/MsoozNN+1FKmD5aDuzYVJXuDnCz9cJ91SxjsHX1K+i0kyr 89rvDM7cdAzmA== From: cel@kernel.org To: Neil Brown , Mike Snitzer Cc: , Jeff Layton Subject: [RFC PATCH 6/6] nfsd: add nfsd_file_acquire_local() Date: Tue, 27 Aug 2024 20:44:45 -0400 Message-ID: <20240828004445.22634-7-cel@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240828004445.22634-1-cel@kernel.org> References: <20240828004445.22634-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-nfs@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: NeilBrown nfsd_file_acquire_local() can be used to look up a file by filehandle without having a struct svc_rqst. This can be used by NFS LOCALIO to allow the NFS client to bypass the NFS protocol to directly access a file provided by the NFS server which is running in the same kernel. In nfsd_file_do_acquire() care is taken to always use fh_verify() if rqstp is not NULL (as is the case for non-LOCALIO callers). Otherwise the non-LOCALIO callers will not supply the correct and required arguments to __fh_verify (e.g. gssclient isn't passed). Also, use GC for nfsd_file returned by nfsd_file_acquire_local. GC offers performance improvements if/when a file is reopened before launderette cleans it from the filecache's LRU. Suggested-by: Jeff Layton # use filecache's GC Signed-off-by: NeilBrown Co-developed-by: Mike Snitzer Signed-off-by: Mike Snitzer Signed-off-by: Chuck Lever --- fs/nfsd/filecache.c | 61 +++++++++++++++++++++++++++++++++++++++------ fs/nfsd/filecache.h | 3 +++ fs/nfsd/nfsfh.c | 18 ++++++++++++- fs/nfsd/nfsfh.h | 5 ++++ 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 9e9d246f993c..40f19e9af0ba 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -982,12 +982,14 @@ nfsd_file_is_cached(struct inode *inode) } static __be32 -nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, +nfsd_file_do_acquire(struct svc_rqst *rqstp, struct net *net, + struct svc_cred *cred, + struct auth_domain *client, + struct svc_fh *fhp, unsigned int may_flags, struct file *file, struct nfsd_file **pnf, bool want_gc) { unsigned char need = may_flags & NFSD_FILE_MAY_MASK; - struct net *net = SVC_NET(rqstp); struct nfsd_file *new, *nf; bool stale_retry = true; bool open_retry = true; @@ -996,8 +998,13 @@ nfsd_file_do_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, int ret; retry: - status = fh_verify(rqstp, fhp, S_IFREG, - may_flags|NFSD_MAY_OWNER_OVERRIDE); + if (rqstp) { + status = fh_verify(rqstp, fhp, S_IFREG, + may_flags|NFSD_MAY_OWNER_OVERRIDE); + } else { + status = __fh_verify(NULL, net, cred, client, NULL, fhp, + S_IFREG, may_flags|NFSD_MAY_OWNER_OVERRIDE); + } if (status != nfs_ok) return status; inode = d_inode(fhp->fh_dentry); @@ -1143,7 +1150,8 @@ __be32 nfsd_file_acquire_gc(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned int may_flags, struct nfsd_file **pnf) { - return nfsd_file_do_acquire(rqstp, fhp, may_flags, NULL, pnf, true); + return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, + fhp, may_flags, NULL, pnf, true); } /** @@ -1167,7 +1175,45 @@ __be32 nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned int may_flags, struct nfsd_file **pnf) { - return nfsd_file_do_acquire(rqstp, fhp, may_flags, NULL, pnf, false); + return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, + fhp, may_flags, NULL, pnf, false); +} + +/** + * nfsd_file_acquire_local - Get a struct nfsd_file with an open file for localio + * @net: The network namespace in which to perform a lookup + * @cred: the user credential with which to validate access + * @client: the auth_domain for LOCALIO lookup + * @fhp: the NFS filehandle of the file to be opened + * @may_flags: NFSD_MAY_ settings for the file + * @pnf: OUT: new or found "struct nfsd_file" object + * + * This file lookup interface provide access to a file given the + * filehandle and credential. No connection-based authorisation + * is performed and in that way it is quite different to other + * file access mediated by nfsd. It allows a kernel module such as the NFS + * client to reach across network and filesystem namespaces to access + * a file. The security implications of this should be carefully + * considered before use. + * + * The nfsd_file object returned by this API is reference-counted + * and garbage-collected. The object is retained for a few + * seconds after the final nfsd_file_put() in case the caller + * wants to re-use it. + * + * Return values: + * %nfs_ok - @pnf points to an nfsd_file with its reference + * count boosted. + * + * On error, an nfsstat value in network byte order is returned. + */ +__be32 +nfsd_file_acquire_local(struct net *net, struct svc_cred *cred, + struct auth_domain *client, struct svc_fh *fhp, + unsigned int may_flags, struct nfsd_file **pnf) +{ + return nfsd_file_do_acquire(NULL, net, cred, client, + fhp, may_flags, NULL, pnf, true); } /** @@ -1193,7 +1239,8 @@ nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned int may_flags, struct file *file, struct nfsd_file **pnf) { - return nfsd_file_do_acquire(rqstp, fhp, may_flags, file, pnf, false); + return nfsd_file_do_acquire(rqstp, SVC_NET(rqstp), NULL, NULL, + fhp, may_flags, file, pnf, false); } /* diff --git a/fs/nfsd/filecache.h b/fs/nfsd/filecache.h index 3fbec24eea6c..26ada78b8c1e 100644 --- a/fs/nfsd/filecache.h +++ b/fs/nfsd/filecache.h @@ -66,5 +66,8 @@ __be32 nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp, __be32 nfsd_file_acquire_opened(struct svc_rqst *rqstp, struct svc_fh *fhp, unsigned int may_flags, struct file *file, struct nfsd_file **nfp); +__be32 nfsd_file_acquire_local(struct net *net, struct svc_cred *cred, + struct auth_domain *client, struct svc_fh *fhp, + unsigned int may_flags, struct nfsd_file **pnf); int nfsd_file_cache_stats_show(struct seq_file *m, void *v); #endif /* _FS_NFSD_FILECACHE_H */ diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 80c06e170e9a..41be0f15182d 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -301,7 +301,23 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net, return error; } -static __be32 +/** + * __fh_verify - filehandle lookup and access checking + * @rqstp: RPC transaction context, or NULL + * @net: net namespace in which to perform the export lookup + * @cred: RPC user credential + * @client: RPC auth domain + * @gssclient: RPC GSS auth domain + * @fhp: filehandle to be verified + * @type: expected type of object pointed to by filehandle + * @access: type of access needed to object + * + * This internal API can be used by callers who do not have an RPC + * transaction context (ie are not running in an nfsd thread). + * + * See fh_verify() for further descriptions of @fhp, @type, and @access. + */ +__be32 __fh_verify(struct svc_rqst *rqstp, struct net *net, struct svc_cred *cred, struct auth_domain *client, diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index 8d46e203d139..8dd653ba4100 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h @@ -217,6 +217,11 @@ extern char * SVCFH_fmt(struct svc_fh *fhp); * Function prototypes */ __be32 fh_verify(struct svc_rqst *, struct svc_fh *, umode_t, int); +__be32 __fh_verify(struct svc_rqst *rqstp, + struct net *net, struct svc_cred *cred, + struct auth_domain *client, + struct auth_domain *gssclient, + struct svc_fh *fhp, umode_t type, int access); __be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *); __be32 fh_update(struct svc_fh *); void fh_put(struct svc_fh *);