Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Eric Biggers and committed by
Chuck Lever
78cd170d fceb8734

+11 -69
+2 -2
fs/nfsd/Kconfig
··· 5 5 depends on FILE_LOCKING 6 6 depends on FSNOTIFY 7 7 select CRC32 8 + select CRYPTO_LIB_MD5 if NFSD_LEGACY_CLIENT_TRACKING 8 9 select CRYPTO_LIB_SHA256 if NFSD_V4 9 10 select LOCKD 10 11 select SUNRPC ··· 78 77 depends on NFSD && PROC_FS 79 78 select FS_POSIX_ACL 80 79 select RPCSEC_GSS_KRB5 81 - select CRYPTO 82 - select CRYPTO_MD5 80 + select CRYPTO # required by RPCSEC_GSS_KRB5 83 81 select GRACE_PERIOD 84 82 select NFS_V4_2_SSC_HELPER if NFS_V4_2 85 83 help
+9 -67
fs/nfsd/nfs4recover.c
··· 32 32 * 33 33 */ 34 34 35 - #include <crypto/hash.h> 35 + #include <crypto/md5.h> 36 36 #include <crypto/sha2.h> 37 37 #include <linux/file.h> 38 38 #include <linux/slab.h> ··· 92 92 put_cred(revert_creds(original)); 93 93 } 94 94 95 - static int 95 + static void 96 96 nfs4_make_rec_clidname(char dname[HEXDIR_LEN], const struct xdr_netobj *clname) 97 97 { 98 98 u8 digest[MD5_DIGEST_SIZE]; 99 - struct crypto_shash *tfm; 100 - int status; 101 99 102 100 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", 103 101 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 - } 109 102 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); 114 104 115 105 static_assert(HEXDIR_LEN == 2 * MD5_DIGEST_SIZE + 1); 116 106 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 - } 146 107 } 147 108 148 109 static void ··· 132 171 if (!nn->rec_file) 133 172 return; 134 173 135 - status = nfs4_make_rec_clidname(dname, &clp->cl_name); 136 - if (status) 137 - return legacy_recdir_name_error(clp, status); 174 + nfs4_make_rec_clidname(dname, &clp->cl_name); 138 175 139 176 status = nfs4_save_creds(&original_cred); 140 177 if (status < 0) ··· 313 354 if (!nn->rec_file || !test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags)) 314 355 return; 315 356 316 - status = nfs4_make_rec_clidname(dname, &clp->cl_name); 317 - if (status) 318 - return legacy_recdir_name_error(clp, status); 357 + nfs4_make_rec_clidname(dname, &clp->cl_name); 319 358 320 359 status = mnt_want_write_file(nn->rec_file); 321 360 if (status) ··· 593 636 static int 594 637 nfsd4_check_legacy_client(struct nfs4_client *clp) 595 638 { 596 - int status; 597 639 char dname[HEXDIR_LEN]; 598 640 struct nfs4_client_reclaim *crp; 599 641 struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); ··· 602 646 if (test_bit(NFSD4_CLIENT_STABLE, &clp->cl_flags)) 603 647 return 0; 604 648 605 - status = nfs4_make_rec_clidname(dname, &clp->cl_name); 606 - if (status) { 607 - legacy_recdir_name_error(clp, status); 608 - return status; 609 - } 649 + nfs4_make_rec_clidname(dname, &clp->cl_name); 610 650 611 651 /* look for it in the reclaim hashtable otherwise */ 612 652 name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL); ··· 1195 1243 1196 1244 #ifdef CONFIG_NFSD_LEGACY_CLIENT_TRACKING 1197 1245 if (nn->cld_net->cn_has_legacy) { 1198 - int status; 1199 1246 char dname[HEXDIR_LEN]; 1200 1247 struct xdr_netobj name; 1201 1248 1202 - status = nfs4_make_rec_clidname(dname, &clp->cl_name); 1203 - if (status) 1204 - return -ENOENT; 1249 + nfs4_make_rec_clidname(dname, &clp->cl_name); 1205 1250 1206 1251 name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL); 1207 1252 if (!name.data) { ··· 1243 1294 if (cn->cn_has_legacy) { 1244 1295 struct xdr_netobj name; 1245 1296 char dname[HEXDIR_LEN]; 1246 - int status; 1247 1297 1248 - status = nfs4_make_rec_clidname(dname, &clp->cl_name); 1249 - if (status) 1250 - return -ENOENT; 1298 + nfs4_make_rec_clidname(dname, &clp->cl_name); 1251 1299 1252 1300 name.data = kmemdup(dname, HEXDIR_LEN, GFP_KERNEL); 1253 1301 if (!name.data) { ··· 1617 1671 return NULL; 1618 1672 } 1619 1673 1620 - copied = nfs4_make_rec_clidname(result + copied, name); 1621 - if (copied) { 1622 - kfree(result); 1623 - return NULL; 1624 - } 1674 + nfs4_make_rec_clidname(result + copied, name); 1625 1675 1626 1676 return result; 1627 1677 }