IPoIB: Fix use-after-free of multicast object
authorPatrick McHardy <kaber@trash.net>
Thu, 30 Aug 2012 07:01:30 +0000 (07:01 +0000)
committerWilly Tarreau <w@1wt.eu>
Mon, 10 Jun 2013 09:42:57 +0000 (11:42 +0200)
commitdd70f87c0a17389be3a10ce979a8f59cc99440f1
treee87b48b3b2015e8049adba1ebe180ae6ea130db2
parente6d11ed587bbd99b2cd3bb2dba791e30d1211a1b
IPoIB: Fix use-after-free of multicast object

commit bea1e22df494a729978e7f2c54f7bda328f74bc3 upstream.

Fix a crash in ipoib_mcast_join_task().  (with help from Or Gerlitz)

Commit c8c2afe360b7 ("IPoIB: Use rtnl lock/unlock when changing device
flags") added a call to rtnl_lock() in ipoib_mcast_join_task(), which
is run from the ipoib_workqueue, and hence the workqueue can't be
flushed from the context of ipoib_stop().

In the current code, ipoib_stop() (which doesn't flush the workqueue)
calls ipoib_mcast_dev_flush(), which goes and deletes all the
multicast entries.  This takes place without any synchronization with
a possible running instance of ipoib_mcast_join_task() for the same
ipoib device, leading to a crash due to NULL pointer dereference.

Fix this by making sure that the workqueue is flushed before
ipoib_mcast_dev_flush() is called.  To make that possible, we move the
RTNL-lock wrapped code to ipoib_mcast_join_finish().

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Willy Tarreau <w@1wt.eu>
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c