92 lines
3.1 KiB
Diff
92 lines
3.1 KiB
Diff
From: Sameeh Jubran <sameehj@amazon.com>
|
|
Date: Wed, 1 May 2019 16:47:04 +0300
|
|
Subject: [PATCH] net: ena: fix: set freed objects to NULL to avoid failing
|
|
future allocations
|
|
Origin: https://git.kernel.org/linus/8ee8ee7fe87bf64738ab4e31be036a7165608b27
|
|
Bug-Debian: https://bugs.debian.org/941291
|
|
|
|
In some cases when a queue related allocation fails, successful past
|
|
allocations are freed but the pointer that pointed to them is not
|
|
set to NULL. This is a problem for 2 reasons:
|
|
1. This is generally a bad practice since this pointer might be
|
|
accidentally accessed in the future.
|
|
2. Future allocations using the same pointer check if the pointer
|
|
is NULL and fail if it is not.
|
|
|
|
Fixed this by setting such pointers to NULL in the allocation of
|
|
queue related objects.
|
|
|
|
Also refactored the code of ena_setup_tx_resources() to goto-style
|
|
error handling to avoid code duplication of resource freeing.
|
|
|
|
Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)")
|
|
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
|
|
Signed-off-by: Sameeh Jubran <sameehj@amazon.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
drivers/net/ethernet/amazon/ena/ena_netdev.c | 25 ++++++++++++--------
|
|
1 file changed, 15 insertions(+), 10 deletions(-)
|
|
|
|
Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
|
|
===================================================================
|
|
--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c
|
|
+++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c
|
|
@@ -224,28 +224,23 @@ static int ena_setup_tx_resources(struct
|
|
if (!tx_ring->tx_buffer_info) {
|
|
tx_ring->tx_buffer_info = vzalloc(size);
|
|
if (!tx_ring->tx_buffer_info)
|
|
- return -ENOMEM;
|
|
+ goto err_tx_buffer_info;
|
|
}
|
|
|
|
size = sizeof(u16) * tx_ring->ring_size;
|
|
tx_ring->free_tx_ids = vzalloc_node(size, node);
|
|
if (!tx_ring->free_tx_ids) {
|
|
tx_ring->free_tx_ids = vzalloc(size);
|
|
- if (!tx_ring->free_tx_ids) {
|
|
- vfree(tx_ring->tx_buffer_info);
|
|
- return -ENOMEM;
|
|
- }
|
|
+ if (!tx_ring->free_tx_ids)
|
|
+ goto err_free_tx_ids;
|
|
}
|
|
|
|
size = tx_ring->tx_max_header_size;
|
|
tx_ring->push_buf_intermediate_buf = vzalloc_node(size, node);
|
|
if (!tx_ring->push_buf_intermediate_buf) {
|
|
tx_ring->push_buf_intermediate_buf = vzalloc(size);
|
|
- if (!tx_ring->push_buf_intermediate_buf) {
|
|
- vfree(tx_ring->tx_buffer_info);
|
|
- vfree(tx_ring->free_tx_ids);
|
|
- return -ENOMEM;
|
|
- }
|
|
+ if (!tx_ring->push_buf_intermediate_buf)
|
|
+ goto err_push_buf_intermediate_buf;
|
|
}
|
|
|
|
/* Req id ring for TX out of order completions */
|
|
@@ -259,6 +254,15 @@ static int ena_setup_tx_resources(struct
|
|
tx_ring->next_to_clean = 0;
|
|
tx_ring->cpu = ena_irq->cpu;
|
|
return 0;
|
|
+
|
|
+err_push_buf_intermediate_buf:
|
|
+ vfree(tx_ring->free_tx_ids);
|
|
+ tx_ring->free_tx_ids = NULL;
|
|
+err_free_tx_ids:
|
|
+ vfree(tx_ring->tx_buffer_info);
|
|
+ tx_ring->tx_buffer_info = NULL;
|
|
+err_tx_buffer_info:
|
|
+ return -ENOMEM;
|
|
}
|
|
|
|
/* ena_free_tx_resources - Free I/O Tx Resources per Queue
|
|
@@ -378,6 +382,7 @@ static int ena_setup_rx_resources(struct
|
|
rx_ring->free_rx_ids = vzalloc(size);
|
|
if (!rx_ring->free_rx_ids) {
|
|
vfree(rx_ring->rx_buffer_info);
|
|
+ rx_ring->rx_buffer_info = NULL;
|
|
return -ENOMEM;
|
|
}
|
|
}
|