net: sk_prot_alloc() should not blindly overwrite memory
Some sockets use SLAB_DESTROY_BY_RCU, and our RCU code correctness depends on sk->sk_nulls_node.next being always valid. A NULL value is not allowed as it might fault a lockless reader. Current sk_prot_alloc() implementation doesnt respect this hypothesis, calling kmem_cache_alloc() with __GFP_ZERO. Just call memset() around the forbidden field. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e594e96e8a
commit
e912b1142b
1 changed files with 17 additions and 2 deletions
|
@ -939,8 +939,23 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority,
|
|||
struct kmem_cache *slab;
|
||||
|
||||
slab = prot->slab;
|
||||
if (slab != NULL)
|
||||
sk = kmem_cache_alloc(slab, priority);
|
||||
if (slab != NULL) {
|
||||
sk = kmem_cache_alloc(slab, priority & ~__GFP_ZERO);
|
||||
if (!sk)
|
||||
return sk;
|
||||
if (priority & __GFP_ZERO) {
|
||||
/*
|
||||
* caches using SLAB_DESTROY_BY_RCU should let
|
||||
* sk_node.next un-modified. Special care is taken
|
||||
* when initializing object to zero.
|
||||
*/
|
||||
if (offsetof(struct sock, sk_node.next) != 0)
|
||||
memset(sk, 0, offsetof(struct sock, sk_node.next));
|
||||
memset(&sk->sk_node.pprev, 0,
|
||||
prot->obj_size - offsetof(struct sock,
|
||||
sk_node.pprev));
|
||||
}
|
||||
}
|
||||
else
|
||||
sk = kmalloc(prot->obj_size, priority);
|
||||
|
||||
|
|
Loading…
Reference in a new issue