提交 a83165f0 编写于 作者: J Jiri Pirko 提交者: David S. Miller

rocker: fix possible null pointer dereference in rocker_router_fib_event_work

Currently, rocker user may experience following null pointer
derefence bug:

[    3.062141] BUG: unable to handle kernel NULL pointer dereference at 00000000000000d0
[    3.065163] IP: rocker_router_fib_event_work+0x36/0x110 [rocker]

The problem is uninitialized rocker->wops pointer that is initialized
only with the first initialized port. So move the port initialization
before registering the fib events.

Fixes: 936bd486 ("rocker: use FIB notifications instead of switchdev calls")
Signed-off-by: NJiri Pirko <jiri@mellanox.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 0ba98718
...@@ -2902,6 +2902,12 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2902,6 +2902,12 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto err_alloc_ordered_workqueue; goto err_alloc_ordered_workqueue;
} }
err = rocker_probe_ports(rocker);
if (err) {
dev_err(&pdev->dev, "failed to probe ports\n");
goto err_probe_ports;
}
/* Only FIBs pointing to our own netdevs are programmed into /* Only FIBs pointing to our own netdevs are programmed into
* the device, so no need to pass a callback. * the device, so no need to pass a callback.
*/ */
...@@ -2918,22 +2924,16 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2918,22 +2924,16 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
rocker->hw.id = rocker_read64(rocker, SWITCH_ID); rocker->hw.id = rocker_read64(rocker, SWITCH_ID);
err = rocker_probe_ports(rocker);
if (err) {
dev_err(&pdev->dev, "failed to probe ports\n");
goto err_probe_ports;
}
dev_info(&pdev->dev, "Rocker switch with id %*phN\n", dev_info(&pdev->dev, "Rocker switch with id %*phN\n",
(int)sizeof(rocker->hw.id), &rocker->hw.id); (int)sizeof(rocker->hw.id), &rocker->hw.id);
return 0; return 0;
err_probe_ports:
unregister_switchdev_notifier(&rocker_switchdev_notifier);
err_register_switchdev_notifier: err_register_switchdev_notifier:
unregister_fib_notifier(&rocker->fib_nb); unregister_fib_notifier(&rocker->fib_nb);
err_register_fib_notifier: err_register_fib_notifier:
rocker_remove_ports(rocker);
err_probe_ports:
destroy_workqueue(rocker->rocker_owq); destroy_workqueue(rocker->rocker_owq);
err_alloc_ordered_workqueue: err_alloc_ordered_workqueue:
free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker); free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);
...@@ -2961,9 +2961,9 @@ static void rocker_remove(struct pci_dev *pdev) ...@@ -2961,9 +2961,9 @@ static void rocker_remove(struct pci_dev *pdev)
{ {
struct rocker *rocker = pci_get_drvdata(pdev); struct rocker *rocker = pci_get_drvdata(pdev);
rocker_remove_ports(rocker);
unregister_switchdev_notifier(&rocker_switchdev_notifier); unregister_switchdev_notifier(&rocker_switchdev_notifier);
unregister_fib_notifier(&rocker->fib_nb); unregister_fib_notifier(&rocker->fib_nb);
rocker_remove_ports(rocker);
rocker_write32(rocker, CONTROL, ROCKER_CONTROL_RESET); rocker_write32(rocker, CONTROL, ROCKER_CONTROL_RESET);
destroy_workqueue(rocker->rocker_owq); destroy_workqueue(rocker->rocker_owq);
free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker); free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册