]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
net: ena: avoid memory access violation by validating req_id properly
authorArthur Kiyanovski <akiyano@amazon.com>
Tue, 17 Mar 2020 07:06:41 +0000 (09:06 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 1 Apr 2020 08:59:51 +0000 (10:59 +0200)
[ Upstream commit 30623e1ed116bcd1785217d0a98eec643687e091 ]

Rx req_id is an index in struct ena_eth_io_rx_cdesc_base.
The driver should validate that the Rx req_id it received from
the device is in range [0, ring_size -1].  Failure to do so could
yield to potential memory access violoation.
The validation was mistakenly done when refilling
the Rx submission queue and not in Rx completion queue.

Fixes: ad974baef2a1 ("net: ena: add support for out of order rx buffers refill")
Signed-off-by: Noam Dagan <ndagan@amazon.com>
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/ethernet/amazon/ena/ena_netdev.c

index 91d4f8c91263b7a0d57769300ef8baaf6cdd3243..ba832e49a458b95d35a9827938f6f90984896962 100644 (file)
@@ -532,13 +532,9 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num)
                struct ena_rx_buffer *rx_info;
 
                req_id = rx_ring->free_ids[next_to_use];
-               rc = validate_rx_req_id(rx_ring, req_id);
-               if (unlikely(rc < 0))
-                       break;
 
                rx_info = &rx_ring->rx_buffer_info[req_id];
 
-
                rc = ena_alloc_rx_page(rx_ring, rx_info,
                                       GFP_ATOMIC | __GFP_COMP);
                if (unlikely(rc < 0)) {
@@ -868,9 +864,15 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
        struct ena_rx_buffer *rx_info;
        u16 len, req_id, buf = 0;
        void *va;
+       int rc;
 
        len = ena_bufs[buf].len;
        req_id = ena_bufs[buf].req_id;
+
+       rc = validate_rx_req_id(rx_ring, req_id);
+       if (unlikely(rc < 0))
+               return NULL;
+
        rx_info = &rx_ring->rx_buffer_info[req_id];
 
        if (unlikely(!rx_info->page)) {
@@ -943,6 +945,11 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring,
                buf++;
                len = ena_bufs[buf].len;
                req_id = ena_bufs[buf].req_id;
+
+               rc = validate_rx_req_id(rx_ring, req_id);
+               if (unlikely(rc < 0))
+                       return NULL;
+
                rx_info = &rx_ring->rx_buffer_info[req_id];
        } while (1);