Commit b9fde507 authored by Jiasheng Jiang's avatar Jiasheng Jiang Committed by Greg Kroah-Hartman
Browse files

usb: gadget: f_tcm: Fix NULL pointer dereferences in nexus handling



The `tpg->tpg_nexus` pointer in the USB Target driver is dynamically
managed and tied to userspace configuration via ConfigFS. It can be
NULL if the USB host sends requests before the nexus is fully
established or immediately after it is dropped.

Currently, functions like `bot_submit_command()` and the data
transfer paths retrieve `tv_nexus = tpg->tpg_nexus` and immediately
dereference `tv_nexus->tvn_se_sess` without any validation. If a
malicious or misconfigured USB host sends a BOT (Bulk-Only Transport)
command during this race window, it triggers a NULL pointer
dereference, leading to a kernel panic (local DoS).

This exposes an inconsistent API usage within the module, as peer
functions like `usbg_submit_command()` and `bot_send_bad_response()`
correctly implement a NULL check for `tv_nexus` before proceeding.

Fix this by bringing consistency to the nexus handling. Add the
missing `if (!tv_nexus)` checks to the vulnerable BOT command and
request processing paths, aborting the command gracefully with an
error instead of crashing the system.

Fixes: c52661d6 ("usb-gadget: Initial merge of target module for UASP + BOT")
Cc: stable <stable@kernel.org>
Signed-off-by: default avatarJiasheng Jiang <jiashengjiangcool@gmail.com>
Reviewed-by: default avatarThinh Nguyen <Thinh.Nguyen@synopsys.com>
Link: https://patch.msgid.link/20260219023834.17976-1-jiashengjiangcool@gmail.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 93cd0d66
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1222,6 +1222,13 @@ static void usbg_submit_cmd(struct usbg_cmd *cmd)
	se_cmd = &cmd->se_cmd;
	tpg = cmd->fu->tpg;
	tv_nexus = tpg->tpg_nexus;
	if (!tv_nexus) {
		struct usb_gadget *gadget = fuas_to_gadget(cmd->fu);

		dev_err(&gadget->dev, "Missing nexus, ignoring command\n");
		return;
	}

	dir = get_cmd_dir(cmd->cmd_buf);
	if (dir < 0)
		goto out;
@@ -1483,6 +1490,13 @@ static void bot_cmd_work(struct work_struct *work)
	se_cmd = &cmd->se_cmd;
	tpg = cmd->fu->tpg;
	tv_nexus = tpg->tpg_nexus;
	if (!tv_nexus) {
		struct usb_gadget *gadget = fuas_to_gadget(cmd->fu);

		dev_err(&gadget->dev, "Missing nexus, ignoring command\n");
		return;
	}

	dir = get_cmd_dir(cmd->cmd_buf);
	if (dir < 0)
		goto out;