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: Elena Reshetova <elena.reshetova@intel.com> Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: David Windsor <dwindsor@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Este cometimento está contido em:

cometido por
David S. Miller

ascendente
2638595afc
cometimento
14afee4b60
@@ -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);
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
|
||||
|
Criar uma nova questão referindo esta
Bloquear um utilizador