bluez5: fix wrong use of send_with_reply in HFP backends

The pattern if (!send_with_reply(...)) leaks DBusPendingCall and is
UAF prone.

Replace these with proper tracking and cancellation of the pending
calls in HFP backends.
This commit is contained in:
Pauli Virtanen 2026-05-04 19:52:46 +03:00 committed by Wim Taymans
parent 81470db44f
commit 31f0300c48
3 changed files with 43 additions and 14 deletions

View file

@ -106,6 +106,8 @@ struct impl {
struct spa_dbus *dbus;
DBusConnection *conn;
DBusPendingCall *pending_register_profile;
const struct media_codec * const * codecs;
#define DEFAULT_ENABLED_PROFILES (SPA_BT_PROFILE_HFP_HF | SPA_BT_PROFILE_HFP_AG)
@ -3685,7 +3687,8 @@ static void register_profile_reply(DBusPendingCall *pending, void *user_data)
{
struct impl *backend = user_data;
spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
spa_assert(backend->pending_register_profile == pending);
spa_autoptr(DBusMessage) r = steal_reply_and_unref(&backend->pending_register_profile);
if (r == NULL)
return;
@ -3715,6 +3718,9 @@ static int register_profile(struct impl *backend, const char *profile, const cha
if (!(backend->enabled_profiles & spa_bt_profile_from_uuid(uuid)))
return -ECANCELED;
if (backend->pending_register_profile)
return -EBUSY;
spa_log_debug(backend->log, "Registering Profile %s %s", profile, uuid);
m = dbus_message_new_method_call(BLUEZ_SERVICE, "/org/bluez",
@ -3813,7 +3819,8 @@ static int register_profile(struct impl *backend, const char *profile, const cha
}
dbus_message_iter_close_container(&it[0], &it[1]);
if (!send_with_reply(backend->conn, m, register_profile_reply, backend))
backend->pending_register_profile = send_with_reply(backend->conn, m, register_profile_reply, backend);
if (!backend->pending_register_profile)
return -EIO;
return 0;
@ -3880,6 +3887,8 @@ static int backend_native_unregister_profiles(void *data)
{
struct impl *backend = data;
cancel_and_unref(&backend->pending_register_profile);
sco_close(backend);
#ifdef HAVE_BLUEZ_5_BACKEND_HSP_NATIVE
@ -4060,6 +4069,8 @@ static int backend_native_free(void *data)
struct rfcomm *rfcomm;
cancel_and_unref(&backend->pending_register_profile);
sco_close(backend);
if (backend->modemmanager) {