diff options
Diffstat (limited to 'net/core/timestamping.c')
-rw-r--r-- | net/core/timestamping.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 98a52640e7cd..661b5a40ec10 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/phy.h> | 21 | #include <linux/phy.h> |
22 | #include <linux/ptp_classify.h> | 22 | #include <linux/ptp_classify.h> |
23 | #include <linux/skbuff.h> | 23 | #include <linux/skbuff.h> |
24 | #include <linux/export.h> | ||
24 | 25 | ||
25 | static struct sock_filter ptp_filter[] = { | 26 | static struct sock_filter ptp_filter[] = { |
26 | PTP_FILTER | 27 | PTP_FILTER |
@@ -57,9 +58,13 @@ void skb_clone_tx_timestamp(struct sk_buff *skb) | |||
57 | case PTP_CLASS_V2_VLAN: | 58 | case PTP_CLASS_V2_VLAN: |
58 | phydev = skb->dev->phydev; | 59 | phydev = skb->dev->phydev; |
59 | if (likely(phydev->drv->txtstamp)) { | 60 | if (likely(phydev->drv->txtstamp)) { |
61 | if (!atomic_inc_not_zero(&sk->sk_refcnt)) | ||
62 | return; | ||
60 | clone = skb_clone(skb, GFP_ATOMIC); | 63 | clone = skb_clone(skb, GFP_ATOMIC); |
61 | if (!clone) | 64 | if (!clone) { |
65 | sock_put(sk); | ||
62 | return; | 66 | return; |
67 | } | ||
63 | clone->sk = sk; | 68 | clone->sk = sk; |
64 | phydev->drv->txtstamp(phydev, clone, type); | 69 | phydev->drv->txtstamp(phydev, clone, type); |
65 | } | 70 | } |
@@ -77,8 +82,11 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
77 | struct sock_exterr_skb *serr; | 82 | struct sock_exterr_skb *serr; |
78 | int err; | 83 | int err; |
79 | 84 | ||
80 | if (!hwtstamps) | 85 | if (!hwtstamps) { |
86 | sock_put(sk); | ||
87 | kfree_skb(skb); | ||
81 | return; | 88 | return; |
89 | } | ||
82 | 90 | ||
83 | *skb_hwtstamps(skb) = *hwtstamps; | 91 | *skb_hwtstamps(skb) = *hwtstamps; |
84 | serr = SKB_EXT_ERR(skb); | 92 | serr = SKB_EXT_ERR(skb); |
@@ -87,6 +95,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
87 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; | 95 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; |
88 | skb->sk = NULL; | 96 | skb->sk = NULL; |
89 | err = sock_queue_err_skb(sk, skb); | 97 | err = sock_queue_err_skb(sk, skb); |
98 | sock_put(sk); | ||
90 | if (err) | 99 | if (err) |
91 | kfree_skb(skb); | 100 | kfree_skb(skb); |
92 | } | 101 | } |