Skip to content

Commit 78cd170

Browse files
Eric Biggerschucklever
authored andcommitted
nfsd: Use MD5 library instead of crypto_shash
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> Acked-by: Ard Biesheuvel <ardb@kernel.org> Acked-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Scott Mayhew <smayhew@redhat.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent fceb873 commit 78cd170

2 files changed

Lines changed: 11 additions & 69 deletions

File tree

fs/nfsd/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ config NFSD
55
depends on FILE_LOCKING
66
depends on FSNOTIFY
77
select CRC32
8+
select CRYPTO_LIB_MD5 if NFSD_LEGACY_CLIENT_TRACKING
89
select CRYPTO_LIB_SHA256 if NFSD_V4
910
select LOCKD
1011
select SUNRPC
@@ -77,8 +78,7 @@ config NFSD_V4
7778
depends on NFSD && PROC_FS
7879
select FS_POSIX_ACL
7980
select RPCSEC_GSS_KRB5
80-
select CRYPTO
81-
select CRYPTO_MD5
81+
select CRYPTO # required by RPCSEC_GSS_KRB5
8282
select GRACE_PERIOD
8383
select NFS_V4_2_SSC_HELPER if NFS_V4_2
8484
help

fs/nfsd/nfs4recover.c

Lines changed: 9 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
*
3333
*/
3434

35-
#include <crypto/hash.h>
35+
#include <crypto/md5.h>
3636
#include <crypto/sha2.h>
3737
#include <linux/file.h>
3838
#include <linux/slab.h>
@@ -92,57 +92,18 @@ nfs4_reset_creds(const struct cred *original)
9292
put_cred(revert_creds(original));
9393
}
9494

95-
static int
95+
static void
9696
nfs4_make_rec_clidname(char dname[HEXDIR_LEN], const struct xdr_netobj *clname)
9797
{
9898
u8 digest[MD5_DIGEST_SIZE];
99-
struct crypto_shash *tfm;
100-
int status;
10199

102100
dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
103101
clname->len, clname->data);
104-
tfm = crypto_alloc_shash("md5", 0, 0);
105-
if (IS_ERR(tfm)) {
106-
status = PTR_ERR(tfm);
107-
goto out_no_tfm;
108-
}
109102

110-
status = crypto_shash_tfm_digest(tfm, clname->data, clname->len,
111-
digest);
112-
if (status)
113-
goto out;
103+
md5(clname->data, clname->len, digest);
114104

115105
static_assert(HEXDIR_LEN == 2 * MD5_DIGEST_SIZE + 1);
116106
sprintf(dname, "%*phN", MD5_DIGEST_SIZE, digest);
117-
118-
status = 0;
119-
out:
120-
crypto_free_shash(tfm);
121-
out_no_tfm:
122-
return status;
123-
}
124-
125-
/*
126-
* If we had an error generating the recdir name for the legacy tracker
127-
* then warn the admin. If the error doesn't appear to be transient,
128-
* then disable recovery tracking.
129-
*/
130-
static void
131-
legacy_recdir_name_error(struct nfs4_client *clp, int error)
132-
{
133-
printk(KERN_ERR "NFSD: unable to generate recoverydir "
134-
"name (%d).\n", error);
135-
136-
/*
137-
* if the algorithm just doesn't exist, then disable the recovery
138-
* tracker altogether. The crypto libs will generally return this if
139-
* FIPS is enabled as well.
140-
*/
141-
if (error == -ENOENT) {
142-
printk(KERN_ERR "NFSD: disabling legacy clientid tracking. "
143-
"Reboot recovery will not function correctly!\n");
144-
nfsd4_client_tracking_exit(clp->net);
145-
}
146107
}
147108

148109
static void
@@ -171,9 +132,7 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
171132
if (!nn->rec_file)
172133
return;
173134

174-
status = nfs4_make_rec_clidname(dname, &clp->cl_name);
175-
if (status)
176-
return legacy_recdir_name_error(clp, status);
135+
nfs4_make_rec_clidname(dname, &clp->cl_name);
177136

178137
status = nfs4_save_creds(&original_cred);
179138
if (status < 0)
@@ -354,9 +313,7 @@ nfsd4_remove_clid_dir(struct nfs4_client *clp)
354313
if (!nn->rec_file || !test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
355314
return;
356315

357-
status = nfs4_make_rec_clidname(dname, &clp->cl_name);
358-
if (status)
359-
return legacy_recdir_name_error(clp, status);
316+
nfs4_make_rec_clidname(dname, &clp->cl_name);
360317

361318
status = mnt_want_write_file(nn->rec_file);
362319
if (status)
@@ -636,7 +593,6 @@ nfs4_recoverydir(void)
636593
static int
637594
nfsd4_check_legacy_client(struct nfs4_client *clp)
638595
{
639-
int status;
640596
char dname[HEXDIR_LEN];
641597
struct nfs4_client_reclaim *crp;
642598
struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id);
@@ -646,11 +602,7 @@ nfsd4_check_legacy_client(struct nfs4_client *clp)
646602
if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags))
647603
return 0;
648604

649-
status = nfs4_make_rec_clidname(dname, &clp->cl_name);
650-
if (status) {
651-
legacy_recdir_name_error(clp, status);
652-
return status;
653-
}
605+
nfs4_make_rec_clidname(dname, &clp->cl_name);
654606

655607
/* look for it in the reclaim hashtable otherwise */
656608
name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
@@ -1243,13 +1195,10 @@ nfsd4_cld_check(struct nfs4_client *clp)
12431195

12441196
#ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING
12451197
if (nn->cld_net->cn_has_legacy) {
1246-
int status;
12471198
char dname[HEXDIR_LEN];
12481199
struct xdr_netobj name;
12491200

1250-
status = nfs4_make_rec_clidname(dname, &clp->cl_name);
1251-
if (status)
1252-
return -ENOENT;
1201+
nfs4_make_rec_clidname(dname, &clp->cl_name);
12531202

12541203
name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
12551204
if (!name.data) {
@@ -1294,11 +1243,8 @@ nfsd4_cld_check_v2(struct nfs4_client *clp)
12941243
if (cn->cn_has_legacy) {
12951244
struct xdr_netobj name;
12961245
char dname[HEXDIR_LEN];
1297-
int status;
12981246

1299-
status = nfs4_make_rec_clidname(dname, &clp->cl_name);
1300-
if (status)
1301-
return -ENOENT;
1247+
nfs4_make_rec_clidname(dname, &clp->cl_name);
13021248

13031249
name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL);
13041250
if (!name.data) {
@@ -1671,11 +1617,7 @@ nfsd4_cltrack_legacy_recdir(const struct xdr_netobj *name)
16711617
return NULL;
16721618
}
16731619

1674-
copied = nfs4_make_rec_clidname(result + copied, name);
1675-
if (copied) {
1676-
kfree(result);
1677-
return NULL;
1678-
}
1620+
nfs4_make_rec_clidname(result + copied, name);
16791621

16801622
return result;
16811623
}

0 commit comments

Comments
 (0)