Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2d367468 authored by Johan Hovold's avatar Johan Hovold Committed by Greg Kroah-Hartman
Browse files

rsi: fix use-after-free on probe errors



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: default avatar <syzbot+1d1597a5aa3679c65b9f@syzkaller.appspotmail.com>
Fixes: b78e91bc ("rsi: Add new firmware loading method")
Cc: stable <stable@vger.kernel.org>     # 4.12
Cc: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Cc: Amitkumar Karwar <amit.karwar@redpinesignals.com>
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d8902b43
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -622,6 +622,7 @@ static int bl_cmd(struct rsi_hw *adapter, u8 cmd, u8 exp_resp, char *str)
	bl_start_cmd_timer(adapter, timeout);
	bl_start_cmd_timer(adapter, timeout);
	status = bl_write_cmd(adapter, cmd, exp_resp, &regout_val);
	status = bl_write_cmd(adapter, cmd, exp_resp, &regout_val);
	if (status < 0) {
	if (status < 0) {
		bl_stop_cmd_timer(adapter);
		rsi_dbg(ERR_ZONE,
		rsi_dbg(ERR_ZONE,
			"%s: Command %s (%0x) writing failed..\n",
			"%s: Command %s (%0x) writing failed..\n",
			__func__, str, cmd);
			__func__, str, cmd);
@@ -737,10 +738,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);
	status = bl_cmd(adapter, cmd_req, cmd_resp, str);
	if (status) {
	if (status)
		bl_stop_cmd_timer(adapter);
		return status;
		return status;
	}

	return 0;
	return 0;
}
}


@@ -828,10 +828,9 @@ static int auto_fw_upgrade(struct rsi_hw *adapter, u8 *flash_content,


	status = bl_cmd(adapter, EOF_REACHED, FW_LOADING_SUCCESSFUL,
	status = bl_cmd(adapter, EOF_REACHED, FW_LOADING_SUCCESSFUL,
			"EOF_REACHED");
			"EOF_REACHED");
	if (status) {
	if (status)
		bl_stop_cmd_timer(adapter);
		return status;
		return status;
	}

	rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n");
	rsi_dbg(INFO_ZONE, "FW loading is done and FW is running..\n");
	return 0;
	return 0;
}
}
@@ -849,6 +848,7 @@ static int rsi_hal_prepare_fwload(struct rsi_hw *adapter)
						  &regout_val,
						  &regout_val,
						  RSI_COMMON_REG_SIZE);
						  RSI_COMMON_REG_SIZE);
		if (status < 0) {
		if (status < 0) {
			bl_stop_cmd_timer(adapter);
			rsi_dbg(ERR_ZONE,
			rsi_dbg(ERR_ZONE,
				"%s: REGOUT read failed\n", __func__);
				"%s: REGOUT read failed\n", __func__);
			return status;
			return status;