Fix NULL pointer dereference in ena_up()

If the call to ena_up() in ena_restore_device() fails, next usage of
`ifconfig up` will cause NULL pointer dereference.

This patch adds additional checks to prevent that.

Submitted by:  Rafal Kozik <rk@semihalf.com>
Obtained from: Semihalf
Sponsored by:  Amazon, Inc.
This commit is contained in:
mw 2019-05-30 13:42:52 +00:00
parent c8a33fe4c2
commit 0d75120490

View File

@ -134,7 +134,7 @@ static void ena_cleanup(void *arg, int pending);
static int ena_handle_msix(void *); static int ena_handle_msix(void *);
static int ena_enable_msix(struct ena_adapter *); static int ena_enable_msix(struct ena_adapter *);
static void ena_setup_mgmnt_intr(struct ena_adapter *); static void ena_setup_mgmnt_intr(struct ena_adapter *);
static void ena_setup_io_intr(struct ena_adapter *); static int ena_setup_io_intr(struct ena_adapter *);
static int ena_request_mgmnt_irq(struct ena_adapter *); static int ena_request_mgmnt_irq(struct ena_adapter *);
static int ena_request_io_irq(struct ena_adapter *); static int ena_request_io_irq(struct ena_adapter *);
static void ena_free_mgmnt_irq(struct ena_adapter *); static void ena_free_mgmnt_irq(struct ena_adapter *);
@ -1969,12 +1969,15 @@ ena_setup_mgmnt_intr(struct ena_adapter *adapter)
adapter->msix_entries[ENA_MGMNT_IRQ_IDX].vector; adapter->msix_entries[ENA_MGMNT_IRQ_IDX].vector;
} }
static void static int
ena_setup_io_intr(struct ena_adapter *adapter) ena_setup_io_intr(struct ena_adapter *adapter)
{ {
static int last_bind_cpu = -1; static int last_bind_cpu = -1;
int irq_idx; int irq_idx;
if (adapter->msix_entries == NULL)
return (EINVAL);
for (int i = 0; i < adapter->num_queues; i++) { for (int i = 0; i < adapter->num_queues; i++) {
irq_idx = ENA_IO_IRQ_IDX(i); irq_idx = ENA_IO_IRQ_IDX(i);
@ -1997,6 +2000,8 @@ ena_setup_io_intr(struct ena_adapter *adapter)
last_bind_cpu; last_bind_cpu;
last_bind_cpu = CPU_NEXT(last_bind_cpu); last_bind_cpu = CPU_NEXT(last_bind_cpu);
} }
return (0);
} }
static int static int
@ -2290,11 +2295,15 @@ ena_up(struct ena_adapter *adapter)
device_printf(adapter->pdev, "device is going UP\n"); device_printf(adapter->pdev, "device is going UP\n");
/* setup interrupts for IO queues */ /* setup interrupts for IO queues */
ena_setup_io_intr(adapter); rc = ena_setup_io_intr(adapter);
if (unlikely(rc != 0)) {
ena_trace(ENA_ALERT, "error setting up IO interrupt\n");
goto error;
}
rc = ena_request_io_irq(adapter); rc = ena_request_io_irq(adapter);
if (unlikely(rc != 0)) { if (unlikely(rc != 0)) {
ena_trace(ENA_ALERT, "err_req_irq\n"); ena_trace(ENA_ALERT, "err_req_irq\n");
goto err_req_irq; goto error;
} }
/* allocate transmit descriptors */ /* allocate transmit descriptors */
@ -2351,7 +2360,7 @@ ena_up(struct ena_adapter *adapter)
ena_free_all_tx_resources(adapter); ena_free_all_tx_resources(adapter);
err_setup_tx: err_setup_tx:
ena_free_io_irq(adapter); ena_free_io_irq(adapter);
err_req_irq: error:
return (rc); return (rc);
} }