All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Tianchu Chen" <tianchu.chen@linux.dev>
To: mkp@kernel.org
Cc: linux-scsi@vger.kernel.org, target-devel@vger.kernel.org
Subject: [PATCH] scsi: target: fix use-after-free on self-preempt in PROUT PREEMPT
Date: Mon, 31 Aug 2026 15:00:26 +0000	[thread overview]
Message-ID: <ddf3c216cf486a1939784731bd1fb50e58092256@linux.dev> (raw)
In-Reply-To: <cfc81cd805c38b2600a219329c351580aa535326@linux.dev>

From: Tianchu Chen <flynnnchen@tencent.com>

In core_scsi3_emulate_pro_preempt(), the !all_reg first path removes
every registration whose key matches the SA RESERVATION KEY field -
including the caller's own.  Unlike the two sibling loops, this one
does not skip the calling I_T nexus; instead it passes
dec_holders = calling_it_nexus, so __core_scsi3_free_registration()
drops the reference taken by core_scsi3_locate_pr_reg() and, for
plain PREEMPT, kmem_cache_free()s the registration right away.

The function tail then unconditionally calls
core_scsi3_put_pr_reg(pr_reg_n), decrementing pr_res_holders of the
already freed object.

A remote initiator can trigger this with two commands: REGISTER with
key K, then PREEMPT with SA RESERVATION KEY K while no reservation is
held (or it is held with a different key).  The dangling decrement
silently corrupts the freed slot, or underflows pr_res_holders of
whatever registration reuses the t10_pr_reg_cache slot, which can
later turn into an early free / double free of a live registration.

Track that the free path consumed the locate reference and skip the
final put in that case.

Discovered by Atuin - Automated Vulnerability Discovery Engine.

Fixes: c66ac9db8d4ad ("[SCSI] target: Add LIO target core v4.0.0-rc6")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
---
 drivers/target/target_core_pr.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index 1d34887e9e845..80e112efd6ead 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -2823,6 +2823,7 @@ core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_
 	u64 pr_res_mapped_lun = 0;
 	int all_reg = 0, calling_it_nexus = 0;
 	bool sa_res_key_unmatched = sa_res_key != 0;
+	bool reg_n_released = false;
 	int prh_type = 0, prh_scope = 0;
 
 	if (!se_sess)
@@ -2926,6 +2927,13 @@ core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_
 				sa_res_key_unmatched = false;
 
 				calling_it_nexus = (pr_reg_n == pr_reg) ? 1 : 0;
+				/*
+				 * dec_holders=1 makes the free path drop the
+				 * reference core_scsi3_locate_pr_reg() took on
+				 * pr_reg_n, so the tail must not put it again.
+				 */
+				if (calling_it_nexus)
+					reg_n_released = true;
 				pr_reg_nacl = pr_reg->pr_reg_nacl;
 				pr_res_mapped_lun = pr_reg->pr_res_mapped_lun;
 				__core_scsi3_free_registration(dev, pr_reg,
@@ -3012,7 +3020,8 @@ core_scsi3_emulate_pro_preempt(struct se_cmd *cmd, int type, int scope, u64 res_
 		if (pr_tmpl->pr_aptpl_active)
 			core_scsi3_update_and_write_aptpl(cmd->se_dev, true);
 
-		core_scsi3_put_pr_reg(pr_reg_n);
+		if (!reg_n_released)
+			core_scsi3_put_pr_reg(pr_reg_n);
 		core_scsi3_pr_generation(cmd->se_dev);
 		return 0;
 	}
-- 
2.51.0

  parent reply	other threads:[~2026-08-31 15:00 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31 13:21 [PATCH] scsi: target: fix PRIN READ_FULL_STATUS buffer bounds check Tianchu Chen
2026-08-31 13:37 ` sashiko-bot
2026-08-31 15:00 ` Tianchu Chen [this message]
2026-08-31 18:14   ` [PATCH] scsi: target: fix use-after-free on self-preempt in PROUT PREEMPT sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ddf3c216cf486a1939784731bd1fb50e58092256@linux.dev \
    --to=tianchu.chen@linux.dev \
    --cc=linux-scsi@vger.kernel.org \
    --cc=mkp@kernel.org \
    --cc=target-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.