diff options
| author | Koki Sanagi <sanagi.koki@jp.fujitsu.com> | 2011-05-30 17:48:34 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-06-02 17:06:31 -0400 |
| commit | ec764bf083a6ff396234351b51fd236f53c903bf (patch) | |
| tree | 30c0f8232fe10c76651114dea999b93fa2c8ade5 /include/trace | |
| parent | 2e4ceec4edaef6e903422792de4f7f37de98cec6 (diff) | |
net: tracepoint of net_dev_xmit sees freed skb and causes panic
Because there is a possibility that skb is kfree_skb()ed and zero cleared
after ndo_start_xmit, we should not see the contents of skb like skb->len and
skb->dev->name after ndo_start_xmit. But trace_net_dev_xmit does that
and causes panic by NULL pointer dereference.
This patch fixes trace_net_dev_xmit not to see the contents of skb directly.
If you want to reproduce this panic,
1. Get tracepoint of net_dev_xmit on
2. Create 2 guests on KVM
2. Make 2 guests use virtio_net
4. Execute netperf from one to another for a long time as a network burden
5. host will panic(It takes about 30 minutes)
Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/trace')
| -rw-r--r-- | include/trace/events/net.h | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/include/trace/events/net.h b/include/trace/events/net.h index 5f247f5ffc56..f99645d05a8f 100644 --- a/include/trace/events/net.h +++ b/include/trace/events/net.h | |||
| @@ -12,22 +12,24 @@ | |||
| 12 | TRACE_EVENT(net_dev_xmit, | 12 | TRACE_EVENT(net_dev_xmit, |
| 13 | 13 | ||
| 14 | TP_PROTO(struct sk_buff *skb, | 14 | TP_PROTO(struct sk_buff *skb, |
| 15 | int rc), | 15 | int rc, |
| 16 | struct net_device *dev, | ||
| 17 | unsigned int skb_len), | ||
| 16 | 18 | ||
| 17 | TP_ARGS(skb, rc), | 19 | TP_ARGS(skb, rc, dev, skb_len), |
| 18 | 20 | ||
| 19 | TP_STRUCT__entry( | 21 | TP_STRUCT__entry( |
| 20 | __field( void *, skbaddr ) | 22 | __field( void *, skbaddr ) |
| 21 | __field( unsigned int, len ) | 23 | __field( unsigned int, len ) |
| 22 | __field( int, rc ) | 24 | __field( int, rc ) |
| 23 | __string( name, skb->dev->name ) | 25 | __string( name, dev->name ) |
| 24 | ), | 26 | ), |
| 25 | 27 | ||
| 26 | TP_fast_assign( | 28 | TP_fast_assign( |
| 27 | __entry->skbaddr = skb; | 29 | __entry->skbaddr = skb; |
| 28 | __entry->len = skb->len; | 30 | __entry->len = skb_len; |
| 29 | __entry->rc = rc; | 31 | __entry->rc = rc; |
| 30 | __assign_str(name, skb->dev->name); | 32 | __assign_str(name, dev->name); |
| 31 | ), | 33 | ), |
| 32 | 34 | ||
| 33 | TP_printk("dev=%s skbaddr=%p len=%u rc=%d", | 35 | TP_printk("dev=%s skbaddr=%p len=%u rc=%d", |
