net: convert sk_buff.users 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>
This commit is contained in:

committed by
David S. Miller

parent
53869cebce
commit
633547973f
@@ -27,7 +27,7 @@ void rxrpc_new_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
|
||||
{
|
||||
const void *here = __builtin_return_address(0);
|
||||
int n = atomic_inc_return(select_skb_count(op));
|
||||
trace_rxrpc_skb(skb, op, atomic_read(&skb->users), n, here);
|
||||
trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -38,7 +38,7 @@ void rxrpc_see_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
|
||||
const void *here = __builtin_return_address(0);
|
||||
if (skb) {
|
||||
int n = atomic_read(select_skb_count(op));
|
||||
trace_rxrpc_skb(skb, op, atomic_read(&skb->users), n, here);
|
||||
trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ void rxrpc_get_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
|
||||
{
|
||||
const void *here = __builtin_return_address(0);
|
||||
int n = atomic_inc_return(select_skb_count(op));
|
||||
trace_rxrpc_skb(skb, op, atomic_read(&skb->users), n, here);
|
||||
trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here);
|
||||
skb_get(skb);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ void rxrpc_free_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
|
||||
int n;
|
||||
CHECK_SLAB_OKAY(&skb->users);
|
||||
n = atomic_dec_return(select_skb_count(op));
|
||||
trace_rxrpc_skb(skb, op, atomic_read(&skb->users), n, here);
|
||||
trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@ void rxrpc_lose_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
|
||||
int n;
|
||||
CHECK_SLAB_OKAY(&skb->users);
|
||||
n = atomic_dec_return(select_skb_count(op));
|
||||
trace_rxrpc_skb(skb, op, atomic_read(&skb->users), n, here);
|
||||
trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ void rxrpc_purge_queue(struct sk_buff_head *list)
|
||||
while ((skb = skb_dequeue((list))) != NULL) {
|
||||
int n = atomic_dec_return(select_skb_count(rxrpc_skb_rx_purged));
|
||||
trace_rxrpc_skb(skb, rxrpc_skb_rx_purged,
|
||||
atomic_read(&skb->users), n, here);
|
||||
refcount_read(&skb->users), n, here);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user