Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a83165f0 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

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: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0ba98718
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -2902,6 +2902,12 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id)
		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
	 * 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)

	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",
		 (int)sizeof(rocker->hw.id), &rocker->hw.id);

	return 0;

err_probe_ports:
	unregister_switchdev_notifier(&rocker_switchdev_notifier);
err_register_switchdev_notifier:
	unregister_fib_notifier(&rocker->fib_nb);
err_register_fib_notifier:
	rocker_remove_ports(rocker);
err_probe_ports:
	destroy_workqueue(rocker->rocker_owq);
err_alloc_ordered_workqueue:
	free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);
@@ -2961,9 +2961,9 @@ static void rocker_remove(struct pci_dev *pdev)
{
	struct rocker *rocker = pci_get_drvdata(pdev);

	rocker_remove_ports(rocker);
	unregister_switchdev_notifier(&rocker_switchdev_notifier);
	unregister_fib_notifier(&rocker->fib_nb);
	rocker_remove_ports(rocker);
	rocker_write32(rocker, CONTROL, ROCKER_CONTROL_RESET);
	destroy_workqueue(rocker->rocker_owq);
	free_irq(rocker_msix_vector(rocker, ROCKER_MSIX_VEC_EVENT), rocker);