net: hdlc_x25: Prevent racing between "x25_close" and "x25_xmit"/"x25_rx"
authorXie He <xie.he.0141@gmail.com>
Sun, 14 Mar 2021 11:21:01 +0000 (04:21 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 30 Mar 2021 12:31:59 +0000 (14:31 +0200)
commit375f5169f23147044958cdcb57bd5c411292adbe
tree188535f19f05f148d07bb6a4f6bad5952eb1c7ad
parentee39ee5f437c1741cb9d1bde5b1aace11de50cb0
net: hdlc_x25: Prevent racing between "x25_close" and "x25_xmit"/"x25_rx"

[ Upstream commit bf0ffea336b493c0a8c8bc27b46683ecf1e8f294 ]

"x25_close" is called by "hdlc_close" in "hdlc.c", which is called by
hardware drivers' "ndo_stop" function.
"x25_xmit" is called by "hdlc_start_xmit" in "hdlc.c", which is hardware
drivers' "ndo_start_xmit" function.
"x25_rx" is called by "hdlc_rcv" in "hdlc.c", which receives HDLC frames
from "net/core/dev.c".

"x25_close" races with "x25_xmit" and "x25_rx" because their callers race.

However, we need to ensure that the LAPB APIs called in "x25_xmit" and
"x25_rx" are called before "lapb_unregister" is called in "x25_close".

This patch adds locking to ensure when "x25_xmit" and "x25_rx" are doing
their work, "lapb_unregister" is not yet called in "x25_close".

Reasons for not solving the racing between "x25_close" and "x25_xmit" by
calling "netif_tx_disable" in "x25_close":
1. We still need to solve the racing between "x25_close" and "x25_rx";
2. The design of the HDLC subsystem assumes the HDLC hardware drivers
have full control over the TX queue, and the HDLC protocol drivers (like
this driver) have no control. Controlling the queue here in the protocol
driver may interfere with hardware drivers' control of the queue.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Xie He <xie.he.0141@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/net/wan/hdlc_x25.c