Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36341de2 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-driver-refcont_t'



Elena Reshetova says:

====================
networking drivers refcount_t conversions

Note: these are the last patches related to networking that perform
conversion of refcounters from atomic_t to refcount_t.
In contrast to the core network refcounter conversions that
were merged earlier, these are much more straightforward ones.

This series, for various networking drivers, replaces atomic_t reference
counters with the new refcount_t type and API (see include/linux/refcount.h).
By doing this we prevent intentional or accidental
underflows or overflows that can led to use-after-free vulnerabilities.

The patches are fully independent and can be cherry-picked separately.
Patches are based on top of net-next.
If there are no objections to the patches, please merge them via respective trees
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 86f540c1 e65f7ee3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name,
		return NULL;
	}

	atomic_set(&cbq->refcnt, 1);
	refcount_set(&cbq->refcnt, 1);

	atomic_inc(&dev->refcnt);
	cbq->pdev = dev;
@@ -58,7 +58,7 @@ cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name,

void cn_queue_release_callback(struct cn_callback_entry *cbq)
{
	if (!atomic_dec_and_test(&cbq->refcnt))
	if (!refcount_dec_and_test(&cbq->refcnt))
		return;

	atomic_dec(&cbq->pdev->refcnt);
+1 −1
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ static int cn_call_callback(struct sk_buff *skb)
	spin_lock_bh(&dev->cbdev->queue_lock);
	list_for_each_entry(i, &dev->cbdev->queue_list, callback_entry) {
		if (cn_cb_equal(&i->id.id, &msg->id)) {
			atomic_inc(&i->refcnt);
			refcount_inc(&i->refcnt);
			cbq = i;
			break;
		}
+6 −7
Original line number Diff line number Diff line
@@ -96,7 +96,8 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6)
		if (!ret) {
			ce = cte;
			read_unlock_bh(&ctbl->lock);
			goto found;
			refcount_inc(&ce->refcnt);
			return 0;
		}
	}
	read_unlock_bh(&ctbl->lock);
@@ -108,7 +109,7 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6)
		list_del(&ce->list);
		INIT_LIST_HEAD(&ce->list);
		spin_lock_init(&ce->lock);
		atomic_set(&ce->refcnt, 0);
		refcount_set(&ce->refcnt, 0);
		atomic_dec(&ctbl->nfree);
		list_add_tail(&ce->list, &ctbl->hash_list[hash]);
		if (v6) {
@@ -138,9 +139,7 @@ int cxgb4_clip_get(const struct net_device *dev, const u32 *lip, u8 v6)
		return -ENOMEM;
	}
	write_unlock_bh(&ctbl->lock);
found:
	atomic_inc(&ce->refcnt);

	refcount_set(&ce->refcnt, 1);
	return 0;
}
EXPORT_SYMBOL(cxgb4_clip_get);
@@ -179,7 +178,7 @@ void cxgb4_clip_release(const struct net_device *dev, const u32 *lip, u8 v6)
found:
	write_lock_bh(&ctbl->lock);
	spin_lock_bh(&ce->lock);
	if (atomic_dec_and_test(&ce->refcnt)) {
	if (refcount_dec_and_test(&ce->refcnt)) {
		list_del(&ce->list);
		INIT_LIST_HEAD(&ce->list);
		list_add_tail(&ce->list, &ctbl->ce_free_head);
@@ -266,7 +265,7 @@ int clip_tbl_show(struct seq_file *seq, void *v)
			ip[0] = '\0';
			sprintf(ip, "%pISc", &ce->addr);
			seq_printf(seq, "%-25s   %u\n", ip,
				   atomic_read(&ce->refcnt));
				   refcount_read(&ce->refcnt));
		}
	}
	seq_printf(seq, "Free clip entries : %d\n", atomic_read(&ctbl->nfree));
+3 −1
Original line number Diff line number Diff line
@@ -10,9 +10,11 @@
 *  release for licensing terms and conditions.
 */

#include <linux/refcount.h>

struct clip_entry {
	spinlock_t lock;	/* Hold while modifying clip reference */
	atomic_t refcnt;
	refcount_t refcnt;
	struct list_head list;
	union {
		struct sockaddr_in addr;
+5 −3
Original line number Diff line number Diff line
@@ -1817,7 +1817,7 @@ static int mtk_open(struct net_device *dev)
	struct mtk_eth *eth = mac->hw;

	/* we run 2 netdevs on the same dma ring so we only bring it up once */
	if (!atomic_read(&eth->dma_refcnt)) {
	if (!refcount_read(&eth->dma_refcnt)) {
		int err = mtk_start_dma(eth);

		if (err)
@@ -1827,8 +1827,10 @@ static int mtk_open(struct net_device *dev)
		napi_enable(&eth->rx_napi);
		mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
		mtk_rx_irq_enable(eth, MTK_RX_DONE_INT);
		refcount_set(&eth->dma_refcnt, 1);
	}
	atomic_inc(&eth->dma_refcnt);
	else
		refcount_inc(&eth->dma_refcnt);

	phy_start(dev->phydev);
	netif_start_queue(dev);
@@ -1868,7 +1870,7 @@ static int mtk_stop(struct net_device *dev)
	phy_stop(dev->phydev);

	/* only shutdown DMA if this is the last user */
	if (!atomic_dec_and_test(&eth->dma_refcnt))
	if (!refcount_dec_and_test(&eth->dma_refcnt))
		return 0;

	mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
Loading