sd_varlink_call_full() returns borrowed references into the varlink
connection's receive buffer (v->current). fetch_machine() stored this
borrowed reference with _cleanup_(sd_json_variant_unrefp), which would
unref it on error paths -- potentially freeing the parent object while
the varlink connection still owns it. On success, TAKE_PTR passed the
raw borrowed pointer to the caller, but the varlink connection (and its
receive buffer) is freed when fetch_machine returns, leaving the caller
with a dangling pointer.
Fix by removing the cleanup attribute (the reference is borrowed, not
owned) and taking a real ref via sd_json_variant_ref() before returning
to the caller, so the data survives the varlink connection's cleanup.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
if (r < 0)
return log_error_errno(r, "Failed to connect to machined on %s: %m", addr);
- _cleanup_(sd_json_variant_unrefp) sd_json_variant *result = NULL;
+ sd_json_variant *result = NULL;
const char *error_id;
r = sd_varlink_callbo(
vl,
return log_error_errno(r, "Failed to issue io.systemd.Machine.List() varlink call: %s", error_id);
}
- *ret = TAKE_PTR(result);
+ /* result is a borrowed reference into the varlink connection's receive buffer. Take a real ref so
+ * that it survives the cleanup of vl below. */
+ *ret = sd_json_variant_ref(result);
return 0;
}