linux/drivers/net
nikolay@redhat.com fbb0c41b81 bonding: fix miimon and arp_interval delayed work race conditions
First I would give three observations which will be used later.
Observation 1: if (delayed_work_pending(wq)) cancel_delayed_work(wq)
 This usage is wrong because the pending bit is cleared just before the
 work's fn is executed and if the function re-arms itself we might end up
 with the work still running. It's safe to call cancel_delayed_work_sync()
 even if the work is not queued at all.
Observation 2: Use of INIT_DELAYED_WORK()
 Work needs to be initialized only once prior to (de/en)queueing.
Observation 3: IFF_UP is set only after ndo_open is called

Related race conditions:
1. Race between bonding_store_miimon() and bonding_store_arp_interval()
 Because of Obs.1 we can end up having both works enqueued.
2. Multiple races with INIT_DELAYED_WORK()
 Since the works are not protected by anything between INIT_DELAYED_WORK()
 and calls to (en/de)queue it is possible for races between the following
 functions:
 (races are also possible between the calls to INIT_DELAYED_WORK()
  and workqueue code)
 bonding_store_miimon() - bonding_store_arp_interval(), bond_close(),
			  bond_open(), enqueued functions
 bonding_store_arp_interval() - bonding_store_miimon(), bond_close(),
				bond_open(), enqueued functions
3. By Obs.1 we need to change bond_cancel_all()

Bugs 1 and 2 are fixed by moving all work initializations in bond_open
which by Obs. 2 and Obs. 3 and the fact that we make sure that all works
are cancelled in bond_close(), is guaranteed not to have any work
enqueued.
Also RTNL lock is now acquired in bonding_store_miimon/arp_interval so
they can't race with bond_close and bond_open. The opposing work is
cancelled only if the IFF_UP flag is set and it is cancelled
unconditionally. The opposing work is already cancelled if the interface
is down so no need to cancel it again. This way we don't need new
synchronizations for the bonding workqueue. These bugs (and fixes) are
tied together and belong in the same patch.
Note: I have left 1 line intentionally over 80 characters (84) because I
      didn't like how it looks broken down. If you'd prefer it otherwise,
      then simply break it.

 v2: Make description text < 75 columns

Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-11-29 13:13:15 -05:00
..
appletalk net: Use PTR_RET rather than if(IS_ERR(.. [1] 2012-08-06 13:30:02 -07:00
arcnet
bonding bonding: fix miimon and arp_interval delayed work race conditions 2012-11-29 13:13:15 -05:00
caif caif: fix NULL pointer check 2012-07-24 13:54:16 -07:00
can can: peak_usb: fix hwtstamp assignment 2012-11-26 22:33:06 +01:00
cris cris: fix eth_v10.c build error 2012-08-03 20:32:31 -07:00
dsa
ethernet net/mlx4_en: Can set maxrate only for TC0 2012-11-28 11:15:32 -05:00
fddi fddi: 64 bit bug in smt_add_para() 2012-09-01 22:44:13 -04:00
hamradio sections: fix section conflicts in drivers/net/hamradio 2012-10-06 03:04:43 +09:00
hippi
hyperv hyperv: Add buffer for extended info after the RNDIS response message. 2012-10-02 14:39:31 -04:00
ieee802154 workqueue: avoid using deprecated functions 2012-10-02 16:01:31 -07:00
irda irda: sir_dev: Fix copy/paste typo 2012-11-20 15:51:55 -05:00
phy of/net/mdio-gpio: Fix pdev->id issue when using devicetrees. 2012-11-19 18:57:07 -05:00
plip
ppp Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net 2012-09-28 14:40:49 -04:00
slip
team team: fix hw_features setup 2012-11-28 11:39:22 -05:00
usb net: qmi_wwan: add Huawei E173 2012-11-28 11:23:41 -05:00
vmxnet3 vmxnet3: must split too big fragments 2012-11-02 21:58:09 -04:00
wan ixp4xx_hss: avoid calling dma_pool_create() with NULL dev 2012-11-20 15:12:44 -05:00
wimax wimax/i2400m: use is_zero_ether_addr() instead of memcmp() 2012-08-24 13:30:26 -04:00
wireless Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem 2012-11-21 11:48:31 -05:00
xen-netback xen: netback: handle compound page fragments on transmit. 2012-10-10 22:50:45 -04:00
dummy.c net: fix race condition in several drivers when reading stats 2012-07-22 12:12:32 -07:00
eql.c
ifb.c
Kconfig vxlan: Depend on CONFIG_INET 2012-10-02 14:37:31 -04:00
LICENSE.SRC
loopback.c net: loopback: set default mtu to 64K 2012-09-24 16:23:53 -04:00
macvlan.c netlink: add attributes to fdb interface 2012-10-01 18:39:44 -04:00
macvtap.c macvtap: rcu_dereference outside read-lock section 2012-08-12 13:40:48 -07:00
Makefile vxlan: virtual extensible lan 2012-10-01 18:39:45 -04:00
mdio.c
mii.c
netconsole.c netconsole: remove a redundant netconsole_target_put() 2012-08-20 02:59:49 -07:00
rionet.c rapidio/rionet: rework to support multiple RIO master ports 2012-10-06 03:05:23 +09:00
sb1000.c
Space.c
sungem_phy.c
tun.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace 2012-10-02 11:11:09 -07:00
veth.c veth: Allow to create peer link with given ifindex 2012-08-09 16:18:07 -07:00
virtio_net.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next 2012-10-02 13:38:27 -07:00
vxlan.c vxlan: Update hard_header_len based on lowerdev when instantiating VXLAN 2012-11-13 18:19:50 -05:00
xen-netfront.c xen/netfront: handle compound page fragments on transmit 2012-11-21 11:50:31 -05:00