Even though commit 2e281e1155fc ("idpf: detach and close netdevs while handling a reset") prevents ethtool -N/-n operations to operate on detached netdevs, we found that out-of-tree workflows like OpenOnload can bypass ethtool core locks and call idpf_set_rxnfc directly during an idpf HW reset. When this happens, we could get kernel crashes like the following: [ 4045.787439] BUG: kernel NULL pointer dereference, address: 0000000000000070 [ 4045.794420] #PF: supervisor read access in kernel mode [ 4045.799580] #PF: error_code(0x0000) - not-present page [ 4045.804739] PGD 0 [ 4045.806772] Oops: Oops: 0000 [#1] SMP NOPTI ... [ 4045.836425] Workqueue: onload-wqueue oof_do_deferred_work_fn [onload] [ 4045.842926] RIP: 0010:idpf_del_flow_steer+0x24/0x170 [idpf] ... [ 4045.946323] Call Trace: [ 4045.948796] [ 4045.950915] ? show_trace_log_lvl+0x1b0/0x2f0 [ 4045.955293] ? show_trace_log_lvl+0x1b0/0x2f0 [ 4045.959672] ? idpf_set_rxnfc+0x6f/0x80 [idpf] [ 4046.063613] To prevent this, we need to add checks in idpf_set_rxnfc and idpf_get_rxnfc to error out if the netdev is already detached. Tested: synthetically forced idpf into a HW reset by introducing module parameters to simulate a Tx timeout and force virtual channel initialization failure. This was done by skipping completion cleaning for specific queues and returning -EIO during core initialization. The failure was then triggered by writing 1 to the corresponding sysfs parameters and calling idpf_get_rxnfc() during the reset process. Without the patch: encountered NULL pointer and kernel crash. With the patch: no crashes. Fixes: 2e281e1155fc ("idpf: detach and close netdevs while handling a reset") Cc: stable@vger.kernel.org Signed-off-by: Li Li --- v2: - Removed the raw code block from the commit message and replaced it with a textual description of the test modifications. drivers/net/ethernet/intel/idpf/idpf_ethtool.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c index bb99d9e7c65d..8368a7e6a754 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c +++ b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c @@ -43,6 +43,9 @@ static int idpf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, unsigned int cnt = 0; int err = 0; + if (!netdev || !netif_device_present(netdev)) + return -ENODEV; + idpf_vport_ctrl_lock(netdev); vport = idpf_netdev_to_vport(netdev); vport_config = np->adapter->vport_config[np->vport_idx]; @@ -349,6 +352,9 @@ static int idpf_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd) { int ret = -EOPNOTSUPP; + if (!netdev || !netif_device_present(netdev)) + return -ENODEV; + idpf_vport_ctrl_lock(netdev); switch (cmd->cmd) { case ETHTOOL_SRXCLSRLINS: -- 2.54.0.rc1.555.g9c883467ad-goog