)]}'
{
  "commit": "bfd264fbbbca7a39ea430d7bc2baf8ee2ea958e4",
  "tree": "178565008daf4e24f3803c93cc6a137528fab6fd",
  "parents": [
    "f1e2f0ce704e4a14e3f367d3b97d3dd2d8e183b7"
  ],
  "author": {
    "name": "Vladimir Oltean",
    "email": "vladimir.oltean@nxp.com",
    "time": "Wed Feb 18 18:05:51 2026 +0200"
  },
  "committer": {
    "name": "Jakub Kicinski",
    "email": "kuba@kernel.org",
    "time": "Thu Feb 19 14:55:57 2026 -0800"
  },
  "message": "net: dsa: sja1105: protect link replay helpers against NULL phylink instance\n\nThere is a crash when unbinding the sja1105 driver under special\ncircumstances:\n\nUnable to handle kernel NULL pointer dereference at virtual address 0000000000000030\nCall trace:\nphylink_run_resolve_and_disable+0x10/0x90\nsja1105_static_config_reload+0xc0/0x410\nsja1105_vlan_filtering+0x100/0x140\ndsa_port_vlan_filtering+0x13c/0x368\ndsa_port_reset_vlan_filtering.isra.0+0xe8/0x198\ndsa_port_bridge_leave+0x130/0x248\ndsa_user_changeupper.part.0+0x74/0x158\ndsa_user_netdevice_event+0x50c/0xa50\nnotifier_call_chain+0x78/0x148\nraw_notifier_call_chain+0x20/0x38\ncall_netdevice_notifiers_info+0x58/0xa8\n__netdev_upper_dev_unlink+0xac/0x220\nnetdev_upper_dev_unlink+0x38/0x70\ndel_nbp+0x1a4/0x320\nbr_del_if+0x3c/0xd8\nbr_device_event+0xf8/0x2d8\nnotifier_call_chain+0x78/0x148\nraw_notifier_call_chain+0x20/0x38\ncall_netdevice_notifiers_info+0x58/0xa8\nunregister_netdevice_many_notify+0x314/0x848\nunregister_netdevice_queue+0xe8/0xf8\ndsa_user_destroy+0x50/0xa8\ndsa_port_teardown+0x80/0x98\ndsa_switch_teardown_ports+0x4c/0xb8\ndsa_switch_deinit+0x94/0xb8\ndsa_switch_put_tree+0x2c/0xc0\ndsa_unregister_switch+0x38/0x60\nsja1105_remove+0x24/0x40\nspi_remove+0x38/0x60\ndevice_remove+0x54/0x90\ndevice_release_driver_internal+0x1d4/0x230\ndevice_driver_detach+0x20/0x38\nunbind_store+0xbc/0xc8\n---[ end trace 0000000000000000 ]---\n\nwhich requires an explanation.\n\nWhen a port offloads a bridge, the switch must be reset to change\nthe VLAN awareness state (the SJA1105_VLAN_FILTERING reason for\nsja1105_static_config_reload()). When the port leaves a VLAN-aware\nbridge, it must also be reset for the same reason: it is returning\nto operation as a VLAN-unaware standalone port.\n\nsja1105_static_config_reload() triggers the phylink link replay helpers.\n\nBecause sja1105 is a switch, it has multiple user ports. During unbind,\nports are torn down one by one in dsa_switch_teardown_ports() -\u003e\ndsa_port_teardown() -\u003e dsa_user_destroy().\n\nThe crash happens when the first user port is not part of the VLAN-aware\nbridge, but any other user port is.\n\nTearing down the first user port causes phylink_destroy() to be called\non dp-\u003epl, and this pointer to be set to NULL. Then, when the second\nuser port is torn down, this was offloading a VLAN-aware bridge port, so\nindirectly it will trigger sja1105_static_config_reload().\n\nThe latter function iterates using dsa_switch_for_each_available_port(),\nand unconditionally dereferences dp-\u003epl, including for the\naforementioned torn down previous port, and passes that to phylink.\nThis is where the NULL pointer is coming from.\n\nThere are multiple levels at which this could be avoided:\n- add an \"if (dp-\u003epl)\" in sja1105_static_config_reload()\n- make the phylink replay helpers NULL-tolerant\n- mark ports as DSA_PORT_TYPE_UNUSED after dsa_port_phylink_destroy()\n  has run, such that subsequent dsa_switch_for_each_available_port()\n  iterations skip them\n- disconnect the entire switch at once from switchdev and\n  NETDEV_CHANGEUPPER events while unbinding, not just port by port,\n  likely using a \"ds-\u003eunbinding \u003d true\" mechanism or similar\n\nhowever options 3 and 4 are quite heavy and might have side effects.\nAlthough 2 allows to keep the driver simpler, the phylink API it not\nNULL-tolerant in general and is not responsible for the NULL pointer\n(this is something done by dsa_port_phylink_destroy()). So I went\nwith 1.\n\nFunctionally speaking, skipping the replay helpers for ports without\na phylink instance is fine, because that only happens during driver\nremoval (an operation which cannot be cancelled). The ports are not\nrequired to work (although they probably still will - untested\nassumption - as long as we don\u0027t overwrite the last port speed with\nSJA1105_SPEED_AUTO).\n\nFixes: 0b2edc531e0b (\"net: dsa: sja1105: let phylink help with the replay of link callbacks\")\nSigned-off-by: Vladimir Oltean \u003cvladimir.oltean@nxp.com\u003e\nReviewed-by: Andrew Lunn \u003candrew@lunn.ch\u003e\nLink: https://patch.msgid.link/20260218160551.194782-1-vladimir.oltean@nxp.com\nSigned-off-by: Jakub Kicinski \u003ckuba@kernel.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "71a817c07a90c306f32f1c20fdbc14427e30fe2a",
      "old_mode": 33188,
      "old_path": "drivers/net/dsa/sja1105/sja1105_main.c",
      "new_id": "94d17b06da404f476d09fbe96551a6fe25f7bae2",
      "new_mode": 33188,
      "new_path": "drivers/net/dsa/sja1105/sja1105_main.c"
    }
  ]
}
