]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
vmspawn-qmp: take temporary ref in drive_info_add_fail 41951/head
authorLuca Boccassi <luca.boccassi@gmail.com>
Tue, 5 May 2026 12:55:54 +0000 (13:55 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 5 May 2026 13:39:38 +0000 (14:39 +0100)
drive_info_add_fail() calls bridge_unregister_drive() followed by
drive_info_unref(), then continues to access the DriveInfo object.
While all current callers hold their own reference, it is a bit
fragile and it trips static analyzers. Take a local reference.

CID#1655804

Follow-up for 1d0a8e5dbd267c803e100d9030d70d327eddf8b1

src/vmspawn/vmspawn-qmp.c

index 621c5e781a7a653579830bc33684fc5c97f18c3a..d09576213a1633f88f9080304d59eee936cb6aff 100644 (file)
@@ -730,23 +730,26 @@ static int drive_info_add_fail(DriveInfo *d, int error, const char *error_desc)
         if (FLAGS_SET(d->state, BLOCK_DEVICE_STATE_ADD_FAILED))
                 return 0;
 
-        vmspawn_qmp_block_device_teardown(d->bridge->qmp, d->qmp_node_name, d->state);
-        d->state = BLOCK_DEVICE_STATE_ADD_FAILED;
+        /* Pin the object alive across bridge_unregister_drive() + drive_info_unref() below. */
+        _cleanup_(drive_info_unrefp) DriveInfo *ref = drive_info_ref(d);
 
-        if (bridge_unregister_drive(d->bridge, d))
-                drive_info_unref(d);
+        vmspawn_qmp_block_device_teardown(ref->bridge->qmp, ref->qmp_node_name, ref->state);
+        ref->state = BLOCK_DEVICE_STATE_ADD_FAILED;
 
-        if (d->link) {
-                (void) reply_qmp_error(d->link, error_desc, error);
-                d->link = sd_varlink_unref(d->link);
+        if (bridge_unregister_drive(ref->bridge, ref))
+                drive_info_unref(ref);
+
+        if (ref->link) {
+                (void) reply_qmp_error(ref->link, error_desc, error);
+                ref->link = sd_varlink_unref(ref->link);
                 return 0;
         }
 
         log_error_errno(error, "Block device '%s' setup failed: %s",
-                        strna(d->id), strna(error_desc));
+                        strna(ref->id), strna(error_desc));
 
         /* Boot-time (link == NULL) is always fatal — even for late-arriving ephemeral replies. */
-        return sd_event_exit(qmp_client_get_event(d->bridge->qmp), error);
+        return sd_event_exit(qmp_client_get_event(ref->bridge->qmp), error);
 }
 
 /* Rolls back the up-front registry insert on a sync error path. */