net: make skb_set_owner_w() more robust
skb_set_owner_w() is called from various places that assume
skb->sk always point to a full blown socket (as it changes
sk->sk_wmem_alloc)
We'd like to attach skb to request sockets, and in the future
to timewait sockets as well. For these kind of pseudo sockets,
we need to take a traditional refcount and use sock_edemux()
as the destructor.
It is now time to un-inline skb_set_owner_w(), being too big.
Fixes: ca6fb06518
("tcp: attach SYNACK messages to request sockets instead of listener")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Bisected-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
eca1e006cf
commit
9e17f8a475
@@ -1656,6 +1656,28 @@ void sock_wfree(struct sk_buff *skb)
|
||||
}
|
||||
EXPORT_SYMBOL(sock_wfree);
|
||||
|
||||
void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
|
||||
{
|
||||
skb_orphan(skb);
|
||||
skb->sk = sk;
|
||||
#ifdef CONFIG_INET
|
||||
if (unlikely(!sk_fullsock(sk))) {
|
||||
skb->destructor = sock_edemux;
|
||||
sock_hold(sk);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
skb->destructor = sock_wfree;
|
||||
skb_set_hash_from_sk(skb, sk);
|
||||
/*
|
||||
* We used to take a refcount on sk, but following operation
|
||||
* is enough to guarantee sk_free() wont free this sock until
|
||||
* all in-flight packets are completed
|
||||
*/
|
||||
atomic_add(skb->truesize, &sk->sk_wmem_alloc);
|
||||
}
|
||||
EXPORT_SYMBOL(skb_set_owner_w);
|
||||
|
||||
void skb_orphan_partial(struct sk_buff *skb)
|
||||
{
|
||||
/* TCP stack sets skb->ooo_okay based on sk_wmem_alloc,
|
||||
|
Reference in New Issue
Block a user