carl9170_cmd_callback() checks if the response length matches what was expected (ar->readlen). If it doesn't match, it warns and calls carl9170_restart(), but the code below still runs anyway and copies the response into ar->readbuf using the actual (wrong) length. ar->readbuf is only sized for the expected length, so a bad response larger than expected overflows it. This showed up as a KASAN stack-out-of-bounds write, found by syzbot with a fuzzed USB device sending a 60-byte response when 0 bytes were expected. Move the memcpy() and complete() into an else branch so they only run when the length actually matches, instead of falling through after the mismatch is already detected. Fixes: a84fab3cbfdc ("carl9170: 802.11 rx/tx processing and usb backend") Reported-by: syzbot+5c1ca6ccaa1215781cac@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=5c1ca6ccaa1215781cac Signed-off-by: Alexander Bendezu --- drivers/net/wireless/ath/carl9170/rx.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index 6833430130f4..3460b0ca0360 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -145,17 +145,17 @@ static void carl9170_cmd_callback(struct ar9170 *ar, u32 len, void *buffer) * and we get a stack trace from there. */ carl9170_restart(ar, CARL9170_RR_INVALID_RSP); - } - - spin_lock(&ar->cmd_lock); - if (ar->readbuf) { - if (len >= 4) - memcpy(ar->readbuf, buffer + 4, len - 4); + } else { + spin_lock(&ar->cmd_lock); + if (ar->readbuf) { + if (len >= 4) + memcpy(ar->readbuf, buffer + 4, len - 4); - ar->readbuf = NULL; + ar->readbuf = NULL; + } + complete(&ar->cmd_wait); + spin_unlock(&ar->cmd_lock); } - complete(&ar->cmd_wait); - spin_unlock(&ar->cmd_lock); } void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) -- 2.53.0