ftrace: tracepoint of net_dev_xmit sees freed skb and causes panic
Subsystems (3)
PATCH 1/1 ftrace: 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)
--- include/trace/events/net.h | 12 +++++++----- net/core/dev.c | 7 +++++-- 2 files changed, 12 insertions(+), 7 deletions(-)
include/trace/events/net.h +7 -5
@@ -12,22 +12,24 @@ TRACE_EVENT(net_dev_xmit, TP_PROTO(struct sk_buff *skb, - int rc), + int rc, + struct net_device *dev, + unsigned int skb_len), - TP_ARGS(skb, rc), + TP_ARGS(skb, rc, dev, skb_len), TP_STRUCT__entry( __field( void *, skbaddr ) __field( unsigned int, len ) __field( int, rc ) - __string( name, skb->dev->name ) + __string( name, dev->name ) ), TP_fast_assign( __entry->skbaddr = skb; - __entry->len = skb->len; + __entry->len = skb_len; __entry->rc = rc; - __assign_str(name, skb->dev->name); + __assign_str(name, dev->name); ), TP_printk("dev=%s skbaddr=%p len=%u rc=%d",
net/core/dev.c +5 -2
@@ -2089,6 +2089,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, {const struct net_device_ops *ops = dev->netdev_ops;int rc =NETDEV_TX_OK ; +unsigned int skb_len;if (likely (!skb->next)) {u32 features;
@@ -2139,8 +2140,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, } } + skb_len = skb->len; rc = ops->ndo_start_xmit (skb, dev); -trace_net_dev_xmit (skb, rc); +trace_net_dev_xmit (skb, rc, dev, skb_len);if (rc ==NETDEV_TX_OK )txq_trans_update (txq);return rc;
@@ -2160,8 +2162,9 @@ gso:if (dev->priv_flags &IFF_XMIT_DST_RELEASE )skb_dst_drop (nskb); + skb_len = nskb->len; rc = ops->ndo_start_xmit (nskb, dev); -trace_net_dev_xmit (nskb, rc); +trace_net_dev_xmit (nskb, rc, dev, skb_len);if (unlikely (rc !=NETDEV_TX_OK )) {if (rc & ~NETDEV_TX_MASK ) goto out_kfree_gso_skb;
Steven Rostedt
maintainerQuoted 22 lines · Koki Sanagi
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 likeskb->lenandskb->dev->nameafterndo_start_xmit. Buttrace_net_dev_xmitdoes that and causes panic by NULL pointer dereference.
This patch fixestrace_net_dev_xmitnot to see the contents of skb directly.net/core/dev.c +2
-1if (likely (!skb->next)) {u32 features;@@ -2139,8 +2140,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, } } + skb_len = skb->len; rc = ops->ndo_start_xmit (skb, dev); -trace_net_dev_xmit (skb, rc); +trace_net_dev_xmit (skb, rc, dev, skb_len);if (rc ==NETDEV_TX_OK )txq_trans_update (txq);return rc;
net/core/dev.c gso: · line 2167
Quoted 7 lines
net/core/dev.c +2
-1@@ -2160,8 +2162,9 @@ gso:if (dev->priv_flags &IFF_XMIT_DST_RELEASE )skb_dst_drop (nskb); + skb_len = nskb->len; rc = ops->ndo_start_xmit (nskb, dev); -trace_net_dev_xmit (nskb, rc); +trace_net_dev_xmit (nskb, rc, dev, skb_len);
What if you just put the tracepoint before the call to ops->ndo_start_xmit?
-- Steve
Quoted 3 lines
net/core/dev.c +0
-0if (unlikely (rc !=NETDEV_TX_OK )) {if (rc & ~NETDEV_TX_MASK ) goto out_kfree_gso_skb;
Quoted 26 lines · Steven Rostedt
Quoted 25 lines · Koki Sanagi
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 likeskb->lenandskb->dev->nameafterndo_start_xmit. Buttrace_net_dev_xmitdoes that and causes panic by NULL pointer dereference.
This patch fixestrace_net_dev_xmitnot to see the contents of skb directly.net/core/dev.c +2
-1if (likely (!skb->next)) {u32 features;@@ -2139,8 +2140,9 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, } } + skb_len = skb->len; rc = ops->ndo_start_xmit (skb, dev); -trace_net_dev_xmit (skb, rc); +trace_net_dev_xmit (skb, rc, dev, skb_len);if (rc ==NETDEV_TX_OK )txq_trans_update (txq);return rc;@@ -2160,8 +2162,9 @@ gso:if (dev->priv_flags &IFF_XMIT_DST_RELEASE )skb_dst_drop (nskb);
Quoted 8 lines
net/core/dev.c gso: · line 2167
Quoted 4 lines
net/core/dev.c +2
-1+ skb_len = nskb->len; rc = ops->ndo_start_xmit (nskb, dev); -trace_net_dev_xmit (nskb, rc); +trace_net_dev_xmit (nskb, rc, dev, skb_len);What if you just put the tracepoint before the call to
ops->ndo_start_xmit?
Then you won't know the return code of ndo_start_xmit, which this tracepoint records.
Neil
Quoted 8 lines
-- Steve
Quoted 3 lines
net/core/dev.c +0
-0if (unlikely (rc !=NETDEV_TX_OK )) {if (rc & ~NETDEV_TX_MASK ) goto out_kfree_gso_skb;
Steven Rostedt
maintainerQuoted 10 lines · Neil Horman
skb_dst_drop(nskb);Quoted 9 lines
net/core/dev.c gso: · line 2167
Quoted 5 lines
net/core/dev.c +2
-1+ skb_len = nskb->len; rc = ops->ndo_start_xmit (nskb, dev); -trace_net_dev_xmit (nskb, rc); +trace_net_dev_xmit (nskb, rc, dev, skb_len);What if you just put the tracepoint before the call to
ops->ndo_start_xmit?
Quoted 2 lines
Then you won't know the return code of
ndo_start_xmit, which this tracepoint records.
Doh! Yeah, I see that now ;)
-- Steve
Steven Rostedt
maintainerNote, the subject should not be "ftrace:", but "net:" or maybe even "net/tracing", as this really has nothing to do with ftrace code. The tracepoints are more generic than ftrace.
-- Steve
David Miller
maintainerFrom: Steven Rostedt <[email protected]>
Date: Tue, 31 May 2011 11:14:27 -0400
Quoted 3 lines
Note, the subject should not be "ftrace:", but "net:" or maybe even "net/tracing", as this really has nothing to do with ftrace code. The tracepoints are more generic than ftrace.
Do you guys mind if I take this in via the net-2.6 tree?
Steven Rostedt
maintainerQuoted 8 lines · David Miller
From: Steven Rostedt <[email protected]>
Date: Tue, 31 May 2011 11:14:27 -0400Quoted 3 lines
Note, the subject should not be "ftrace:", but "net:" or maybe even "net/tracing", as this really has nothing to do with ftrace code. The tracepoints are more generic than ftrace.
Do you guys mind if I take this in via the net-2.6 tree?
I have no issue with that. Heck, I prefer it.
-- Steve
David Miller
maintainerFrom: Steven Rostedt <[email protected]>
Date: Thu, 02 Jun 2011 17:01:52 -0400
Quoted 11 lines · David Miller
Quoted 8 lines
From: Steven Rostedt <[email protected]>
Date: Tue, 31 May 2011 11:14:27 -0400Quoted 3 lines
Note, the subject should not be "ftrace:", but "net:" or maybe even "net/tracing", as this really has nothing to do with ftrace code. The tracepoints are more generic than ftrace.
Do you guys mind if I take this in via the net-2.6 tree?
I have no issue with that. Heck, I prefer it.
Great, thanks!
Quoted 11 lines · David Miller
From: Steven Rostedt <[email protected]>
Date: Thu, 02 Jun 2011 17:01:52 -0400Quoted 8 lines · David Miller
Quoted 7 lines
From: Steven Rostedt <[email protected]>
Date: Tue, 31 May 2011 11:14:27 -0400Quoted 3 lines
Note, the subject should not be "ftrace:", but "net:" or maybe even "net/tracing", as this really has nothing to do with ftrace code. The tracepoints are more generic than ftrace.
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
Do you guys mind if I take this in via the net-2.6 tree?
I have no issue with that. Heck, I prefer it.
Great, thanks!
O.K.
I will resubmit this patch with appropriate subject "net/tracing:"
Thanks,
Koki Sanagi
David Miller
maintainerFrom: Koki Sanagi <[email protected]>
Date: Fri, 03 Jun 2011 14:03:51 +0900
Quoted 1 line
I will resubmit this patch with appropriate subject "net/tracing:"
You don't need to, I fixed it up when I applied your patch.
Quoted 7 lines · David Miller
From: Koki Sanagi <[email protected]>
Date: Fri, 03 Jun 2011 14:03:51 +0900Quoted 1 line
I will resubmit this patch with appropriate subject "net/tracing:"
You don't need to, I fixed it up when I applied your patch.
O.K.
Thanks!
Koki Sanagi