Commit 8be636dd authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from David Miller:

 1) Fix memory leak in xfrm_state code, from Steffen Klassert.

 2) Fix races between devlink reload operations and device
    setup/cleanup, from Jiri Pirko.

 3) Null deref in NFC code, from Stephan Gerhold.

 4) Refcount fixes in SMC, from Ursula Braun.

 5) Memory leak in slcan open error paths, from Jouni Hogander.

 6) Fix ETS bandwidth validation in hns3, from Yonglong Liu.

 7) Info leak on short USB request answers in ax88172a driver, from
    Oliver Neukum.

 8) Release mem region properly in ep93xx_eth, from Chuhong Yuan.

 9) PTP config timestamp flags validation, from Richard Cochran.

10) Dangling pointers after SKB data realloc in seg6, from Andrea Mayer.

11) Missing free_netdev() in gemini driver, from Chuhong Yuan.

* git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (56 commits)
  ipmr: Fix skb headroom in ipmr_get_route().
  net: hns3: cleanup of stray struct hns3_link_mode_mapping
  net/smc: fix fastopen for non-blocking connect()
  rds: ib: update WR sizes when bringing up connection
  net: gemini: add missed free_netdev
  net: dsa: tag_8021q: Fix dsa_8021q_restore_pvid for an absent pvid
  seg6: fix skb transport_header after decap_and_validate()
  seg6: fix srh pointer in get_srh()
  net: stmmac: Use the correct style for SPDX License Identifier
  octeontx2-af: Use the correct style for SPDX License Identifier
  ptp: Extend the test program to check the external time stamp flags.
  mlx5: Reject requests to enable time stamping on both edges.
  igb: Reject requests that fail to enable time stamping on both edges.
  dp83640: Reject requests to enable time stamping on both edges.
  mv88e6xxx: Reject requests to enable time stamping on both edges.
  ptp: Introduce strict checking of external time stamp options.
  renesas: reject unsupported external timestamp flags
  mlx5: reject unsupported external timestamp flags
  igb: reject unsupported external timestamp flags
  dp83640: reject unsupported external timestamp flags
  ...
parents bec8b6e9 7901cd97
...@@ -149,11 +149,21 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg) ...@@ -149,11 +149,21 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
err = -EFAULT; err = -EFAULT;
break; break;
} }
if (((req.extts.flags & ~PTP_EXTTS_VALID_FLAGS) || if (cmd == PTP_EXTTS_REQUEST2) {
req.extts.rsv[0] || req.extts.rsv[1]) && /* Tell the drivers to check the flags carefully. */
cmd == PTP_EXTTS_REQUEST2) { req.extts.flags |= PTP_STRICT_FLAGS;
err = -EINVAL; /* Make sure no reserved bit is set. */
break; if ((req.extts.flags & ~PTP_EXTTS_VALID_FLAGS) ||
req.extts.rsv[0] || req.extts.rsv[1]) {
err = -EINVAL;
break;
}
/* Ensure one of the rising/falling edge bits is set. */
if ((req.extts.flags & PTP_ENABLE_FEATURE) &&
(req.extts.flags & PTP_EXTTS_EDGES) == 0) {
err = -EINVAL;
break;
}
} else if (cmd == PTP_EXTTS_REQUEST) { } else if (cmd == PTP_EXTTS_REQUEST) {
req.extts.flags &= PTP_EXTTS_V1_VALID_FLAGS; req.extts.flags &= PTP_EXTTS_V1_VALID_FLAGS;
req.extts.rsv[0] = 0; req.extts.rsv[0] = 0;
......
...@@ -65,5 +65,6 @@ extern void can_rx_unregister(struct net *net, struct net_device *dev, ...@@ -65,5 +65,6 @@ extern void can_rx_unregister(struct net *net, struct net_device *dev,
void *data); void *data);
extern int can_send(struct sk_buff *skb, int loop); extern int can_send(struct sk_buff *skb, int loop);
void can_sock_destruct(struct sock *sk);
#endif /* !_CAN_CORE_H */ #endif /* !_CAN_CORE_H */
...@@ -38,7 +38,8 @@ struct devlink { ...@@ -38,7 +38,8 @@ struct devlink {
struct device *dev; struct device *dev;
possible_net_t _net; possible_net_t _net;
struct mutex lock; struct mutex lock;
bool reload_failed; u8 reload_failed:1,
reload_enabled:1;
char priv[0] __aligned(NETDEV_ALIGN); char priv[0] __aligned(NETDEV_ALIGN);
}; };
...@@ -774,6 +775,8 @@ struct ib_device; ...@@ -774,6 +775,8 @@ struct ib_device;
struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size); struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size);
int devlink_register(struct devlink *devlink, struct device *dev); int devlink_register(struct devlink *devlink, struct device *dev);
void devlink_unregister(struct devlink *devlink); void devlink_unregister(struct devlink *devlink);
void devlink_reload_enable(struct devlink *devlink);
void devlink_reload_disable(struct devlink *devlink);
void devlink_free(struct devlink *devlink); void devlink_free(struct devlink *devlink);
int devlink_port_register(struct devlink *devlink, int devlink_port_register(struct devlink *devlink,
struct devlink_port *devlink_port, struct devlink_port *devlink_port,
......
...@@ -86,7 +86,7 @@ DECLARE_EVENT_CLASS(tcp_event_sk_skb, ...@@ -86,7 +86,7 @@ DECLARE_EVENT_CLASS(tcp_event_sk_skb,
sk->sk_v6_rcv_saddr, sk->sk_v6_daddr); sk->sk_v6_rcv_saddr, sk->sk_v6_daddr);
), ),
TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c state=%s\n", TP_printk("sport=%hu dport=%hu saddr=%pI4 daddr=%pI4 saddrv6=%pI6c daddrv6=%pI6c state=%s",
__entry->sport, __entry->dport, __entry->saddr, __entry->daddr, __entry->sport, __entry->dport, __entry->saddr, __entry->daddr,
__entry->saddr_v6, __entry->daddr_v6, __entry->saddr_v6, __entry->daddr_v6,
show_tcp_state_name(__entry->state)) show_tcp_state_name(__entry->state))
......
...@@ -421,6 +421,7 @@ enum devlink_attr { ...@@ -421,6 +421,7 @@ enum devlink_attr {
DEVLINK_ATTR_RELOAD_FAILED, /* u8 0 or 1 */ DEVLINK_ATTR_RELOAD_FAILED, /* u8 0 or 1 */
DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS, /* u64 */
/* add new attributes above here, update the policy in devlink.c */ /* add new attributes above here, update the policy in devlink.c */
__DEVLINK_ATTR_MAX, __DEVLINK_ATTR_MAX,
......
...@@ -31,13 +31,16 @@ ...@@ -31,13 +31,16 @@
#define PTP_ENABLE_FEATURE (1<<0) #define PTP_ENABLE_FEATURE (1<<0)
#define PTP_RISING_EDGE (1<<1) #define PTP_RISING_EDGE (1<<1)
#define PTP_FALLING_EDGE (1<<2) #define PTP_FALLING_EDGE (1<<2)
#define PTP_STRICT_FLAGS (1<<3)
#define PTP_EXTTS_EDGES (PTP_RISING_EDGE | PTP_FALLING_EDGE)
/* /*
* flag fields valid for the new PTP_EXTTS_REQUEST2 ioctl. * flag fields valid for the new PTP_EXTTS_REQUEST2 ioctl.
*/ */
#define PTP_EXTTS_VALID_FLAGS (PTP_ENABLE_FEATURE | \ #define PTP_EXTTS_VALID_FLAGS (PTP_ENABLE_FEATURE | \
PTP_RISING_EDGE | \ PTP_RISING_EDGE | \
PTP_FALLING_EDGE) PTP_FALLING_EDGE | \
PTP_STRICT_FLAGS)
/* /*
* flag fields valid for the original PTP_EXTTS_REQUEST ioctl. * flag fields valid for the original PTP_EXTTS_REQUEST ioctl.
......
...@@ -86,11 +86,12 @@ static atomic_t skbcounter = ATOMIC_INIT(0); ...@@ -86,11 +86,12 @@ static atomic_t skbcounter = ATOMIC_INIT(0);
/* af_can socket functions */ /* af_can socket functions */
static void can_sock_destruct(struct sock *sk) void can_sock_destruct(struct sock *sk)
{ {
skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_receive_queue);
skb_queue_purge(&sk->sk_error_queue); skb_queue_purge(&sk->sk_error_queue);
} }
EXPORT_SYMBOL(can_sock_destruct);
static const struct can_proto *can_get_proto(int protocol) static const struct can_proto *can_get_proto(int protocol)
{ {
......
...@@ -51,6 +51,7 @@ static void j1939_can_recv(struct sk_buff *iskb, void *data) ...@@ -51,6 +51,7 @@ static void j1939_can_recv(struct sk_buff *iskb, void *data)
if (!skb) if (!skb)
return; return;
j1939_priv_get(priv);
can_skb_set_owner(skb, iskb->sk); can_skb_set_owner(skb, iskb->sk);
/* get a pointer to the header of the skb /* get a pointer to the header of the skb
...@@ -104,6 +105,7 @@ static void j1939_can_recv(struct sk_buff *iskb, void *data) ...@@ -104,6 +105,7 @@ static void j1939_can_recv(struct sk_buff *iskb, void *data)
j1939_simple_recv(priv, skb); j1939_simple_recv(priv, skb);
j1939_sk_recv(priv, skb); j1939_sk_recv(priv, skb);
done: done:
j1939_priv_put(priv);
kfree_skb(skb); kfree_skb(skb);
} }
...@@ -150,6 +152,10 @@ static void __j1939_priv_release(struct kref *kref) ...@@ -150,6 +152,10 @@ static void __j1939_priv_release(struct kref *kref)
netdev_dbg(priv->ndev, "%s: 0x%p\n", __func__, priv); netdev_dbg(priv->ndev, "%s: 0x%p\n", __func__, priv);
WARN_ON_ONCE(!list_empty(&priv->active_session_list));
WARN_ON_ONCE(!list_empty(&priv->ecus));
WARN_ON_ONCE(!list_empty(&priv->j1939_socks));
dev_put(ndev); dev_put(ndev);
kfree(priv); kfree(priv);
} }
...@@ -207,6 +213,9 @@ static inline struct j1939_priv *j1939_ndev_to_priv(struct net_device *ndev) ...@@ -207,6 +213,9 @@ static inline struct j1939_priv *j1939_ndev_to_priv(struct net_device *ndev)
{ {
struct can_ml_priv *can_ml_priv = ndev->ml_priv; struct can_ml_priv *can_ml_priv = ndev->ml_priv;
if (!can_ml_priv)
return NULL;
return can_ml_priv->j1939_priv; return can_ml_priv->j1939_priv;
} }
......
...@@ -78,7 +78,6 @@ static void j1939_jsk_add(struct j1939_priv *priv, struct j1939_sock *jsk) ...@@ -78,7 +78,6 @@ static void j1939_jsk_add(struct j1939_priv *priv, struct j1939_sock *jsk)
{ {
jsk->state |= J1939_SOCK_BOUND; jsk->state |= J1939_SOCK_BOUND;
j1939_priv_get(priv); j1939_priv_get(priv);
jsk->priv = priv;
spin_lock_bh(&priv->j1939_socks_lock); spin_lock_bh(&priv->j1939_socks_lock);
list_add_tail(&jsk->list, &priv->j1939_socks); list_add_tail(&jsk->list, &priv->j1939_socks);
...@@ -91,7 +90,6 @@ static void j1939_jsk_del(struct j1939_priv *priv, struct j1939_sock *jsk) ...@@ -91,7 +90,6 @@ static void j1939_jsk_del(struct j1939_priv *priv, struct j1939_sock *jsk)
list_del_init(&jsk->list); list_del_init(&jsk->list);
spin_unlock_bh(&priv->j1939_socks_lock); spin_unlock_bh(&priv->j1939_socks_lock);
jsk->priv = NULL;
j1939_priv_put(priv); j1939_priv_put(priv);
jsk->state &= ~J1939_SOCK_BOUND; jsk->state &= ~J1939_SOCK_BOUND;
} }
...@@ -349,6 +347,34 @@ void j1939_sk_recv(struct j1939_priv *priv, struct sk_buff *skb) ...@@ -349,6 +347,34 @@ void j1939_sk_recv(struct j1939_priv *priv, struct sk_buff *skb)
spin_unlock_bh(&priv->j1939_socks_lock); spin_unlock_bh(&priv->j1939_socks_lock);
} }
static void j1939_sk_sock_destruct(struct sock *sk)
{
struct j1939_sock *jsk = j1939_sk(sk);
/* This function will be call by the generic networking code, when then
* the socket is ultimately closed (sk->sk_destruct).
*
* The race between
* - processing a received CAN frame
* (can_receive -> j1939_can_recv)
* and accessing j1939_priv
* ... and ...
* - closing a socket
* (j1939_can_rx_unregister -> can_rx_unregister)
* and calling the final j1939_priv_put()
*
* is avoided by calling the final j1939_priv_put() from this
* RCU deferred cleanup call.
*/
if (jsk->priv) {
j1939_priv_put(jsk->priv);
jsk->priv = NULL;
}
/* call generic CAN sock destruct */
can_sock_destruct(sk);
}
static int j1939_sk_init(struct sock *sk) static int j1939_sk_init(struct sock *sk)
{ {
struct j1939_sock *jsk = j1939_sk(sk); struct j1939_sock *jsk = j1939_sk(sk);
...@@ -371,6 +397,7 @@ static int j1939_sk_init(struct sock *sk) ...@@ -371,6 +397,7 @@ static int j1939_sk_init(struct sock *sk)
atomic_set(&jsk->skb_pending, 0); atomic_set(&jsk->skb_pending, 0);
spin_lock_init(&jsk->sk_session_queue_lock); spin_lock_init(&jsk->sk_session_queue_lock);
INIT_LIST_HEAD(&jsk->sk_session_queue); INIT_LIST_HEAD(&jsk->sk_session_queue);
sk->sk_destruct = j1939_sk_sock_destruct;
return 0; return 0;
} }
...@@ -443,6 +470,12 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len) ...@@ -443,6 +470,12 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len)
} }
jsk->ifindex = addr->can_ifindex; jsk->ifindex = addr->can_ifindex;
/* the corresponding j1939_priv_put() is called via
* sk->sk_destruct, which points to j1939_sk_sock_destruct()
*/
j1939_priv_get(priv);
jsk->priv = priv;
} }
/* set default transmit pgn */ /* set default transmit pgn */
...@@ -560,8 +593,8 @@ static int j1939_sk_release(struct socket *sock) ...@@ -560,8 +593,8 @@ static int j1939_sk_release(struct socket *sock)
if (!sk) if (!sk)
return 0; return 0;
jsk = j1939_sk(sk);
lock_sock(sk); lock_sock(sk);
jsk = j1939_sk(sk);
if (jsk->state & J1939_SOCK_BOUND) { if (jsk->state & J1939_SOCK_BOUND) {
struct j1939_priv *priv = jsk->priv; struct j1939_priv *priv = jsk->priv;
...@@ -1059,51 +1092,72 @@ static int j1939_sk_sendmsg(struct socket *sock, struct msghdr *msg, ...@@ -1059,51 +1092,72 @@ static int j1939_sk_sendmsg(struct socket *sock, struct msghdr *msg,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct j1939_sock *jsk = j1939_sk(sk); struct j1939_sock *jsk = j1939_sk(sk);
struct j1939_priv *priv = jsk->priv; struct j1939_priv *priv;
int ifindex; int ifindex;
int ret; int ret;
lock_sock(sock->sk);
/* various socket state tests */ /* various socket state tests */
if (!(jsk->state & J1939_SOCK_BOUND)) if (!(jsk->state & J1939_SOCK_BOUND)) {
return -EBADFD; ret = -EBADFD;
goto sendmsg_done;
}
priv = jsk->priv;
ifindex = jsk->ifindex; ifindex = jsk->ifindex;
if (!jsk->addr.src_name && jsk->addr.sa == J1939_NO_ADDR) if (!jsk->addr.src_name && jsk->addr.sa == J1939_NO_ADDR) {
/* no source address assigned yet */ /* no source address assigned yet */
return -EBADFD; ret = -EBADFD;
goto sendmsg_done;
}
/* deal with provided destination address info */ /* deal with provided destination address info */
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_can *addr = msg->msg_name; struct sockaddr_can *addr = msg->msg_name;
if (msg->msg_namelen < J1939_MIN_NAMELEN) if (msg->msg_namelen < J1939_MIN_NAMELEN) {
return -EINVAL; ret = -EINVAL;
goto sendmsg_done;
}
if (addr->can_family != AF_CAN) if (addr->can_family != AF_CAN) {
return -EINVAL; ret = -EINVAL;
goto sendmsg_done;
}
if (addr->can_ifindex && addr->can_ifindex != ifindex) if (addr->can_ifindex && addr->can_ifindex != ifindex) {
return -EBADFD; ret = -EBADFD;
goto sendmsg_done;
}
if (j1939_pgn_is_valid(addr->can_addr.j1939.pgn) && if (j1939_pgn_is_valid(addr->can_addr.j1939.pgn) &&
!j1939_pgn_is_clean_pdu(addr->can_addr.j1939.pgn)) !j1939_pgn_is_clean_pdu(addr->can_addr.j1939.pgn)) {
return -EINVAL; ret = -EINVAL;
goto sendmsg_done;
}
if (!addr->can_addr.j1939.name && if (!addr->can_addr.j1939.name &&
addr->can_addr.j1939.addr == J1939_NO_ADDR && addr->can_addr.j1939.addr == J1939_NO_ADDR &&
!sock_flag(sk, SOCK_BROADCAST)) !sock_flag(sk, SOCK_BROADCAST)) {
/* broadcast, but SO_BROADCAST not set */ /* broadcast, but SO_BROADCAST not set */
return -EACCES; ret = -EACCES;
goto sendmsg_done;
}
} else { } else {
if (!jsk->addr.dst_name && jsk->addr.da == J1939_NO_ADDR && if (!jsk->addr.dst_name && jsk->addr.da == J1939_NO_ADDR &&
!sock_flag(sk, SOCK_BROADCAST)) !sock_flag(sk, SOCK_BROADCAST)) {
/* broadcast, but SO_BROADCAST not set */ /* broadcast, but SO_BROADCAST not set */
return -EACCES; ret = -EACCES;
goto sendmsg_done;
}
} }
ret = j1939_sk_send_loop(priv, sk, msg, size); ret = j1939_sk_send_loop(priv, sk, msg, size);
sendmsg_done:
release_sock(sock->sk);
return ret; return ret;
} }
......
...@@ -255,6 +255,7 @@ static void __j1939_session_drop(struct j1939_session *session) ...@@ -255,6 +255,7 @@ static void __j1939_session_drop(struct j1939_session *session)
return; return;
j1939_sock_pending_del(session->sk); j1939_sock_pending_del(session->sk);
sock_put(session->sk);
} }
static void j1939_session_destroy(struct j1939_session *session) static void j1939_session_destroy(struct j1939_session *session)
...@@ -266,6 +267,9 @@ static void j1939_session_destroy(struct j1939_session *session) ...@@ -266,6 +267,9 @@ static void j1939_session_destroy(struct j1939_session *session)
netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session); netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
WARN_ON_ONCE(!list_empty(&session->sk_session_queue_entry));
WARN_ON_ONCE(!list_empty(&session->active_session_list_entry));
skb_queue_purge(&session->skb_queue); skb_queue_purge(&session->skb_queue);
__j1939_session_drop(session); __j1939_session_drop(session);
j1939_priv_put(session->priv); j1939_priv_put(session->priv);
...@@ -1042,12 +1046,13 @@ j1939_session_deactivate_activate_next(struct j1939_session *session) ...@@ -1042,12 +1046,13 @@ j1939_session_deactivate_activate_next(struct j1939_session *session)
j1939_sk_queue_activate_next(session); j1939_sk_queue_activate_next(session);
} }
static void j1939_session_cancel(struct j1939_session *session, static void __j1939_session_cancel(struct j1939_session *session,
enum j1939_xtp_abort err) enum j1939_xtp_abort err)
{ {
struct j1939_priv *priv = session->priv; struct j1939_priv *priv = session->priv;
WARN_ON_ONCE(!err); WARN_ON_ONCE(!err);
lockdep_assert_held(&session->priv->active_session_list_lock);
session->err = j1939_xtp_abort_to_errno(priv, err); session->err = j1939_xtp_abort_to_errno(priv, err);
/* do not send aborts on incoming broadcasts */ /* do not send aborts on incoming broadcasts */
...@@ -1062,6 +1067,20 @@ static void j1939_session_cancel(struct j1939_session *session, ...@@ -1062,6 +1067,20 @@ static void j1939_session_cancel(struct j1939_session *session,
j1939_sk_send_loop_abort(session->sk, session->err); j1939_sk_send_loop_abort(session->sk, session->err);
} }
static void j1939_session_cancel(struct j1939_session *session,
enum j1939_xtp_abort err)
{
j1939_session_list_lock(session->priv);
if (session->state >= J1939_SESSION_ACTIVE &&
session->state < J1939_SESSION_WAITING_ABORT) {
j1939_tp_set_rxtimeout(session, J1939_XTP_ABORT_TIMEOUT_MS);
__j1939_session_cancel(session, err);
}
j1939_session_list_unlock(session->priv);
}
static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer) static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer)
{ {
struct j1939_session *session = struct j1939_session *session =
...@@ -1108,8 +1127,6 @@ static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer) ...@@ -1108,8 +1127,6 @@ static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer)
netdev_alert(priv->ndev, "%s: 0x%p: tx aborted with unknown reason: %i\n", netdev_alert(priv->ndev, "%s: 0x%p: tx aborted with unknown reason: %i\n",
__func__, session, ret); __func__, session, ret);
if (session->skcb.addr.type != J1939_SIMPLE) { if (session->skcb.addr.type != J1939_SIMPLE) {
j1939_tp_set_rxtimeout(session,
J1939_XTP_ABORT_TIMEOUT_MS);
j1939_session_cancel(session, J1939_XTP_ABORT_OTHER); j1939_session_cancel(session, J1939_XTP_ABORT_OTHER);
} else { } else {
session->err = ret; session->err = ret;
...@@ -1169,7 +1186,7 @@ static enum hrtimer_restart j1939_tp_rxtimer(struct hrtimer *hrtimer) ...@@ -1169,7 +1186,7 @@ static enum hrtimer_restart j1939_tp_rxtimer(struct hrtimer *hrtimer)
hrtimer_start(&session->rxtimer, hrtimer_start(&session->rxtimer,
ms_to_ktime(J1939_XTP_ABORT_TIMEOUT_MS), ms_to_ktime(J1939_XTP_ABORT_TIMEOUT_MS),
HRTIMER_MODE_REL_SOFT); HRTIMER_MODE_REL_SOFT);
j1939_session_cancel(session, J1939_XTP_ABORT_TIMEOUT); __j1939_session_cancel(session, J1939_XTP_ABORT_TIMEOUT);
} }
j1939_session_list_unlock(session->priv); j1939_session_list_unlock(session->priv);
} }
...@@ -1375,7 +1392,6 @@ j1939_xtp_rx_cts_one(struct j1939_session *session, struct sk_buff *skb) ...@@ -1375,7 +1392,6 @@ j1939_xtp_rx_cts_one(struct j1939_session *session, struct sk_buff *skb)
out_session_cancel: out_session_cancel:
j1939_session_timers_cancel(session); j1939_session_timers_cancel(session);
j1939_tp_set_rxtimeout(session, J1939_XTP_ABORT_TIMEOUT_MS);
j1939_session_cancel(session, err); j1939_session_cancel(session, err);
} }
...@@ -1572,7 +1588,6 @@ static int j1939_xtp_rx_rts_session_active(struct j1939_session *session, ...@@ -1572,7 +1588,6 @@ static int j1939_xtp_rx_rts_session_active(struct j1939_session *session,
/* RTS on active session */ /* RTS on active session */
j1939_session_timers_cancel(session); j1939_session_timers_cancel(session);
j1939_tp_set_rxtimeout(session, J1939_XTP_ABORT_TIMEOUT_MS);
j1939_session_cancel(session, J1939_XTP_ABORT_BUSY); j1939_session_cancel(session, J1939_XTP_ABORT_BUSY);
} }
...@@ -1583,7 +1598,6 @@ static int j1939_xtp_rx_rts_session_active(struct j1939_session *session, ...@@ -1583,7 +1598,6 @@ static int j1939_xtp_rx_rts_session_active(struct j1939_session *session,
session->last_cmd); session->last_cmd);
j1939_session_timers_cancel(session); j1939_session_timers_cancel(session);
j1939_tp_set_rxtimeout(session, J1939_XTP_ABORT_TIMEOUT_MS);
j1939_session_cancel(session, J1939_XTP_ABORT_BUSY); j1939_session_cancel(session, J1939_XTP_ABORT_BUSY);
return -EBUSY; return -EBUSY;
...@@ -1785,7 +1799,6 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session, ...@@ -1785,7 +1799,6 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
out_session_cancel: out_session_cancel:
j1939_session_timers_cancel(session); j1939_session_timers_cancel(session);
j1939_tp_set_rxtimeout(session, J1939_XTP_ABORT_TIMEOUT_MS);
j1939_session_cancel(session, J1939_XTP_ABORT_FAULT); j1939_session_cancel(session, J1939_XTP_ABORT_FAULT);
j1939_session_put(session); j1939_session_put(session);
} }
...@@ -1866,6 +1879,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv, ...@@ -1866,6 +1879,7 @@ struct j1939_session *j1939_tp_send(struct j1939_priv *priv,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
/* skb is recounted in j1939_session_new() */ /* skb is recounted in j1939_session_new() */
sock_hold(skb->sk);
session->sk = skb->sk; session->sk = skb->sk;
session->transmission = true; session->transmission = true;
session->pkt.total = (size + 6) / 7; session->pkt.total = (size + 6) / 7;
...@@ -2028,7 +2042,11 @@ int j1939_cancel_active_session(struct j1939_priv *priv, struct sock *sk) ...@@ -2028,7 +2042,11 @@ int j1939_cancel_active_session(struct j1939_priv *priv, struct sock *sk)
&priv->active_session_list, &priv->active_session_list,
active_session_list_entry) { active_session_list_entry) {
if (!sk || sk == session->sk) { if (!sk || sk == session->sk) {
j1939_session_timers_cancel(session); if (hrtimer_try_to_cancel(&session->txtimer) == 1)
j1939_session_put(session);
if (hrtimer_try_to_cancel(&session->rxtimer) == 1)
j1939_session_put(session);
session->err = ESHUTDOWN; session->err = ESHUTDOWN;
j1939_session_deactivate_locked(session); j1939_session_deactivate_locked(session);
} }
......
...@@ -2699,7 +2699,7 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info) ...@@ -2699,7 +2699,7 @@ static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)