From a32b41746c4e1a44fb998a93da99c72f6586b359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A1n=20Tomko?= Date: Wed, 22 May 2013 12:56:23 +0200 Subject: [PATCH] conf: fix use after free in virChrdevOpen Don't free the stream on error if we've successfully added it to the hash table, since it will be freed by virChrdevHashEntryFree callback. Preserve the error message before calling virStreamFree, since it resets the error. Introduced by 4716138, crashing since 6921892. Reported by Sergey Fionov on libvir-list. --- src/conf/virchrdev.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/conf/virchrdev.c b/src/conf/virchrdev.c index d15d861d94..17b1f05f86 100644 --- a/src/conf/virchrdev.c +++ b/src/conf/virchrdev.c @@ -341,6 +341,8 @@ int virChrdevOpen(virChrdevsPtr devs, virStreamPtr savedStream; char *path; int ret; + bool added = false; + virErrorPtr savedError; switch (source->type) { case VIR_DOMAIN_CHR_TYPE_PTY: @@ -397,6 +399,7 @@ int virChrdevOpen(virChrdevsPtr devs, if (virHashAddEntry(devs->hash, path, st) < 0) goto error; + added = true; cbdata->devs = devs; if (VIR_STRDUP(cbdata->path, path) < 0) @@ -429,8 +432,16 @@ int virChrdevOpen(virChrdevsPtr devs, return 0; error: - virStreamFree(st); - virHashRemoveEntry(devs->hash, path); + savedError = virSaveLastError(); + + if (added) + virHashRemoveEntry(devs->hash, path); + else + virStreamFree(st); + + virSetError(savedError); + virFreeError(savedError); + if (cbdata) VIR_FREE(cbdata->path); VIR_FREE(cbdata);