set_carrier() reads CSCR via get_registers() (a USB control transfer) without checking the return value, so a transient control transfer failure would leave the on-stack "tmp" uninitialized and then be used to decide the netif carrier state. Check the return value of get_registers() and bail out on error, leaving the previously known carrier state untouched. A failed USB control transfer here may be transient (e.g. EMI, flaky cable, retries exhausted), so it is wrong to force the link down on such failures and cause the carrier state to toggle unnecessarily. This only addresses the uninitialized-value usage and does not change link-state policy. Reported-by: syzbot+9db6c624635564ad813c@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=9db6c624635564ad813c Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: Petko Manolov Cc: Simon Horman Cc: Andrew Lunn Cc: Michal Pecio Signed-off-by: Morduan Zang --- Changes in v2: - Do not force netif_carrier_off() on get_registers() failure; instead return and keep the previous carrier state. A transient USB control transfer failure should not cause carrier to toggle. (based on review feedback from Simon Horman, Petko Manolov, Andrew Lunn and Michal Pecio.) - Minimal change: only avoid the uninitialized read; no link-state policy change. Petko's Ack on v1 is not carried over because v2 changes the error-handling behavior. Changes in v1: - Initial submission: on get_registers() failure call netif_carrier_off() and return. --- drivers/net/usb/rtl8150.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 4cda0643afb6..816759ced56c 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -722,7 +722,8 @@ static void set_carrier(struct net_device *netdev) rtl8150_t *dev = netdev_priv(netdev); short tmp; - get_registers(dev, CSCR, 2, &tmp); + if (get_registers(dev, CSCR, 2, &tmp) < 0) + return; if (tmp & CSCR_LINK_STATUS) netif_carrier_on(netdev); else -- 2.50.1