diff options
Diffstat (limited to 'net/core/timestamping.c')
-rw-r--r-- | net/core/timestamping.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 98a52640e7cd..82fb28857b64 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c | |||
@@ -57,9 +57,13 @@ void skb_clone_tx_timestamp(struct sk_buff *skb) | |||
57 | case PTP_CLASS_V2_VLAN: | 57 | case PTP_CLASS_V2_VLAN: |
58 | phydev = skb->dev->phydev; | 58 | phydev = skb->dev->phydev; |
59 | if (likely(phydev->drv->txtstamp)) { | 59 | if (likely(phydev->drv->txtstamp)) { |
60 | if (!atomic_inc_not_zero(&sk->sk_refcnt)) | ||
61 | return; | ||
60 | clone = skb_clone(skb, GFP_ATOMIC); | 62 | clone = skb_clone(skb, GFP_ATOMIC); |
61 | if (!clone) | 63 | if (!clone) { |
64 | sock_put(sk); | ||
62 | return; | 65 | return; |
66 | } | ||
63 | clone->sk = sk; | 67 | clone->sk = sk; |
64 | phydev->drv->txtstamp(phydev, clone, type); | 68 | phydev->drv->txtstamp(phydev, clone, type); |
65 | } | 69 | } |
@@ -77,8 +81,11 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
77 | struct sock_exterr_skb *serr; | 81 | struct sock_exterr_skb *serr; |
78 | int err; | 82 | int err; |
79 | 83 | ||
80 | if (!hwtstamps) | 84 | if (!hwtstamps) { |
85 | sock_put(sk); | ||
86 | kfree_skb(skb); | ||
81 | return; | 87 | return; |
88 | } | ||
82 | 89 | ||
83 | *skb_hwtstamps(skb) = *hwtstamps; | 90 | *skb_hwtstamps(skb) = *hwtstamps; |
84 | serr = SKB_EXT_ERR(skb); | 91 | serr = SKB_EXT_ERR(skb); |
@@ -87,6 +94,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
87 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; | 94 | serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; |
88 | skb->sk = NULL; | 95 | skb->sk = NULL; |
89 | err = sock_queue_err_skb(sk, skb); | 96 | err = sock_queue_err_skb(sk, skb); |
97 | sock_put(sk); | ||
90 | if (err) | 98 | if (err) |
91 | kfree_skb(skb); | 99 | kfree_skb(skb); |
92 | } | 100 | } |