There is a race in rmnet_unregister_real_device() because it cancels TX aggregation before unregistering the rx handler. A transmit that already obtained the port through rmnet_get_port_rcu() can wait on port->agg_lock, then create a new aggregate and rearm the timer after rmnet_map_tx_aggregate_exit() has drained it. The timer can later queue work on the freed port. Unregister the rx handler first so that no reader can rearm aggregation after rmnet_map_tx_aggregate_exit() drains it. Fixes: 64b5d1f8f2d1 ("net: qualcomm: rmnet: add tx packets aggregation") Cc: stable@vger.kernel.org Signed-off-by: Jérémy Jean --- drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c index 61b04c6c0390..2ff4b9519139 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c @@ -40,10 +40,10 @@ static int rmnet_unregister_real_device(struct net_device *real_dev) if (port->nr_rmnet_devs) return -EINVAL; - rmnet_map_tx_aggregate_exit(port); - netdev_rx_handler_unregister(real_dev); + rmnet_map_tx_aggregate_exit(port); + kfree(port); netdev_dbg(real_dev, "Removed from rmnet\n"); -- 2.47.3