Project

General

Profile

Bug #216 » 0001-batman-adv-lock-crc-access-in-bridge-loop-avoidance.patch

Simon Wunderlich, 06/11/2015 06:48 PM

View differences:

bridge_loop_avoidance.c
246 246
	}
247 247

  
248 248
	/* all claims gone, intialize CRC */
249
	spin_lock_bh(&backbone_gw->crc_lock);
249 250
	backbone_gw->crc = BATADV_BLA_CRC_INIT;
251
	spin_unlock_bh(&backbone_gw->crc_lock);
250 252
}
251 253

  
252 254
/**
......
393 395
	entry->lasttime = jiffies;
394 396
	entry->crc = BATADV_BLA_CRC_INIT;
395 397
	entry->bat_priv = bat_priv;
398
	spin_lock_init(&entry->crc_lock);
396 399
	atomic_set(&entry->request_sent, 0);
397 400
	atomic_set(&entry->wait_periods, 0);
398 401
	ether_addr_copy(entry->orig, orig);
......
541 544
	__be16 crc;
542 545

  
543 546
	memcpy(mac, batadv_announce_mac, 4);
547
	spin_lock_bh(&backbone_gw->crc_lock);
544 548
	crc = htons(backbone_gw->crc);
549
	spin_unlock_bh(&backbone_gw->crc_lock);
545 550
	memcpy(&mac[4], &crc, 2);
546 551

  
547 552
	batadv_bla_send_claim(bat_priv, mac, backbone_gw->vid,
......
602 607
			   "bla_add_claim(): changing ownership for %pM, vid %d\n",
603 608
			   mac, BATADV_PRINT_VID(vid));
604 609

  
610
		spin_lock_bh(&claim->backbone_gw->crc_lock);
605 611
		claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
612
		spin_unlock_bh(&claim->backbone_gw->crc_lock);
606 613
		batadv_backbone_gw_free_ref(claim->backbone_gw);
607 614
	}
608 615
	/* set (new) backbone gw */
609 616
	atomic_inc(&backbone_gw->refcount);
610 617
	claim->backbone_gw = backbone_gw;
611 618

  
619
	spin_lock_bh(&backbone_gw->crc_lock);
612 620
	backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
621
	spin_unlock_bh(&backbone_gw->crc_lock);
613 622
	backbone_gw->lasttime = jiffies;
614 623

  
615 624
claim_free_ref:
......
637 646
			   batadv_choose_claim, claim);
638 647
	batadv_claim_free_ref(claim); /* reference from the hash is gone */
639 648

  
649
	spin_lock_bh(&claim->backbone_gw->crc_lock);
640 650
	claim->backbone_gw->crc ^= crc16(0, claim->addr, ETH_ALEN);
651
	spin_unlock_bh(&claim->backbone_gw->crc_lock);
641 652

  
642 653
	/* don't need the reference from hash_find() anymore */
643 654
	batadv_claim_free_ref(claim);
......
649 660
				  unsigned short vid)
650 661
{
651 662
	struct batadv_bla_backbone_gw *backbone_gw;
652
	uint16_t crc;
663
	uint16_t backbone_crc, crc;
653 664

  
654 665
	if (memcmp(an_addr, batadv_announce_mac, 4) != 0)
655 666
		return 0;
......
669 680
		   "handle_announce(): ANNOUNCE vid %d (sent by %pM)... CRC = %#.4x\n",
670 681
		   BATADV_PRINT_VID(vid), backbone_gw->orig, crc);
671 682

  
672
	if (backbone_gw->crc != crc) {
683
	spin_lock_bh(&backbone_gw->crc_lock);
684
	backbone_crc = backbone_gw->crc;
685
	spin_unlock_bh(&backbone_gw->crc_lock);
686

  
687
	if (backbone_crc != crc) {
673 688
		batadv_dbg(BATADV_DBG_BLA, backbone_gw->bat_priv,
674 689
			   "handle_announce(): CRC FAILED for %pM/%d (my = %#.4x, sent = %#.4x)\n",
675 690
			   backbone_gw->orig,
676 691
			   BATADV_PRINT_VID(backbone_gw->vid),
677
			   backbone_gw->crc, crc);
692
			   backbone_crc, crc);
678 693

  
679 694
		batadv_bla_send_request(backbone_gw);
680 695
	} else {
......
1636 1651
	struct batadv_bla_claim *claim;
1637 1652
	struct batadv_hard_iface *primary_if;
1638 1653
	struct hlist_head *head;
1654
	uint16_t backbone_crc;
1639 1655
	uint32_t i;
1640 1656
	bool is_own;
1641 1657
	uint8_t *primary_addr;
......
1658 1674
		hlist_for_each_entry_rcu(claim, head, hash_entry) {
1659 1675
			is_own = batadv_compare_eth(claim->backbone_gw->orig,
1660 1676
						    primary_addr);
1677

  
1678
			spin_lock_bh(&claim->backbone_gw->crc_lock);
1679
			backbone_crc = claim->backbone_gw->crc;
1680
			spin_lock_bh(&claim->backbone_gw->crc_lock);
1661 1681
			seq_printf(seq, " * %pM on %5d by %pM [%c] (%#.4x)\n",
1662 1682
				   claim->addr, BATADV_PRINT_VID(claim->vid),
1663 1683
				   claim->backbone_gw->orig,
1664 1684
				   (is_own ? 'x' : ' '),
1665
				   claim->backbone_gw->crc);
1685
				   backbone_crc);
1666 1686
		}
1667 1687
		rcu_read_unlock();
1668 1688
	}
......
1682 1702
	struct hlist_head *head;
1683 1703
	int secs, msecs;
1684 1704
	uint32_t i;
1705
	uint16_t backbone_crc;
1685 1706
	bool is_own;
1686 1707
	uint8_t *primary_addr;
1687 1708

  
......
1711 1732
			if (is_own)
1712 1733
				continue;
1713 1734

  
1735
			spin_lock_bh(&backbone_gw->crc_lock);
1736
			backbone_crc = backbone_gw->crc;
1737
			spin_unlock_bh(&backbone_gw->crc_lock);
1738

  
1714 1739
			seq_printf(seq, " * %pM on %5d %4i.%03is (%#.4x)\n",
1715 1740
				   backbone_gw->orig,
1716 1741
				   BATADV_PRINT_VID(backbone_gw->vid), secs,
1717
				   msecs, backbone_gw->crc);
1742
				   msecs, backbone_crc);
1718 1743
		}
1719 1744
		rcu_read_unlock();
1720 1745
	}
types.h
868 868
 *  backbone gateway - no bcast traffic is formwared until the situation was
869 869
 *  resolved
870 870
 * @crc: crc16 checksum over all claims
871
 * @crc_lock: lock protecting crc
871 872
 * @refcount: number of contexts the object is used
872 873
 * @rcu: struct used for freeing in an RCU-safe manner
873 874
 */
......
881 882
	atomic_t wait_periods;
882 883
	atomic_t request_sent;
883 884
	uint16_t crc;
885
	spinlock_t crc_lock;
884 886
	atomic_t refcount;
885 887
	struct rcu_head rcu;
886 888
};
887
- 
(3-3/4)