This is a note to let you know that I've just added the patch titled can: j1939: change j1939_netdev_lock type to mutex to the 5.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: can-j1939-change-j1939_netdev_lock-type-to-mutex.patch and it can be found in the queue-5.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From cd9c790de2088b0d797dc4d244b4f174f9962554 Mon Sep 17 00:00:00 2001 From: Fedor Pchelkin <pchelkin@xxxxxxxxx> Date: Fri, 26 May 2023 20:19:09 +0300 Subject: can: j1939: change j1939_netdev_lock type to mutex From: Fedor Pchelkin <pchelkin@xxxxxxxxx> commit cd9c790de2088b0d797dc4d244b4f174f9962554 upstream. It turns out access to j1939_can_rx_register() needs to be serialized, otherwise j1939_priv can be corrupted when parallel threads call j1939_netdev_start() and j1939_can_rx_register() fails. This issue is thoroughly covered in other commit which serializes access to j1939_can_rx_register(). Change j1939_netdev_lock type to mutex so that we do not need to remove GFP_KERNEL from can_rx_register(). j1939_netdev_lock seems to be used in normal contexts where mutex usage is not prohibited. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol") Suggested-by: Alexey Khoroshilov <khoroshilov@xxxxxxxxx> Signed-off-by: Fedor Pchelkin <pchelkin@xxxxxxxxx> Tested-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> Acked-by: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> Link: https://lore.kernel.org/r/20230526171910.227615-2-pchelkin@xxxxxxxxx Cc: stable@xxxxxxxxxxxxxxx Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- net/can/j1939/main.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) --- a/net/can/j1939/main.c +++ b/net/can/j1939/main.c @@ -122,7 +122,7 @@ static void j1939_can_recv(struct sk_buf #define J1939_CAN_ID CAN_EFF_FLAG #define J1939_CAN_MASK (CAN_EFF_FLAG | CAN_RTR_FLAG) -static DEFINE_SPINLOCK(j1939_netdev_lock); +static DEFINE_MUTEX(j1939_netdev_lock); static struct j1939_priv *j1939_priv_create(struct net_device *ndev) { @@ -216,7 +216,7 @@ static void __j1939_rx_release(struct kr j1939_can_rx_unregister(priv); j1939_ecu_unmap_all(priv); j1939_priv_set(priv->ndev, NULL); - spin_unlock(&j1939_netdev_lock); + mutex_unlock(&j1939_netdev_lock); } /* get pointer to priv without increasing ref counter */ @@ -244,9 +244,9 @@ static struct j1939_priv *j1939_priv_get { struct j1939_priv *priv; - spin_lock(&j1939_netdev_lock); + mutex_lock(&j1939_netdev_lock); priv = j1939_priv_get_by_ndev_locked(ndev); - spin_unlock(&j1939_netdev_lock); + mutex_unlock(&j1939_netdev_lock); return priv; } @@ -256,14 +256,14 @@ struct j1939_priv *j1939_netdev_start(st struct j1939_priv *priv, *priv_new; int ret; - spin_lock(&j1939_netdev_lock); + mutex_lock(&j1939_netdev_lock); priv = j1939_priv_get_by_ndev_locked(ndev); if (priv) { kref_get(&priv->rx_kref); - spin_unlock(&j1939_netdev_lock); + mutex_unlock(&j1939_netdev_lock); return priv; } - spin_unlock(&j1939_netdev_lock); + mutex_unlock(&j1939_netdev_lock); priv = j1939_priv_create(ndev); if (!priv) @@ -273,20 +273,20 @@ struct j1939_priv *j1939_netdev_start(st spin_lock_init(&priv->j1939_socks_lock); INIT_LIST_HEAD(&priv->j1939_socks); - spin_lock(&j1939_netdev_lock); + mutex_lock(&j1939_netdev_lock); priv_new = j1939_priv_get_by_ndev_locked(ndev); if (priv_new) { /* Someone was faster than us, use their priv and roll * back our's. */ kref_get(&priv_new->rx_kref); - spin_unlock(&j1939_netdev_lock); + mutex_unlock(&j1939_netdev_lock); dev_put(ndev); kfree(priv); return priv_new; } j1939_priv_set(ndev, priv); - spin_unlock(&j1939_netdev_lock); + mutex_unlock(&j1939_netdev_lock); ret = j1939_can_rx_register(priv); if (ret < 0) @@ -304,7 +304,7 @@ struct j1939_priv *j1939_netdev_start(st void j1939_netdev_stop(struct j1939_priv *priv) { - kref_put_lock(&priv->rx_kref, __j1939_rx_release, &j1939_netdev_lock); + kref_put_mutex(&priv->rx_kref, __j1939_rx_release, &j1939_netdev_lock); j1939_priv_put(priv); } Patches currently in stable-queue which might be from pchelkin@xxxxxxxxx are queue-5.4/can-j1939-change-j1939_netdev_lock-type-to-mutex.patch queue-5.4/can-j1939-avoid-possible-use-after-free-when-j1939_can_rx_register-fails.patch