summaryrefslogtreecommitdiff
path: root/block/crypto.c
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2016-04-01 09:57:02 -0600
committerMax Reitz <mreitz@redhat.com>2016-04-05 17:23:21 +0200
commit95c3df5a24e2f18129b58691c2ebaf0d86808525 (patch)
treed16c0871122bf07bb6bce744b037c3350aa23f38 /block/crypto.c
parent08db36f6ec29aff59c11c0f7524c2481d8a27636 (diff)
downloadqemu-95c3df5a24e2f18129b58691c2ebaf0d86808525.tar.gz
crypto: Avoid memory leak on failure
Commit 7836857 introduced a memory leak due to invalid use of Error vs. visit_type_end(). If visiting the intermediate members fails, we clear the error and unconditionally use visit_end_struct() on the same error object; but if that cleanup succeeds, we then skip the qapi_free call. Until a later patch adds visit_check_struct(), the only safe approach is to use two separate error objects. Signed-off-by: Eric Blake <eblake@redhat.com> Message-id: 1459526222-30052-1-git-send-email-eblake@redhat.com Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block/crypto.c')
-rw-r--r--block/crypto.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/block/crypto.c b/block/crypto.c
index be3498581c..1903e84fbd 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -196,6 +196,7 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
OptsVisitor *ov;
QCryptoBlockOpenOptions *ret = NULL;
Error *local_err = NULL;
+ Error *end_err = NULL;
ret = g_new0(QCryptoBlockOpenOptions, 1);
ret->format = format;
@@ -218,10 +219,9 @@ block_crypto_open_opts_init(QCryptoBlockFormat format,
error_setg(&local_err, "Unsupported block format %d", format);
break;
}
- error_propagate(errp, local_err);
- local_err = NULL;
- visit_end_struct(opts_get_visitor(ov), &local_err);
+ visit_end_struct(opts_get_visitor(ov), &end_err);
+ error_propagate(&local_err, end_err);
out:
if (local_err) {
@@ -242,6 +242,7 @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
OptsVisitor *ov;
QCryptoBlockCreateOptions *ret = NULL;
Error *local_err = NULL;
+ Error *end_err = NULL;
ret = g_new0(QCryptoBlockCreateOptions, 1);
ret->format = format;
@@ -264,10 +265,9 @@ block_crypto_create_opts_init(QCryptoBlockFormat format,
error_setg(&local_err, "Unsupported block format %d", format);
break;
}
- error_propagate(errp, local_err);
- local_err = NULL;
- visit_end_struct(opts_get_visitor(ov), &local_err);
+ visit_end_struct(opts_get_visitor(ov), &end_err);
+ error_propagate(&local_err, end_err);
out:
if (local_err) {