[PATCH] scsi: ufs: core: fix NULL deref in remaining scsi_cmd_priv() callers

From: shao.mingyin

Date: Mon Oct 26 2026 - 04:48:06 EST


From: Shao Mingyin <shao.mingyin@xxxxxxxxxx>

Commit 4cf752f6b99a ("scsi: ufs: core: Fix NULL pointer dereference in
scsi_cmd_priv() calls") fixed the callers that dereference the command
pointer returned by ufshcd_tag_to_cmd() via scsi_cmd_priv() without
checking for NULL first, but three call sites with the same pattern were
left:

- ufshcd_compl_one_cqe(): scsi_cmd_priv(cmd) runs before the !cmd check.
- ufshcd_mcq_sq_cleanup(): scsi_cmd_priv(cmd) and scsi_cmd_to_rq(cmd)
run before the !cmd check.
- ufshcd_issue_devman_upiu_cmd(): scsi_cmd_priv(cmd) runs before the
WARN_ON_ONCE(!cmd) check.

Fix these three remaining sites by deferring the pointer arithmetic until
after the NULL check.

Signed-off-by: Shao Mingyin <shao.mingyin@xxxxxxxxxx>

---
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index cc75384c6502..76c5400009ff 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -5984,13 +5984,15 @@ void ufshcd_compl_one_cqe(struct ufs_hba *hba, int task_tag,
struct cq_entry *cqe)
{
struct scsi_cmnd *cmd = ufshcd_tag_to_cmd(hba, task_tag);
- struct ufshcd_lrb *lrbp = scsi_cmd_priv(cmd);
+ struct ufshcd_lrb *lrbp;
enum utp_ocs ocs;

if (WARN_ONCE(!cmd, "invalid completion tag %d, cqe->command_desc_base_addr = %#llx\n",
task_tag, cqe ? le64_to_cpu(cqe->command_desc_base_addr) : 0ULL))
return;

+ lrbp = scsi_cmd_priv(cmd);
+
if (hba->monitor.enabled) {
lrbp->compl_time_stamp = ktime_get();
lrbp->compl_time_stamp_local_clock = local_clock();
@@ -7707,7 +7709,7 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
enum query_opcode desc_op)
{
struct scsi_cmnd *cmd = ufshcd_get_dev_mgmt_cmd(hba);
- struct ufshcd_lrb *lrbp = scsi_cmd_priv(cmd);
+ struct ufshcd_lrb *lrbp;
u32 tag;
int err = 0;
u8 upiu_flags;
@@ -7718,6 +7720,8 @@ static int ufshcd_issue_devman_upiu_cmd(struct ufs_hba *hba,
if (WARN_ON_ONCE(!cmd))
return -ENOMEM;

+ lrbp = scsi_cmd_priv(cmd);
+
tag = scsi_cmd_to_rq(cmd)->tag;

ufshcd_setup_dev_cmd(hba, cmd, cmd_type, 0, tag);
diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c
index df293b66350d..ecb54b410730 100644
--- a/drivers/ufs/core/ufs-mcq.c
+++ b/drivers/ufs/core/ufs-mcq.c
@@ -565,8 +565,8 @@ static int ufshcd_mcq_sq_start(struct ufs_hba *hba, struct ufs_hw_queue *hwq)
int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag)
{
struct scsi_cmnd *cmd = ufshcd_tag_to_cmd(hba, task_tag);
- struct ufshcd_lrb *lrbp = scsi_cmd_priv(cmd);
- struct request *rq = scsi_cmd_to_rq(cmd);
+ struct ufshcd_lrb *lrbp;
+ struct request *rq;
struct ufs_hw_queue *hwq;
void __iomem *reg, *opr_sqd_base;
u32 nexus, id, val;
@@ -578,6 +578,9 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag)
if (!cmd)
return -EINVAL;

+ lrbp = scsi_cmd_priv(cmd);
+ rq = scsi_cmd_to_rq(cmd);
+
hwq = ufshcd_mcq_req_to_hwq(hba, rq);
if (!hwq)
return 0;