Patch "bonding: Fix bonding crash" has been added to the 4.4-stable tree
Subsystems (4)
This is a note to let you know that I've just added the patch titled
bonding: Fix bonding crash
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
bonding-fix-bonding-crash.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Wed Sep 21 12:45:10 CEST 2016
From: Mahesh Bandewar <[email protected]>
Date: Thu, 1 Sep 2016 22:18:34 -0700
Subject: bonding: Fix bonding crash
From: Mahesh Bandewar <[email protected]>
[ Upstream commit 24b27fc4cdf9e10c5e79e5923b6b7c2c5c95096c ]
Following few steps will crash kernel -
(a) Create bonding master
> modprobe bonding miimon=50
(b) Create macvlan bridge on eth2
> ip link add link eth2 dev mvl0 address aa:0:0:0:0:01 \ type macvlan
(c) Now try adding eth2 into the bond
> echo +eth2 > /sys/class/net/bond0/bonding/slaves <crash>
Bonding does lots of things before checking if the device enslaved is busy or not.
In this case when the notifier call-chain sends notifications, the bond_netdev_event() assumes that the rx_handler /rx_handler_data is registered while the bond_enslave() hasn't progressed far enough to register rx_handler for the new slave.
This patch adds a rx_handler check that can be performed right at the beginning of the enslave code to avoid getting into this situation.
--- drivers/net/bonding/bond_main.c | 7 ++++--- include/linux/netdevice.h | 1 + net/core/dev.c | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 3 deletions(-)
drivers/net/bonding/bond_main.c +4 -3
@@ -1317,9 +1317,10 @@ int bond_enslave(struct net_device *bond slave_dev->name); } -/* already enslaved */ -if (slave_dev->flags &IFF_SLAVE ) { -netdev_dbg (bond_dev,"Error: Device was already enslaved\n" ); +/* already in-use? */ +if (netdev_is_rx_handler_busy (slave_dev)) { +netdev_err (bond_dev, +"Error: Device is in use and cannot be enslaved\n" );return -EBUSY ; }
include/linux/netdevice.h +1 -0
@@ -3036,6 +3036,7 @@ static inline void napi_free_frags(struc napi->skb =NULL ; } +bool netdev_is_rx_handler_busy (struct net_device *dev);int netdev_rx_handler_register (struct net_device *dev,rx_handler_func_t *rx_handler,void *rx_handler_data);
net/core/dev.c +16 -0
@@ -3722,6 +3722,22 @@ static inline struct sk_buff *handle_ing }/** +* netdev_is_rx_handler_busy - check if receive handler is registered +* @dev: device to check +* +* Check if a receive handler is already registered for a given device. +* Return true if there one. +* +* The caller must hold the rtnl_mutex. +*/ +bool netdev_is_rx_handler_busy (struct net_device *dev) +{ +ASSERT_RTNL (); +return dev &&rtnl_dereference (dev->rx_handler); +} +EXPORT_SYMBOL_GPL (netdev_is_rx_handler_busy); + +/** * netdev_rx_handler_register - register receive handler * @dev: device to register a handler for * @rx_handler: receive handler to register
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/bonding-fix-bonding-crash.patch