802: fix a possible race condition
authorCong Wang <amwang@redhat.com>
Tue, 2 Apr 2013 21:52:40 +0000 (21:52 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 7 Apr 2013 21:04:17 +0000 (17:04 -0400)
(Resend with a better changelog)

garp_pdu_queue() should ways be called with this spin lock.
garp_uninit_applicant() only holds rtnl lock which is not
enough here.  A possible race can happen as garp_pdu_rcv()
is called in BH context:

garp_pdu_rcv()
  |->garp_pdu_parse_msg()
    |->garp_pdu_parse_attr()
      |-> garp_gid_event()

Found by code inspection.

Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: David Ward <david.ward@ll.mit.edu>
Cc: "Jorge Boncompte [DTI2]" <jorge@dti2.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/802/garp.c

index 8456f5d98b853b24607d8168aee1b7d9aa9fdac8..5d9630a0eb93b75604f49f3c9de84ad7a417de03 100644 (file)
@@ -609,8 +609,12 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl
        /* Delete timer and generate a final TRANSMIT_PDU event to flush out
         * all pending messages before the applicant is gone. */
        del_timer_sync(&app->join_timer);
+
+       spin_lock_bh(&app->lock);
        garp_gid_event(app, GARP_EVENT_TRANSMIT_PDU);
        garp_pdu_queue(app);
+       spin_unlock_bh(&app->lock);
+
        garp_queue_xmit(app);
 
        dev_mc_del(dev, appl->proto.group_address);