From 5eb256c99b309a86f7836a8397622662376b50f7 Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Tue, 5 May 2026 13:55:54 +0100 Subject: [PATCH] vmspawn-qmp: take temporary ref in drive_info_add_fail 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 | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/vmspawn/vmspawn-qmp.c b/src/vmspawn/vmspawn-qmp.c index 621c5e781a7..d09576213a1 100644 --- a/src/vmspawn/vmspawn-qmp.c +++ b/src/vmspawn/vmspawn-qmp.c @@ -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. */ -- 2.47.3