diff options
author | Andreas Dilger <andreas.dilger@intel.com> | 2016-03-26 19:40:51 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-03-29 19:06:51 (GMT) |
commit | c11e27a4ee39479b9afef86bfed8ef3f75756262 (patch) | |
tree | c75ebc6ba5a85698e5c929d2160b63ffa5037a46 /drivers/staging/lustre/lnet/libcfs | |
parent | 244cd87cc078fd18a8cbbb4db2998b95760007f6 (diff) | |
download | linux-c11e27a4ee39479b9afef86bfed8ef3f75756262.tar.xz |
staging: lustre: libcfs: bug fixes for cfs_crypto_hash_final()
Change cfs_crypto_hash_final() to always clean up the hash descrptor
instead of not doing this in error cases. All of the callers were
just calling cfs_crypto_hash_final() immediately to clean up the
descriptor anyway, and the old behaviour is unlike other init/fini
functions, and prone to memory leaks and other incorrect usage. The
callers can call cfs_crypto_digest_size() to determine the hash size
in advance if needed, and avoid complexity in cfs_crypto_hash_final().
Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-5053
Reviewed-on: http://review.whamcloud.com/9990
Reviewed-by: Bob Glossman <bob.glossman@intel.com>
Reviewed-by: James Simmons <uja.ornl@gmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/lustre/lnet/libcfs')
-rw-r--r-- | drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c index 6fe1fdd..d5bb10f 100644 --- a/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c +++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-crypto.c @@ -265,8 +265,8 @@ EXPORT_SYMBOL(cfs_crypto_hash_update); * \param[in,out] hash_len pointer to hash buffer size, if \a hdesc = NULL * only free \a hdesc instead of computing the hash * - * \retval -ENOSPC if \a hash = NULL, or \a hash_len < digest size * \retval 0 for success + * \retval -EOVERFLOW if hash_len is too small for the hash digest * \retval negative errno for other errors from lower layers */ int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc, @@ -276,22 +276,20 @@ int cfs_crypto_hash_final(struct cfs_crypto_hash_desc *hdesc, struct ahash_request *req = (void *)hdesc; int size = crypto_ahash_digestsize(crypto_ahash_reqtfm(req)); - if (!hash_len) { - crypto_free_ahash(crypto_ahash_reqtfm(req)); - ahash_request_free(req); - return 0; + if (!hash || !hash_len) { + err = 0; + goto free_ahash; } - if (!hash || *hash_len < size) { - *hash_len = size; - return -ENOSPC; + if (*hash_len < size) { + err = -EOVERFLOW; + goto free_ahash; } + ahash_request_set_crypt(req, NULL, hash, 0); err = crypto_ahash_final(req); - - if (err < 0) { - /* May be caller can fix error */ - return err; - } + if (!err) + *hash_len = size; +free_ahash: crypto_free_ahash(crypto_ahash_reqtfm(req)); ahash_request_free(req); return err; |