bot_send_bad_status() reuses fu->bot_req_in/bot_req_out to send the CSW or drain the data phase, but a preceding sg command left req->sg and req->num_sgs pointing at that command's t_data_sg - set in bot_send_read_response() for a read, or usbg_prepare_w_request() for a write. That command is freed before the status request runs, so an sg-capable UDC walks a freed scatter list in dma_map_sg(): it reads freed heap out to the host on an IN endpoint, or writes host data into a freed page on an OUT endpoint. Clear req->num_sgs and req->sg so the UDC uses the linear req->buf instead. With KASAN, a read command followed by a rejected command that reuses bot_req_in reports a slab-use-after-free in the UDC's scatterlist walk, with the previous command's sgl_free() on the freeing stack; clearing the scatter list removes it, while a normal sg read still queues its own scatterlist. Fixes: c52661d60f63 ("usb-gadget: Initial merge of target module for UASP + BOT") Cc: stable@vger.kernel.org Signed-off-by: Yehyeong Lee --- drivers/usb/gadget/function/f_tcm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index a37a3ec8e7a4d..e727e8e1cfa0c 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -140,6 +140,9 @@ static void bot_send_bad_status(struct usbg_cmd *cmd) req->complete = bot_err_compl; req->context = cmd; req->buf = fu->cmd[0].buf; + /* the status request is reused; drop the previous command's sg list */ + req->num_sgs = 0; + req->sg = NULL; usb_ep_queue(ep, req, GFP_ATOMIC); } else { bot_enqueue_sense_code(fu, cmd); -- 2.43.0