diff options
author | Alexander Aring <aar@pengutronix.de> | 2016-02-19 09:59:12 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2016-02-23 20:29:39 +0100 |
commit | c231c5a47a0c697e7bc821af0b5cb28d129fe8e0 (patch) | |
tree | 1c58bf588f6f7467b318badff837b3d86d2ce719 /drivers | |
parent | 07b0188adf7298bf80a9890d3e90f27e973623d3 (diff) |
at86rf230: fix race on error handling
The resource "ctx" can be still used by at86rf230_async_state_change, we
need to free it at the complete handler of the async state change to
avoid a use after free.
Signed-off-by: Alexander Aring <aar@pengutronix.de>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ieee802154/at86rf230.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 0fbbba7a0cae..bf3cfe44b84f 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -343,16 +343,26 @@ static const struct regmap_config at86rf230_regmap_spi_config = { }; static void -at86rf230_async_error_recover(void *context) +at86rf230_async_error_recover_complete(void *context) { struct at86rf230_state_change *ctx = context; struct at86rf230_local *lp = ctx->lp; - lp->is_tx = 0; - at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, NULL); - ieee802154_wake_queue(lp->hw); if (ctx->free) kfree(ctx); + + ieee802154_wake_queue(lp->hw); +} + +static void +at86rf230_async_error_recover(void *context) +{ + struct at86rf230_state_change *ctx = context; + struct at86rf230_local *lp = ctx->lp; + + lp->is_tx = 0; + at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON, + at86rf230_async_error_recover_complete); } static inline void |