--- x/net/can/j1939/transport.c +++ y/net/can/j1939/transport.c @@ -2122,10 +2122,12 @@ static void j1939_tp_cmd_recv(struct j19 int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb) { struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb); + int ret = 1; if (!j1939_tp_im_involved_anydir(skcb) && !j1939_cb_is_broadcast(skcb)) return 0; + skb_get(skb); switch (skcb->addr.pgn) { case J1939_ETP_PGN_DAT: skcb->addr.type = J1939_ETP; @@ -2138,14 +2140,18 @@ int j1939_tp_recv(struct j1939_priv *pri skcb->addr.type = J1939_ETP; fallthrough; case J1939_TP_PGN_CTL: - if (skb->len < 8) - return 0; /* Don't care. Nothing to extract here */ + if (skb->len < 8) { + ret = 0; /* Don't care. Nothing to extract here */ + break; + } j1939_tp_cmd_recv(priv, skb); break; default: - return 0; /* no problem */ + ret = 0; /* no problem */ + break; } + kfree_skb(skb); return 1; /* "I processed the message" */ }