]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
conf: fix use after free in virChrdevOpen
authorJán Tomko <jtomko@redhat.com>
Wed, 22 May 2013 10:56:23 +0000 (12:56 +0200)
committerJán Tomko <jtomko@redhat.com>
Tue, 18 Jun 2013 13:30:23 +0000 (15:30 +0200)
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.
(cherry picked from commit a32b41746c4e1a44fb998a93da99c72f6586b359)

src/conf/virchrdev.c

index 1802324a772bba8e729946ec783a4f944254a339..9c886e4024c6c65aa47a60225af0067c116fecee 100644 (file)
@@ -342,6 +342,8 @@ int virChrdevOpen(virChrdevsPtr devs,
     virStreamPtr savedStream;
     const char *path;
     int ret;
+    bool added = false;
+    virErrorPtr savedError;
 
     switch (source->type) {
     case VIR_DOMAIN_CHR_TYPE_PTY:
@@ -398,6 +400,7 @@ int virChrdevOpen(virChrdevsPtr devs,
 
     if (virHashAddEntry(devs->hash, path, st) < 0)
         goto error;
+    added = true;
 
     cbdata->devs = devs;
     if (!(cbdata->path = strdup(path))) {
@@ -432,8 +435,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);