Skip to content

Commit c255a34

Browse files
akiyanodavem330
authored andcommitted
net: ena: Fix undefined state when tx request id is out of bounds
ena_com_tx_comp_req_id_get() checks the req_id of a received completion, and if it is out of bounds returns -EINVAL. This is a sign that something is wrong with the device and it needs to be reset. The current code does not reset the device in this case, which leaves the driver in an undefined state, where this completion is not properly handled. This commit adds a call to handle_invalid_req_id() in ena_clean_tx_irq() and ena_clean_xdp_irq() which resets the device to fix the issue. This commit also removes unnecessary request id checks from validate_tx_req_id() and validate_xdp_req_id(). This check is unneeded because it was already performed in ena_com_tx_comp_req_id_get(), which is called right before these functions. Fixes: 548c494 ("net: ena: Implement XDP_TX action") Signed-off-by: Shay Agroskin <[email protected]> Signed-off-by: Arthur Kiyanovski <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ae81de7 commit c255a34

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

drivers/net/ethernet/amazon/ena/ena_netdev.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,26 +1288,22 @@ static int handle_invalid_req_id(struct ena_ring *ring, u16 req_id,
12881288

12891289
static int validate_tx_req_id(struct ena_ring *tx_ring, u16 req_id)
12901290
{
1291-
struct ena_tx_buffer *tx_info = NULL;
1291+
struct ena_tx_buffer *tx_info;
12921292

1293-
if (likely(req_id < tx_ring->ring_size)) {
1294-
tx_info = &tx_ring->tx_buffer_info[req_id];
1295-
if (likely(tx_info->skb))
1296-
return 0;
1297-
}
1293+
tx_info = &tx_ring->tx_buffer_info[req_id];
1294+
if (likely(tx_info->skb))
1295+
return 0;
12981296

12991297
return handle_invalid_req_id(tx_ring, req_id, tx_info, false);
13001298
}
13011299

13021300
static int validate_xdp_req_id(struct ena_ring *xdp_ring, u16 req_id)
13031301
{
1304-
struct ena_tx_buffer *tx_info = NULL;
1302+
struct ena_tx_buffer *tx_info;
13051303

1306-
if (likely(req_id < xdp_ring->ring_size)) {
1307-
tx_info = &xdp_ring->tx_buffer_info[req_id];
1308-
if (likely(tx_info->xdpf))
1309-
return 0;
1310-
}
1304+
tx_info = &xdp_ring->tx_buffer_info[req_id];
1305+
if (likely(tx_info->xdpf))
1306+
return 0;
13111307

13121308
return handle_invalid_req_id(xdp_ring, req_id, tx_info, true);
13131309
}
@@ -1332,9 +1328,14 @@ static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 budget)
13321328

13331329
rc = ena_com_tx_comp_req_id_get(tx_ring->ena_com_io_cq,
13341330
&req_id);
1335-
if (rc)
1331+
if (rc) {
1332+
if (unlikely(rc == -EINVAL))
1333+
handle_invalid_req_id(tx_ring, req_id, NULL,
1334+
false);
13361335
break;
1336+
}
13371337

1338+
/* validate that the request id points to a valid skb */
13381339
rc = validate_tx_req_id(tx_ring, req_id);
13391340
if (rc)
13401341
break;
@@ -1896,9 +1897,14 @@ static int ena_clean_xdp_irq(struct ena_ring *xdp_ring, u32 budget)
18961897

18971898
rc = ena_com_tx_comp_req_id_get(xdp_ring->ena_com_io_cq,
18981899
&req_id);
1899-
if (rc)
1900+
if (rc) {
1901+
if (unlikely(rc == -EINVAL))
1902+
handle_invalid_req_id(xdp_ring, req_id, NULL,
1903+
true);
19001904
break;
1905+
}
19011906

1907+
/* validate that the request id points to a valid xdp_frame */
19021908
rc = validate_xdp_req_id(xdp_ring, req_id);
19031909
if (rc)
19041910
break;

0 commit comments

Comments
 (0)