From: Johannes Berg <johannes@xxxxxxxxxxxxxxxx> Date: Thu, 01 May 2008 11:32:29 +0200 > On Thu, 2008-05-01 at 02:20 -0700, David Miller wrote: > > From: Johannes Berg <johannes@xxxxxxxxxxxxxxxx> > > Date: Thu, 01 May 2008 11:08:06 +0200 > > > > > > Seems the skb->destructor messes it up. > > > > > > Actually, it seems to be outside of mac80211, I put in a WARN_ON() and > > > got this: > > > > You're just seeing who freed it last here. > > > > It could have had it's ->truesize put into an illegal state > > elsewhere. > > Yes, I know, but it doesn't come from my skb_orphan() call. Hence, I > just netif_rx() the packet which makes it go onto the input_pkt_queue > and then to netif_receive_skb() which gives it to af_packet and all > others should ignore it since I set PACKET_OTHERHOST. I looked at the mac80211 code, the problem is the skb_push() you guys do in this situation. Things like loopback, which also orphan then reinject, don't trigger this problem because the re-input path trims things, never adds. The good news is that this is easy to fix. Since you've orphaned the SKB, simply adjust skb->truesize as you do pushes. Like this: mac80211: Adjust truesize in ieee80211_tx_status() when reinjecting. Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx> diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 9ad4e36..de2e904 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1485,6 +1485,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, rthdr = (struct ieee80211_tx_status_rtap_hdr*) skb_push(skb, sizeof(*rthdr)); + /* This is safe because the buffer has been orphaned. */ + skb->truesize += sizeof(*rthdr); + memset(rthdr, 0, sizeof(*rthdr)); rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); rthdr->hdr.it_present = ��.n��������+%������w��{.n�����{���zW����ܨ}���Ơz�j:+v�����w����ޙ��&�)ߡ�a����z�ޗ���ݢj��w�f