adapter: capture manager (not Iwd_Adapter) in Set(Powered) reply
On _on_name_vanished the adapter hash is freed, so an in-flight Set(Powered) reply that lands as a local error after disconnect would deref a freed Iwd_Adapter. Mirror the pattern already used in iwd_network.c / iwd_device.c: capture the manager pointer plus a strdup'd path in a small reply context, free in the reply callback.
This commit is contained in:
parent
438fffbacd
commit
862594256a
1 changed files with 22 additions and 4 deletions
|
|
@ -61,14 +61,26 @@ iwd_adapter_free(Iwd_Adapter *a)
|
||||||
free(a);
|
free(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reply context captures the *manager* (which outlives all sub-objects) and
|
||||||
|
* a strdup'd adapter path, never the Iwd_Adapter — on iwd disconnect the
|
||||||
|
* adapter hash is freed, and a raw back-ref would UAF when the local-error
|
||||||
|
* reply lands. Mirrors the pattern in iwd_network.c / iwd_device.c. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
Iwd_Manager *m;
|
||||||
|
char *path;
|
||||||
|
} _Adapter_Reply_Ctx;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_on_set_powered_reply(void *data, const Eldbus_Message *msg, Eldbus_Pending *p EINA_UNUSED)
|
_on_set_powered_reply(void *data, const Eldbus_Message *msg, Eldbus_Pending *p EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Iwd_Adapter *a = data;
|
_Adapter_Reply_Ctx *ctx = data;
|
||||||
const char *en, *em;
|
const char *en, *em;
|
||||||
if (eldbus_message_error_get(msg, &en, &em) && a->manager)
|
if (eldbus_message_error_get(msg, &en, &em) && ctx->m)
|
||||||
iwd_manager_report_error(a->manager,
|
iwd_manager_report_error(ctx->m,
|
||||||
"Set Adapter.Powered failed: %s", em ? em : en);
|
"Set Adapter.Powered failed: %s", em ? em : en);
|
||||||
|
free(ctx->path);
|
||||||
|
free(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -93,7 +105,13 @@ iwd_adapter_set_powered(Iwd_Adapter *a, Eina_Bool on)
|
||||||
eldbus_message_iter_basic_append(variant, 'b', v);
|
eldbus_message_iter_basic_append(variant, 'b', v);
|
||||||
eldbus_message_iter_container_close(iter, variant);
|
eldbus_message_iter_container_close(iter, variant);
|
||||||
|
|
||||||
eldbus_proxy_send(props, msg, _on_set_powered_reply, a, -1);
|
_Adapter_Reply_Ctx *ctx = calloc(1, sizeof(*ctx));
|
||||||
|
if (ctx)
|
||||||
|
{
|
||||||
|
ctx->m = a->manager;
|
||||||
|
ctx->path = a->path ? strdup(a->path) : NULL;
|
||||||
|
}
|
||||||
|
eldbus_proxy_send(props, msg, _on_set_powered_reply, ctx, -1);
|
||||||
/* Keep the props proxy alive on the adapter so the call isn't canceled. */
|
/* Keep the props proxy alive on the adapter so the call isn't canceled. */
|
||||||
if (a->_props_proxy_keepalive) eldbus_proxy_unref(a->_props_proxy_keepalive);
|
if (a->_props_proxy_keepalive) eldbus_proxy_unref(a->_props_proxy_keepalive);
|
||||||
a->_props_proxy_keepalive = props;
|
a->_props_proxy_keepalive = props;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue