From 1c3fcdb8f5888371b2ecd1bc4ac3b59200204177 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Thu, 28 Nov 2019 18:22:01 +0100 Subject: [PATCH] rsi: fix use-after-free on probe errors BugLink: https://bugs.launchpad.net/bugs/1864904 commit 92aafe77123ab478e5f5095878856ab0424910da upstream. The driver would fail to stop the command timer in most error paths, something which specifically could lead to the timer being freed while still active on I/O errors during probe. Fix this by making sure that each function starting the timer also stops it in all relevant error paths. Reported-by: syzbot+1d1597a5aa3679c65b9f@syzkaller.appspotmail.com Fixes: b78e91bcfb33 ("rsi: Add new firmware loading method") Cc: stable # 4.12 Cc: Prameela Rani Garnepudi Cc: Amitkumar Karwar Signed-off-by: Johan Hovold Signed-off-by: Kalle Valo Signed-off-by: Greg Kroah-Hartman Signed-off-by: Kamal Mostafa Signed-off-by: Khalid Elmously --- drivers/net/wireless/rsi/rsi_91x_hal.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c index d793d335d080..375eef8cf74e 100644 --- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -556,6 +556,7 @@ static int bl_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, char *str) bl_start_cmd_timer(adapter, timeout); status = bl_write_cmd(adapter, cmd, exp_resp, ®out_val); if (status < 0) { + bl_stop_cmd_timer(adapter); rsi_dbg(ERR_ZONE, "%s: Command %s (%0x) writing failed..\n", __func__, str, cmd); @@ -671,10 +672,9 @@ static int ping_pong_write(struct rsi_hw *adapter, u8 cmd, u8 *addr, u32 size) } status = bl_cmd(adapter, cmd_req, cmd_resp, str); - if (status) { - bl_stop_cmd_timer(adapter); + if (status) return status; - } + return 0; } @@ -764,10 +764,9 @@ static int auto_fw_upgrade(struct rsi_hw *adapter, u8 *flash_content, status = bl_cmd(adapter, EOF_REACHED, FW_LOADING_SUCCESSFUL, "EOF_REACHED"); - if (status) { - bl_stop_cmd_timer(adapter); + if (status) return status; - } + rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n"); return 0; } @@ -789,6 +788,7 @@ static int rsi_load_firmware(struct rsi_hw *adapter) status = hif_ops->master_reg_read(adapter, SWBL_REGOUT, ®out_val, 2); if (status < 0) { + bl_stop_cmd_timer(adapter); rsi_dbg(ERR_ZONE, "%s: REGOUT read failed\n", __func__); return status; -- 2.39.2