From: Eric Biggers <ebiggers@kernel.org>
To: linux-nfs@vger.kernel.org, Chuck Lever <chuck.lever@oracle.com>,
Jeff Layton <jlayton@kernel.org>
Cc: NeilBrown <neil@brown.name>,
Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <Dai.Ngo@oracle.com>, Tom Talpey <tom@talpey.com>,
linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org,
Eric Biggers <ebiggers@kernel.org>
Subject: [PATCH v2] nfsd: Use MD5 library instead of crypto_shash
Date: Thu, 16 Oct 2025 11:15:34 -0700 [thread overview]
Message-ID: <20251016181534.17252-1-ebiggers@kernel.org> (raw)
Update NFSD's support for "legacy client tracking" (which uses MD5) to
use the MD5 library instead of crypto_shash. This has several benefits:
- Simpler code. Notably, much of the error-handling code is no longer
needed, since the library functions can't fail.
- Improved performance due to reduced overhead. A microbenchmark of
nfs4_make_rec_clidname() shows a speedup from 1455 cycles to 425.
- The MD5 code can now safely be built as a loadable module when nfsd is
built as a loadable module. (Previously, nfsd forced the MD5 code to
built-in, presumably to work around the unreliability of the
name-based loading.) Thus select MD5 from the tristate option NFSD if
NFSD_LEGACY_CLIENT_TRACKING, instead of from the bool option NFSD_V4.
- Fixes a bug where legacy client tracking was not supported on kernels
booted with "fips=1", due to crypto_shash not allowing MD5 to be used.
This particular use of MD5 is not for a cryptographic purpose, though,
so it is acceptable even when fips=1 (see
https://lore.kernel.org/r/dae495a93cbcc482f4ca23c3a0d9360a1fd8c3a8.camel@redhat.com/).
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
---
Changed in v2:
- Removed the fips_enabled check.
- Added 'select CRYPTO' back to NFSD_V4.
fs/nfsd/Kconfig | 4 +--
fs/nfsd/nfs4recover.c | 76 +++++--------------------------------------
2 files changed, 11 insertions(+), 69 deletions(-)
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index e134dce45e350..94ab9e5bf930e 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -3,10 +3,11 @@ config NFSD
tristate "NFS server support"
depends on INET
depends on FILE_LOCKING
depends on FSNOTIFY
select CRC32
+ select CRYPTO_LIB_MD5 if NFSD_LEGACY_CLIENT_TRACKING
select CRYPTO_LIB_SHA256 if NFSD_V4
select LOCKD
select SUNRPC
select EXPORTFS
select NFS_COMMON
@@ -75,12 +76,11 @@ config NFSD_V3_ACL
config NFSD_V4
bool "NFS server support for NFS version 4"
depends on NFSD && PROC_FS
select FS_POSIX_ACL
select RPCSEC_GSS_KRB5
- select CRYPTO
- select CRYPTO_MD5
+ select CRYPTO # required by RPCSEC_GSS_KRB5
select GRACE_PERIOD
select NFS_V4_2_SSC_HELPER if NFS_V4_2
help
This option enables support in your system's NFS server for
version 4 of the NFS protocol (RFC 3530).
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index e2b9472e5c78c..35d645dd6f863 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -30,11 +30,11 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-#include <crypto/hash.h>
+#include <crypto/md5.h>
#include <crypto/sha2.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/namei.h>
#include <linux/sched.h>
@@ -90,61 +90,22 @@ static void
nfs4_reset_creds(const struct cred *original)
{
put_cred(revert_creds(original));
}
-static int
+static void
nfs4_make_rec_clidname(char dname[HEXDIR_LEN], const struct xdr_netobj *clname)
{
u8 digest[MD5_DIGEST_SIZE];
- struct crypto_shash *tfm;
- int status;
dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
clname->len, clname->data);
- tfm = crypto_alloc_shash("md5", 0, 0);
- if (IS_ERR(tfm)) {
- status = PTR_ERR(tfm);
- goto out_no_tfm;
- }
- status = crypto_shash_tfm_digest(tfm, clname->data, clname->len,
- digest);
- if (status)
- goto out;
+ md5(clname->data, clname->len, digest);
static_assert(HEXDIR_LEN == 2 * MD5_DIGEST_SIZE + 1);
sprintf(dname, "%*phN", MD5_DIGEST_SIZE, digest);
-
- status = 0;
-out:
- crypto_free_shash(tfm);
-out_no_tfm:
- return status;
-}
-
-/*
- * If we had an error generating the recdir name for the legacy tracker
- * then warn the admin. If the error doesn't appear to be transient,
- * then disable recovery tracking.
- */
-static void
-legacy_recdir_name_error(struct nfs4_client *clp, int error)
-{
- printk(KERN_ERR "NFSD: unable to generate recoverydir "
- "name (%d).\n", error);
-
- /*
- * if the algorithm just doesn't exist, then disable the recovery
- * tracker altogether. The crypto libs will generally return this if
- * FIPS is enabled as well.
- */
- if (error == -ENOENT) {
- printk(KERN_ERR "NFSD: disabling legacy clientid tracking. "
- "Reboot recovery will not function correctly!\n");
- nfsd4_client_tracking_exit(clp->net);
- }
}
static void
__nfsd4_create_reclaim_record_grace(struct nfs4_client *clp,
const char *dname, int len, struct nfsd_net *nn)
@@ -180,13 +141,11 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
if (test_and_set_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
return;
if (!nn->rec_file)
return;
- status = nfs4_make_rec_clidname(dname, &clp->cl_name);
- if (status)
- return legacy_recdir_name_error(clp, status);
+ nfs4_make_rec_clidname(dname, &clp->cl_name);
status = nfs4_save_creds(&original_cred);
if (status < 0)
return;
@@ -374,13 +333,11 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
if (!nn->rec_file || !test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
return;
- status = nfs4_make_rec_clidname(dname, &clp->cl_name);
- if (status)
- return legacy_recdir_name_error(clp, status);
+ nfs4_make_rec_clidname(dname, &clp->cl_name);
status = mnt_want_write_file(nn->rec_file);
if (status)
goto out;
clear_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags);
@@ -657,25 +614,20 @@ nfs4_recoverydir(void)
}
static int
nfsd4_check_legacy_client(struct nfs4_client *clp)
{
- int status;
char dname[HEXDIR_LEN];
struct nfs4_client_reclaim *crp;
struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
struct xdr_netobj name;
/* did we already find that this client is stable? */
if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
return 0;
- status = nfs4_make_rec_clidname(dname, &clp->cl_name);
- if (status) {
- legacy_recdir_name_error(clp, status);
- return status;
- }
+ nfs4_make_rec_clidname(dname, &clp->cl_name);
/* look for it in the reclaim hashtable otherwise */
name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
if (!name.data) {
dprintk("%s: failed to allocate memory for name.data!\n",
@@ -1264,17 +1216,14 @@ nfsd4_cld_check(struct nfs4_client *clp)
if (crp)
goto found;
#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
if (nn->cld_net->cn_has_legacy) {
- int status;
char dname[HEXDIR_LEN];
struct xdr_netobj name;
- status = nfs4_make_rec_clidname(dname, &clp->cl_name);
- if (status)
- return -ENOENT;
+ nfs4_make_rec_clidname(dname, &clp->cl_name);
name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
if (!name.data) {
dprintk("%s: failed to allocate memory for name.data!\n",
__func__);
@@ -1315,15 +1264,12 @@ nfsd4_cld_check_v2(struct nfs4_client *clp)
#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
if (cn->cn_has_legacy) {
struct xdr_netobj name;
char dname[HEXDIR_LEN];
- int status;
- status = nfs4_make_rec_clidname(dname, &clp->cl_name);
- if (status)
- return -ENOENT;
+ nfs4_make_rec_clidname(dname, &clp->cl_name);
name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
if (!name.data) {
dprintk("%s: failed to allocate memory for name.data\n",
__func__);
@@ -1692,15 +1638,11 @@ nfsd4_cltrack_legacy_recdir(const struct xdr_netobj *name)
/* just return nothing if output will be truncated */
kfree(result);
return NULL;
}
- copied = nfs4_make_rec_clidname(result + copied, name);
- if (copied) {
- kfree(result);
- return NULL;
- }
+ nfs4_make_rec_clidname(result + copied, name);
return result;
}
static char *
base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
--
2.51.0
next reply other threads:[~2025-10-16 18:18 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-16 18:15 Eric Biggers [this message]
2025-10-16 18:20 ` [PATCH v2] nfsd: Use MD5 library instead of crypto_shash Eric Biggers
2025-10-16 18:31 ` Chuck Lever
2025-10-16 18:53 ` Eric Biggers
2025-10-16 19:00 ` Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251016181534.17252-1-ebiggers@kernel.org \
--to=ebiggers@kernel.org \
--cc=Dai.Ngo@oracle.com \
--cc=chuck.lever@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=neil@brown.name \
--cc=okorniev@redhat.com \
--cc=tom@talpey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.