From: Christian Brauner Date: Thu, 2 Apr 2026 07:01:16 +0000 (+0200) Subject: ssh-proxy: fix use-after-free of borrowed varlink reply reference X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=26a9ed955975c8a278d0cfbda410b7cd00b9d4bc;p=thirdparty%2Fsystemd.git ssh-proxy: fix use-after-free of borrowed varlink reply reference 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) --- diff --git a/src/ssh-generator/ssh-proxy.c b/src/ssh-generator/ssh-proxy.c index bfb91b5867c..fa42c5bee80 100644 --- a/src/ssh-generator/ssh-proxy.c +++ b/src/ssh-generator/ssh-proxy.c @@ -282,7 +282,7 @@ static int fetch_machine(const char *machine, RuntimeScope scope, sd_json_varian 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, @@ -303,7 +303,9 @@ static int fetch_machine(const char *machine, RuntimeScope scope, sd_json_varian 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; }