Skip to content

Commit dde538c

Browse files
committed
crypto/hash: avoid overwriting user supplied result pointer
If the user provides a pre-allocated buffer for the hash result, we must use that rather than re-allocating a new buffer. Reported-by: Dorjoy Chowdhury <[email protected]> Signed-off-by: Daniel P. Berrangé <[email protected]>
1 parent b5b89e9 commit dde538c

File tree

4 files changed

+45
-11
lines changed

4 files changed

+45
-11
lines changed

crypto/hash-gcrypt.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,25 @@ int qcrypto_gcrypt_hash_finalize(QCryptoHash *hash,
103103
size_t *result_len,
104104
Error **errp)
105105
{
106+
int ret;
106107
unsigned char *digest;
107108
gcry_md_hd_t *ctx = hash->opaque;
108109

109-
*result_len = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[hash->alg]);
110-
if (*result_len == 0) {
110+
ret = gcry_md_get_algo_dlen(qcrypto_hash_alg_map[hash->alg]);
111+
if (ret == 0) {
111112
error_setg(errp, "Unable to get hash length");
112113
return -1;
113114
}
114115

115-
*result = g_new(uint8_t, *result_len);
116+
if (*result_len == 0) {
117+
*result_len = ret;
118+
*result = g_new(uint8_t, *result_len);
119+
} else if (*result_len != ret) {
120+
error_setg(errp,
121+
"Result buffer size %zu is smaller than hash %d",
122+
*result_len, ret);
123+
return -1;
124+
}
116125

117126
/* Digest is freed by gcry_md_close(), copy it */
118127
digest = gcry_md_read(*ctx, 0);

crypto/hash-glib.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,15 @@ int qcrypto_glib_hash_finalize(QCryptoHash *hash,
9999
return -1;
100100
}
101101

102-
*result_len = ret;
103-
*result = g_new(uint8_t, *result_len);
102+
if (*result_len == 0) {
103+
*result_len = ret;
104+
*result = g_new(uint8_t, *result_len);
105+
} else if (*result_len != ret) {
106+
error_setg(errp,
107+
"Result buffer size %zu is smaller than hash %d",
108+
*result_len, ret);
109+
return -1;
110+
}
104111

105112
g_checksum_get_digest(ctx, *result, result_len);
106113
return 0;

crypto/hash-gnutls.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,24 @@ int qcrypto_gnutls_hash_finalize(QCryptoHash *hash,
115115
Error **errp)
116116
{
117117
gnutls_hash_hd_t *ctx = hash->opaque;
118+
int ret;
118119

119-
*result_len = gnutls_hash_get_len(qcrypto_hash_alg_map[hash->alg]);
120-
if (*result_len == 0) {
120+
ret = gnutls_hash_get_len(qcrypto_hash_alg_map[hash->alg]);
121+
if (ret == 0) {
121122
error_setg(errp, "Unable to get hash length");
122123
return -1;
123124
}
124125

125-
*result = g_new(uint8_t, *result_len);
126+
if (*result_len == 0) {
127+
*result_len = ret;
128+
*result = g_new(uint8_t, *result_len);
129+
} else if (*result_len != ret) {
130+
error_setg(errp,
131+
"Result buffer size %zu is smaller than hash %d",
132+
*result_len, ret);
133+
return -1;
134+
}
135+
126136
gnutls_hash_output(*ctx, *result);
127137
return 0;
128138
}

crypto/hash-nettle.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,17 @@ int qcrypto_nettle_hash_finalize(QCryptoHash *hash,
150150
Error **errp)
151151
{
152152
union qcrypto_hash_ctx *ctx = hash->opaque;
153-
154-
*result_len = qcrypto_hash_alg_map[hash->alg].len;
155-
*result = g_new(uint8_t, *result_len);
153+
int ret = qcrypto_hash_alg_map[hash->alg].len;
154+
155+
if (*result_len == 0) {
156+
*result_len = ret;
157+
*result = g_new(uint8_t, *result_len);
158+
} else if (*result_len != ret) {
159+
error_setg(errp,
160+
"Result buffer size %zu is smaller than hash %d",
161+
*result_len, ret);
162+
return -1;
163+
}
156164

157165
qcrypto_hash_alg_map[hash->alg].result(ctx, *result_len, *result);
158166

0 commit comments

Comments
 (0)