Skip to content

Commit bea1898

Browse files
dmertmananguy11
authored andcommitted
ice: Fix KASAN error in LAG NETDEV_UNREGISTER handler
Currently, the same handler is called for both a NETDEV_BONDING_INFO LAG unlink notification as for a NETDEV_UNREGISTER call. This is causing a problem though, since the netdev_notifier_info passed has a different structure depending on which event is passed. The problem manifests as a call trace from a BUG: KASAN stack-out-of-bounds error. Fix this by creating a handler specific to NETDEV_UNREGISTER that only is passed valid elements in the netdev_notifier_info struct for the NETDEV_UNREGISTER event. Also included is the removal of an unbalanced dev_put on the peer_netdev and related braces. Fixes: 6a8b357 ("ice: Respond to a NETDEV_UNREGISTER event for LAG") Signed-off-by: Dave Ertman <[email protected]> Acked-by: Jonathan Toppins <[email protected]> Tested-by: Sunitha Mekala <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 46b699c commit bea1898

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

drivers/net/ethernet/intel/ice/ice_lag.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,17 +204,39 @@ ice_lag_unlink(struct ice_lag *lag,
204204
lag->upper_netdev = NULL;
205205
}
206206

207-
if (lag->peer_netdev) {
208-
dev_put(lag->peer_netdev);
209-
lag->peer_netdev = NULL;
210-
}
211-
207+
lag->peer_netdev = NULL;
212208
ice_set_sriov_cap(pf);
213209
ice_set_rdma_cap(pf);
214210
lag->bonded = false;
215211
lag->role = ICE_LAG_NONE;
216212
}
217213

214+
/**
215+
* ice_lag_unregister - handle netdev unregister events
216+
* @lag: LAG info struct
217+
* @netdev: netdev reporting the event
218+
*/
219+
static void ice_lag_unregister(struct ice_lag *lag, struct net_device *netdev)
220+
{
221+
struct ice_pf *pf = lag->pf;
222+
223+
/* check to see if this event is for this netdev
224+
* check that we are in an aggregate
225+
*/
226+
if (netdev != lag->netdev || !lag->bonded)
227+
return;
228+
229+
if (lag->upper_netdev) {
230+
dev_put(lag->upper_netdev);
231+
lag->upper_netdev = NULL;
232+
ice_set_sriov_cap(pf);
233+
ice_set_rdma_cap(pf);
234+
}
235+
/* perform some cleanup in case we come back */
236+
lag->bonded = false;
237+
lag->role = ICE_LAG_NONE;
238+
}
239+
218240
/**
219241
* ice_lag_changeupper_event - handle LAG changeupper event
220242
* @lag: LAG info struct
@@ -307,7 +329,7 @@ ice_lag_event_handler(struct notifier_block *notif_blk, unsigned long event,
307329
ice_lag_info_event(lag, ptr);
308330
break;
309331
case NETDEV_UNREGISTER:
310-
ice_lag_unlink(lag, ptr);
332+
ice_lag_unregister(lag, netdev);
311333
break;
312334
default:
313335
break;

0 commit comments

Comments
 (0)