lkml.org 
[lkml]   [2022]   [Feb]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.16 039/227] net: ieee802154: at86rf230: Stop leaking skbs
    Date
    From: Miquel Raynal <miquel.raynal@bootlin.com>

    [ Upstream commit e5ce576d45bf72fd0e3dc37eff897bfcc488f6a9 ]

    Upon error the ieee802154_xmit_complete() helper is not called. Only
    ieee802154_wake_queue() is called manually. In the Tx case we then leak
    the skb structure.

    Free the skb structure upon error before returning when appropriate.

    As the 'is_tx = 0' cannot be moved in the complete handler because of a
    possible race between the delay in switching to STATE_RX_AACK_ON and a
    new interrupt, we introduce an intermediate 'was_tx' boolean just for
    this purpose.

    There is no Fixes tag applying here, many changes have been made on this
    area and the issue kind of always existed.

    Suggested-by: Alexander Aring <alex.aring@gmail.com>
    Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
    Acked-by: Alexander Aring <aahringo@redhat.com>
    Link: https://lore.kernel.org/r/20220125121426.848337-4-miquel.raynal@bootlin.com
    Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/net/ieee802154/at86rf230.c | 13 +++++++++++--
    1 file changed, 11 insertions(+), 2 deletions(-)

    diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
    index 7d67f41387f55..4f5ef8a9a9a87 100644
    --- a/drivers/net/ieee802154/at86rf230.c
    +++ b/drivers/net/ieee802154/at86rf230.c
    @@ -100,6 +100,7 @@ struct at86rf230_local {
    unsigned long cal_timeout;
    bool is_tx;
    bool is_tx_from_off;
    + bool was_tx;
    u8 tx_retry;
    struct sk_buff *tx_skb;
    struct at86rf230_state_change tx;
    @@ -343,7 +344,11 @@ at86rf230_async_error_recover_complete(void *context)
    if (ctx->free)
    kfree(ctx);

    - ieee802154_wake_queue(lp->hw);
    + if (lp->was_tx) {
    + lp->was_tx = 0;
    + dev_kfree_skb_any(lp->tx_skb);
    + ieee802154_wake_queue(lp->hw);
    + }
    }

    static void
    @@ -352,7 +357,11 @@ at86rf230_async_error_recover(void *context)
    struct at86rf230_state_change *ctx = context;
    struct at86rf230_local *lp = ctx->lp;

    - lp->is_tx = 0;
    + if (lp->is_tx) {
    + lp->was_tx = 1;
    + lp->is_tx = 0;
    + }
    +
    at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON,
    at86rf230_async_error_recover_complete);
    }
    --
    2.34.1


    \
     
     \ /
      Last update: 2022-02-21 18:51    [W:2.290 / U:0.096 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site