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
@@ -1951,6 +1951,8 @@ static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk)
|
||||
}
|
||||
}
|
||||
|
||||
void skb_set_owner_w(struct sk_buff *skb, struct sock *sk);
|
||||
|
||||
/*
|
||||
* Queue a received datagram if it will fit. Stream and sequenced
|
||||
* protocols can't normally use this as they need to fit buffers in
|
||||
@@ -1959,21 +1961,6 @@ static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk)
|
||||
* Inlined as it's very short and called for pretty much every
|
||||
* packet ever received.
|
||||
*/
|
||||
|
||||
static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
|
||||
{
|
||||
skb_orphan(skb);
|
||||
skb->sk = sk;
|
||||
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);
|
||||
}
|
||||
|
||||
static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
|
||||
{
|
||||
skb_orphan(skb);
|
||||
|
||||
Reference in New Issue
Block a user