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

Commit 14afee4b authored by Reshetova, Elena's avatar Reshetova, Elena Committed by David S. Miller
Browse files

net: convert sock.sk_wmem_alloc from atomic_t to refcount_t



refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.

Signed-off-by: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarDavid Windsor <dwindsor@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2638595a
Loading
Loading
Loading
Loading
+1 −11
Original line number Diff line number Diff line
@@ -924,12 +924,7 @@ fore200e_tx_irq(struct fore200e* fore200e)
		else {
		    dev_kfree_skb_any(entry->skb);
		}
#if 1
		/* race fixed by the above incarnation mechanism, but... */
		if (atomic_read(&sk_atm(vcc)->sk_wmem_alloc) < 0) {
		    atomic_set(&sk_atm(vcc)->sk_wmem_alloc, 0);
		}
#endif

		/* check error condition */
		if (*entry->status & STATUS_ERROR)
		    atomic_inc(&vcc->stats->tx_err);
@@ -1130,13 +1125,9 @@ fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rp
	return -ENOMEM;
    }

    ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);

    vcc->push(vcc, skb);
    atomic_inc(&vcc->stats->rx);

    ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);

    return 0;
}

@@ -1572,7 +1563,6 @@ fore200e_send(struct atm_vcc *vcc, struct sk_buff *skb)
    unsigned long           flags;

    ASSERT(vcc);
    ASSERT(atomic_read(&sk_atm(vcc)->sk_wmem_alloc) >= 0);
    ASSERT(fore200e);
    ASSERT(fore200e_vcc);

+1 −1
Original line number Diff line number Diff line
@@ -2395,7 +2395,7 @@ he_close(struct atm_vcc *vcc)
		 * TBRQ, the host issues the close command to the adapter.
		 */

		while (((tx_inuse = atomic_read(&sk_atm(vcc)->sk_wmem_alloc)) > 1) &&
		while (((tx_inuse = refcount_read(&sk_atm(vcc)->sk_wmem_alloc)) > 1) &&
		       (retry < MAX_RETRY)) {
			msleep(sleep);
			if (sleep < 250)
+2 −2
Original line number Diff line number Diff line
@@ -724,7 +724,7 @@ push_on_scq(struct idt77252_dev *card, struct vc_map *vc, struct sk_buff *skb)
		struct sock *sk = sk_atm(vcc);

		vc->estimator->cells += (skb->len + 47) / 48;
		if (atomic_read(&sk->sk_wmem_alloc) >
		if (refcount_read(&sk->sk_wmem_alloc) >
		    (sk->sk_sndbuf >> 1)) {
			u32 cps = vc->estimator->maxcps;

@@ -2009,7 +2009,7 @@ idt77252_send_oam(struct atm_vcc *vcc, void *cell, int flags)
		atomic_inc(&vcc->stats->tx_err);
		return -ENOMEM;
	}
	atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
	refcount_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);

	skb_put_data(skb, cell, 52);

+1 −1
Original line number Diff line number Diff line
@@ -254,7 +254,7 @@ static inline void atm_return(struct atm_vcc *vcc,int truesize)

static inline int atm_may_send(struct atm_vcc *vcc,unsigned int size)
{
	return (size + atomic_read(&sk_atm(vcc)->sk_wmem_alloc)) <
	return (size + refcount_read(&sk_atm(vcc)->sk_wmem_alloc)) <
	       sk_atm(vcc)->sk_sndbuf;
}

+4 −4
Original line number Diff line number Diff line
@@ -390,7 +390,7 @@ struct sock {

	/* ===== cache line for TX ===== */
	int			sk_wmem_queued;
	atomic_t		sk_wmem_alloc;
	refcount_t		sk_wmem_alloc;
	unsigned long		sk_tsq_flags;
	struct sk_buff		*sk_send_head;
	struct sk_buff_head	sk_write_queue;
@@ -1911,7 +1911,7 @@ static inline int skb_copy_to_page_nocache(struct sock *sk, struct iov_iter *fro
 */
static inline int sk_wmem_alloc_get(const struct sock *sk)
{
	return atomic_read(&sk->sk_wmem_alloc) - 1;
	return refcount_read(&sk->sk_wmem_alloc) - 1;
}

/**
@@ -2055,7 +2055,7 @@ static inline unsigned long sock_wspace(struct sock *sk)
	int amt = 0;

	if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
		amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
		amt = sk->sk_sndbuf - refcount_read(&sk->sk_wmem_alloc);
		if (amt < 0)
			amt = 0;
	}
@@ -2136,7 +2136,7 @@ bool sk_page_frag_refill(struct sock *sk, struct page_frag *pfrag);
 */
static inline bool sock_writeable(const struct sock *sk)
{
	return atomic_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf >> 1);
	return refcount_read(&sk->sk_wmem_alloc) < (sk->sk_sndbuf >> 1);
}

static inline gfp_t gfp_any(void)
Loading