summaryrefslogtreecommitdiff
path: root/drivers/staging/lustre/lnet/libcfs
diff options
context:
space:
mode:
authorAndreas Dilger <andreas.dilger@intel.com>2016-03-26 19:40:51 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2016-03-29 19:06:51 (GMT)
commitc11e27a4ee39479b9afef86bfed8ef3f75756262 (patch)
treec75ebc6ba5a85698e5c929d2160b63ffa5037a46 /drivers/staging/lustre/lnet/libcfs
parent244cd87cc078fd18a8cbbb4db2998b95760007f6 (diff)
downloadlinux-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.c24
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;