Skip to content
/ linux Public

Commit 6dc1049

Browse files
IronShenSasha Levin
authored andcommitted
net: hns3: fix double free issue for tx spare buffer
[ Upstream commit 6d2f142 ] In hns3_set_ringparam(), a temporary copy (tmp_rings) of the ring structure is created for rollback. However, the tx_spare pointer in the original ring handle is incorrectly left pointing to the old backup memory. Later, if memory allocation fails in hns3_init_all_ring() during the setup, the error path attempts to free all newly allocated rings. Since tx_spare contains a stale (non-NULL) pointer from the backup, it is mistaken for a newly allocated buffer and is erroneously freed, leading to a double-free of the backup memory. The root cause is that the tx_spare field was not cleared after its value was saved in tmp_rings, leaving a dangling pointer. Fix this by setting tx_spare to NULL in the original ring structure when the creation of the new `tx_spare` fails. This ensures the error cleanup path only frees genuinely newly allocated buffers. Fixes: 907676b ("net: hns3: use tx bounce buffer for small packets") Signed-off-by: Jian Shen <shenjian15@huawei.com> Signed-off-by: Jijie Shao <shaojijie@huawei.com> Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://patch.msgid.link/20260205121719.3285730-1-shaojijie@huawei.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 44b2256 commit 6dc1049

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,13 +1048,13 @@ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring)
10481048
int order;
10491049

10501050
if (!alloc_size)
1051-
return;
1051+
goto not_init;
10521052

10531053
order = get_order(alloc_size);
10541054
if (order > MAX_ORDER) {
10551055
if (net_ratelimit())
10561056
dev_warn(ring_to_dev(ring), "failed to allocate tx spare buffer, exceed to max order\n");
1057-
return;
1057+
goto not_init;
10581058
}
10591059

10601060
tx_spare = devm_kzalloc(ring_to_dev(ring), sizeof(*tx_spare),
@@ -1092,6 +1092,13 @@ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring)
10921092
devm_kfree(ring_to_dev(ring), tx_spare);
10931093
devm_kzalloc_error:
10941094
ring->tqp->handle->kinfo.tx_spare_buf_size = 0;
1095+
not_init:
1096+
/* When driver init or reset_init, the ring->tx_spare is always NULL;
1097+
* but when called from hns3_set_ringparam, it's usually not NULL, and
1098+
* will be restored if hns3_init_all_ring() failed. So it's safe to set
1099+
* ring->tx_spare to NULL here.
1100+
*/
1101+
ring->tx_spare = NULL;
10951102
}
10961103

10971104
/* Use hns3_tx_spare_space() to make sure there is enough buffer

0 commit comments

Comments
 (0)