[PATCH net 2/2] net/stmmac: Prevent dma queue NULL free on allocation failure
Jakub Raczynski
j.raczynski at samsung.com
Tue Jul 7 10:41:15 PDT 2026
During allocation of RX/TX descriptor resources and its DMA,
there is verification of failed dma_alloc_coherent() due to lack of memory.
In case of that failure, all allocated resources are freed instantly after,
but there are no checks for dma_free_coherent() whether previous step has
failed.
This will generally result in panic due to freeing NULL address.
Fix it by adding NULL verification of memory that is to be freed.
Theoretically code should also set address of pointed memory to zero when
freeing, but currently the only path of invalid address is non intialized zero,
and there is no case possible of double-free of same memory.
Fixes: e73b19baa3b1c ("net: stmmac: simplify DMA descriptor allocation/init/freeing")
Reported-by: Sashiko AI <sashiko-bot at kernel.org>
Signed-off-by: Jakub Raczynski <j.raczynski at samsung.com>
---
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3098971e0b66..187d9bbc61d9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2146,7 +2146,6 @@ static void __free_dma_rx_desc_resources(struct stmmac_priv *priv,
u32 queue)
{
struct stmmac_rx_queue *rx_q = &dma_conf->rx_queue[queue];
- size_t size;
void *addr;
/* Release the DMA RX socket buffers */
@@ -2164,9 +2163,12 @@ static void __free_dma_rx_desc_resources(struct stmmac_priv *priv,
else
addr = rx_q->dma_rx;
- size = stmmac_get_rx_desc_size(priv) * dma_conf->dma_rx_size;
+ if (!IS_ERR_OR_NULL(addr)) {
+ size_t size;
+ size = stmmac_get_rx_desc_size(priv) * dma_conf->dma_rx_size;
- dma_free_coherent(priv->device, size, addr, rx_q->dma_rx_phy);
+ dma_free_coherent(priv->device, size, addr, rx_q->dma_rx_phy);
+ }
if (xdp_rxq_info_is_reg(&rx_q->xdp_rxq))
xdp_rxq_info_unreg(&rx_q->xdp_rxq);
@@ -2198,7 +2200,6 @@ static void __free_dma_tx_desc_resources(struct stmmac_priv *priv,
u32 queue)
{
struct stmmac_tx_queue *tx_q = &dma_conf->tx_queue[queue];
- size_t size;
void *addr;
/* Release the DMA TX socket buffers */
@@ -2212,9 +2213,12 @@ static void __free_dma_tx_desc_resources(struct stmmac_priv *priv,
addr = tx_q->dma_tx;
}
- size = stmmac_get_tx_desc_size(priv, tx_q) * dma_conf->dma_tx_size;
+ if (!IS_ERR_OR_NULL(addr)) {
+ size_t size;
+ size = stmmac_get_tx_desc_size(priv, tx_q) * dma_conf->dma_tx_size;
- dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy);
+ dma_free_coherent(priv->device, size, addr, tx_q->dma_tx_phy);
+ }
kfree(tx_q->tx_skbuff_dma);
kfree(tx_q->tx_skbuff);
--
2.34.1
More information about the linux-arm-kernel
mailing list