diff options
author | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2023-05-10 03:35:33 +0200 |
---|---|---|
committer | Takashi Sakamoto <o-takashi@sakamocchi.jp> | 2023-05-11 02:06:49 +0200 |
commit | f7dcc5e33c1e4b0d278a30f7d2f0c9a63d7b40ca (patch) | |
tree | da3cd5d35809d08d28da8d0f17861859d63cd471 /drivers | |
parent | Linux 6.4-rc1 (diff) | |
download | linux-f7dcc5e33c1e4b0d278a30f7d2f0c9a63d7b40ca.tar.xz linux-f7dcc5e33c1e4b0d278a30f7d2f0c9a63d7b40ca.zip |
firewire: net: fix unexpected release of object for asynchronous request packet
The lifetime of object for asynchronous request packet is now maintained
by reference counting, while current implementation of firewire-net
releases the passed object in the handler.
This commit fixes the bug.
Reported-by: Dan Carpenter <error27@gmail.com>
Link: https://lore.kernel.org/lkml/Y%2Fymx6WZIAlrtjLc@workstation/
Fixes: 13a55d6bb15f ("firewire: core: use kref structure to maintain lifetime of data for fw_request structure")
Link: https://lore.kernel.org/lkml/20230510031205.782032-1-o-takashi@sakamocchi.jp/
Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/firewire/net.c | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index af22be84034b..538bd677c254 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -706,21 +706,22 @@ static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, int rcode; if (destination == IEEE1394_ALL_NODES) { - kfree(r); - - return; - } - - if (offset != dev->handler.offset) + // Although the response to the broadcast packet is not necessarily required, the + // fw_send_response() function should still be called to maintain the reference + // counting of the object. In the case, the call of function just releases the + // object as a result to decrease the reference counting. + rcode = RCODE_COMPLETE; + } else if (offset != dev->handler.offset) { rcode = RCODE_ADDRESS_ERROR; - else if (tcode != TCODE_WRITE_BLOCK_REQUEST) + } else if (tcode != TCODE_WRITE_BLOCK_REQUEST) { rcode = RCODE_TYPE_ERROR; - else if (fwnet_incoming_packet(dev, payload, length, - source, generation, false) != 0) { + } else if (fwnet_incoming_packet(dev, payload, length, + source, generation, false) != 0) { dev_err(&dev->netdev->dev, "incoming packet failure\n"); rcode = RCODE_CONFLICT_ERROR; - } else + } else { rcode = RCODE_COMPLETE; + } fw_send_response(card, r, rcode); } |