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)
committerDavid S. Miller <davem@davemloft.net>
Mon, 15 Mar 2021 19:18:58 +0000 (12:18 -0700)
commitbf0ffea336b493c0a8c8bc27b46683ecf1e8f294
tree06f9848483c50d5b8f80fd54246d0340fb4998b9
parenta25f822285420486f5da434efc8d940d42a83bce
net: hdlc_x25: Prevent racing between "x25_close" and "x25_xmit"/"x25_rx"

"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>
drivers/net/wan/hdlc_x25.c