summary refs log tree commit diff stats
path: root/util/qemu-option.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/qemu-option.c')
-rw-r--r--util/qemu-option.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 43de3add29..6dc27ce04f 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -1111,6 +1111,7 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
     size_t num_opts, num_dst_opts;
     QemuOptDesc *desc;
     bool need_init = false;
+    bool need_head_update;
 
     if (!list) {
         return dst;
@@ -1121,6 +1122,12 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
      */
     if (!dst) {
         need_init = true;
+        need_head_update = true;
+    } else {
+        /* Moreover, even if dst is not NULL, the realloc may move it to a
+         * different address in which case we may get a stale tail pointer
+         * in dst->head. */
+        need_head_update = QTAILQ_EMPTY(&dst->head);
     }
 
     num_opts = count_opts_list(dst);
@@ -1131,9 +1138,11 @@ QemuOptsList *qemu_opts_append(QemuOptsList *dst,
     if (need_init) {
         dst->name = NULL;
         dst->implied_opt_name = NULL;
-        QTAILQ_INIT(&dst->head);
         dst->merge_lists = false;
     }
+    if (need_head_update) {
+        QTAILQ_INIT(&dst->head);
+    }
     dst->desc[num_dst_opts].name = NULL;
 
     /* append list->desc to dst->desc */