[PATCH v3] sfc: falcon: potential dereference null pointer of rx_queue->page_ring

DORMANTno replies

From: Jiasheng Jiang <hidden>
Date: 2021-12-20 02:35:30
Also in: lkml
Subsystem: networking drivers, sfc network driver, the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Edward Cree, Linus Torvalds

The return value of kcalloc() needs to be checked.
To avoid dereference of null pointer in case of the failure of alloc,
such as ef4_fini_rx_queue().
Therefore, it should be better to change the definition of page_ptr_mask
to signed int and then assign the page_ptr_mask to -1 when page_ring is
NULL, in order to avoid the use in the loop.

Fixes: 5a6681e22c14 ("sfc: separate out SFC4000 ("Falcon") support into new sfc-falcon driver")
Signed-off-by: Jiasheng Jiang <redacted>
---
Changelog:

v2 -> v3

*Change 1. Alter the "ret" to 'rc' and cleanup the rx_queue and tx_queue when alloc fails.
*Change 2. Set size to -1 instead of return error.
---
 drivers/net/ethernet/sfc/falcon/net_driver.h | 2 +-
 drivers/net/ethernet/sfc/falcon/rx.c         | 5 ++++-
 2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/sfc/falcon/net_driver.h b/drivers/net/ethernet/sfc/falcon/net_driver.h
index a381cf9ec4f3..2990563c8832 100644
--- a/drivers/net/ethernet/sfc/falcon/net_driver.h
+++ b/drivers/net/ethernet/sfc/falcon/net_driver.h
@@ -345,7 +345,7 @@ struct ef4_rx_queue {
 	unsigned int page_recycle_count;
 	unsigned int page_recycle_failed;
 	unsigned int page_recycle_full;
-	unsigned int page_ptr_mask;
+	int page_ptr_mask;
 	unsigned int max_fill;
 	unsigned int fast_fill_trigger;
 	unsigned int min_fill;
diff --git a/drivers/net/ethernet/sfc/falcon/rx.c b/drivers/net/ethernet/sfc/falcon/rx.c
index 966f13e7475d..328ad0685f59 100644
--- a/drivers/net/ethernet/sfc/falcon/rx.c
+++ b/drivers/net/ethernet/sfc/falcon/rx.c
@@ -728,7 +728,10 @@ static void ef4_init_rx_recycle_ring(struct ef4_nic *efx,
 					    efx->rx_bufs_per_page);
 	rx_queue->page_ring = kcalloc(page_ring_size,
 				      sizeof(*rx_queue->page_ring), GFP_KERNEL);
-	rx_queue->page_ptr_mask = page_ring_size - 1;
+	if (!rx_queue->page_ring)
+		rx_queue->page_ptr_mask = -1;
+	else
+		rx_queue->page_ptr_mask = page_ring_size - 1;
 }
 
 void ef4_init_rx_queue(struct ef4_rx_queue *rx_queue)
-- 
2.25.1
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help