aboutsummaryrefslogtreecommitdiffstats
path: root/net/dsa
diff options
context:
space:
mode:
authorVladimir Oltean <olteanv@gmail.com>2019-08-04 18:38:47 -0400
committerDavid S. Miller <davem@davemloft.net>2019-08-06 17:37:02 -0400
commitf163fed2764e66511fb5c489bf87e532ad7606fb (patch)
tree9d3a460259bbdfcb8ed6a52af57ccb330fb73a5c /net/dsa
parent6cb0abbdf90c180e1310976c47399f57477e0e53 (diff)
net: dsa: sja1105: Fix memory leak on meta state machine normal path
After a meta frame is received, it is associated with the cached sp->data->stampable_skb from the DSA tagger private structure. Cached means its refcount is incremented with skb_get() in order for dsa_switch_rcv() to not free it when the tagger .rcv returns NULL. The mistake is that skb_unref() is not the correct function to use. It will correctly decrement the refcount (which will go back to zero) but the skb memory will not be freed. That is the job of kfree_skb(), which also calls skb_unref(). But it turns out that freeing the cached stampable_skb is in fact not necessary. It is still a perfectly valid skb, and now it is even annotated with the partial RX timestamp. So remove the skb_copy() altogether and simply pass the stampable_skb with a refcount of 1 (incremented by us, decremented by dsa_switch_rcv) up the stack. Fixes: f3097be21bf1 ("net: dsa: sja1105: Add a state machine for RX timestamping") Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r--net/dsa/tag_sja1105.c11
1 files changed, 1 insertions, 10 deletions
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
index 26363d72d25b..8fa8dda8a15b 100644
--- a/net/dsa/tag_sja1105.c
+++ b/net/dsa/tag_sja1105.c
@@ -211,17 +211,8 @@ static struct sk_buff
211 * for further processing up the network stack. 211 * for further processing up the network stack.
212 */ 212 */
213 kfree_skb(skb); 213 kfree_skb(skb);
214 214 skb = stampable_skb;
215 skb = skb_copy(stampable_skb, GFP_ATOMIC);
216 if (!skb) {
217 dev_err_ratelimited(dp->ds->dev,
218 "Failed to copy stampable skb\n");
219 spin_unlock(&sp->data->meta_lock);
220 return NULL;
221 }
222 sja1105_transfer_meta(skb, meta); 215 sja1105_transfer_meta(skb, meta);
223 /* The cached copy will be freed now */
224 skb_unref(stampable_skb);
225 216
226 spin_unlock(&sp->data->meta_lock); 217 spin_unlock(&sp->data->meta_lock);
227 } 218 }