Tommy Christensen <tommy.christensen@xxxxxxxxx> wrote:
>
> netlink has messed up the send buffer accounting, when trimming a skb.
You are spot on. Dave, you were right too about checking for charged
skb's in netlink_trim.
Since the skb will be orphaned on its way to the destination anyway,
let's simply do that before the trimming. This shouldn't lead to
skb leakage since the skb will either be charged to the destination
socket or freed.
Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Simon, please check if this fixes your problem or not.
Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
===== net/netlink/af_netlink.c 1.66 vs edited =====
--- 1.66/net/netlink/af_netlink.c 2005-01-14 15:41:06 +11:00
+++ edited/net/netlink/af_netlink.c 2005-01-16 00:24:20 +11:00
@@ -629,7 +629,6 @@
}
return 1;
}
- skb_orphan(skb);
skb_set_owner_r(skb, sk);
return 0;
}
@@ -663,14 +662,11 @@
static inline void netlink_trim(struct sk_buff *skb, int allocation)
{
- int delta = skb->end - skb->tail;
+ int delta;
- /* If the packet is charged to a socket, the modification
- * of truesize below is illegal and will corrupt socket
- * buffer accounting state.
- */
- BUG_ON(skb->list != NULL);
+ skb_orphan(skb);
+ delta = skb->end - skb->tail;
if (delta * 2 < skb->truesize)
return;
if (pskb_expand_head(skb, 0, -delta, allocation))
@@ -707,14 +703,12 @@
struct netlink_opt *nlk = nlk_sk(sk);
#ifdef NL_EMULATE_DEV
if (nlk->handler) {
- skb_orphan(skb);
nlk->handler(sk->sk_protocol, skb);
return 0;
} else
#endif
if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf &&
!test_bit(0, &nlk->state)) {
- skb_orphan(skb);
skb_set_owner_r(skb, sk);
skb_queue_tail(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk, skb->len);
|