diff options
author | Cong Wang <amwang@redhat.com> | 2013-04-02 17:52:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-07 17:04:17 -0400 |
commit | cfbe800b8b771afc7d5aa113e19f85ec933b7618 (patch) | |
tree | 153b62e924d6a9982788f294590d0e78d7e53d08 /net/802/garp.c | |
parent | 23a9544206dd91dfe048fcf67abec3f3104c42b9 (diff) |
802: fix a possible race condition
(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>
Diffstat (limited to 'net/802/garp.c')
-rw-r--r-- | net/802/garp.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/net/802/garp.c b/net/802/garp.c index 8456f5d98b85..5d9630a0eb93 100644 --- a/net/802/garp.c +++ b/net/802/garp.c | |||
@@ -609,8 +609,12 @@ void garp_uninit_applicant(struct net_device *dev, struct garp_application *appl | |||
609 | /* Delete timer and generate a final TRANSMIT_PDU event to flush out | 609 | /* Delete timer and generate a final TRANSMIT_PDU event to flush out |
610 | * all pending messages before the applicant is gone. */ | 610 | * all pending messages before the applicant is gone. */ |
611 | del_timer_sync(&app->join_timer); | 611 | del_timer_sync(&app->join_timer); |
612 | |||
613 | spin_lock_bh(&app->lock); | ||
612 | garp_gid_event(app, GARP_EVENT_TRANSMIT_PDU); | 614 | garp_gid_event(app, GARP_EVENT_TRANSMIT_PDU); |
613 | garp_pdu_queue(app); | 615 | garp_pdu_queue(app); |
616 | spin_unlock_bh(&app->lock); | ||
617 | |||
614 | garp_queue_xmit(app); | 618 | garp_queue_xmit(app); |
615 | 619 | ||
616 | dev_mc_del(dev, appl->proto.group_address); | 620 | dev_mc_del(dev, appl->proto.group_address); |