From: Jia Jia <physicalmtea@gmail.com>
To: "Martin K . Petersen" <mkp@kernel.org>
Cc: Jan Engelhardt <jengelh@inai.de>, Hannes Reinecke <hare@suse.de>,
Paolo Bonzini <pbonzini@redhat.com>,
Akinobu Mita <akinobu.mita@gmail.com>,
James Bottomley <James.Bottomley@suse.de>,
linux-scsi@vger.kernel.org, target-devel@vger.kernel.org,
linux-kernel@vger.kernel.org, Jia Jia <physicalmtea@gmail.com>
Subject: [PATCH 8/8] scsi: target: skip an escaped DIF block inside the data sg
Date: Tue, 6 Oct 2026 17:33:38 +0800 [thread overview]
Message-ID: <20261006093338.27342-9-physicalmtea@gmail.com> (raw)
In-Reply-To: <20261006093338.27342-1-physicalmtea@gmail.com>
sbc_dif_verify() treats an application tag of 0xffff as one skipped
logical block and adds block_size to the data cursor. The next tuple
folds that cursor across a single sg entry. When the block spans more
entries, dsg_off remains past dsg->length and the following CRC reads a
full block from that offset.
A 512 byte block split 256 + 100 + the remainder, with the 100 byte
entry ending on a page and the first tuple escaped, reads the next
block from the next physical page.
Walk every data sg the skipped block covers. Those data pages are
mapped with kmap_local_page(), including the page the cursor moves to.
KASAN reports:
BUG: KASAN: use-after-free in crc_t10dif_update+0x91/0xf0
Read of size 1
crc_t10dif_update
sbc_dif_verify
target_execute_cmd
vhost_scsi_write_pending
transport_generic_new_cmd
__target_submit
target_queued_submit_work
process_one_work
worker_thread
kthread
ret_from_fork
ret_from_fork_asm
Fixes: 18213afbd8ce ("target: handle odd SG mapping for data transfer memory")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
---
drivers/target/target_core_sbc.c | 46 +++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c
index 76dbc986e887..7c4f66c2607a 100644
--- a/drivers/target/target_core_sbc.c
+++ b/drivers/target/target_core_sbc.c
@@ -1521,6 +1521,46 @@ void sbc_dif_copy_prot(struct se_cmd *cmd, unsigned int sectors, bool read,
}
EXPORT_SYMBOL(sbc_dif_copy_prot);
+/*
+ * Drop @len bytes of the data sg. An escaped PI tuple still covers one
+ * logical block, which may cross more than one sg entry.
+ */
+static bool
+sbc_dif_consume(struct scatterlist **dsgp, void **daddrp, int *offp,
+ unsigned int len)
+{
+ struct scatterlist *dsg = *dsgp;
+ void *daddr = *daddrp;
+ int off = *offp;
+
+ while (len) {
+ unsigned int take;
+
+ if (off >= dsg->length) {
+ kunmap_local(daddr - dsg->offset);
+ dsg = sg_next(dsg);
+ if (!dsg)
+ return false;
+
+ daddr = kmap_local_page(sg_page(dsg)) + dsg->offset;
+ off = 0;
+ if (!dsg->length) {
+ kunmap_local(daddr - dsg->offset);
+ return false;
+ }
+ }
+
+ take = min_t(unsigned int, len, dsg->length - off);
+ off += take;
+ len -= take;
+ }
+
+ *dsgp = dsg;
+ *daddrp = daddr;
+ *offp = off;
+ return true;
+}
+
sense_reason_t
sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
unsigned int ei_lba, struct scatterlist *psg, int psg_off)
@@ -1559,7 +1599,11 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors,
sdt.app_tag, be32_to_cpu(sdt.ref_tag));
if (sdt.app_tag == T10_PI_APP_ESCAPE) {
- dsg_off += block_size;
+ if (!sbc_dif_consume(&dsg, &daddr, &dsg_off,
+ block_size)) {
+ kunmap_local(paddr - psg->offset);
+ return 0;
+ }
goto next;
}
--
2.34.1
prev parent reply other threads:[~2026-10-06 9:34 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-06 9:33 [PATCH 0/8] scsi: target: keep command bytes inside the sg Jia Jia
2026-10-06 9:33 ` [PATCH 1/8] scsi: target: take COMPARE AND WRITE data from the write half Jia Jia
2026-10-06 9:33 ` [PATCH 2/8] scsi: target: keep REPORT REFERRALS stores inside the buffer Jia Jia
2026-10-06 9:33 ` [PATCH 3/8] scsi: target: reject a short SET TARGET PORT GROUPS list Jia Jia
2026-10-06 9:33 ` [PATCH 4/8] scsi: target: copy a DIF insert tuple across prot sgs Jia Jia
2026-10-06 9:33 ` [PATCH 5/8] scsi: target: copy a DIF verify " Jia Jia
2026-10-06 9:33 ` [PATCH 6/8] scsi: target: limit DIF block CRC to each data sg Jia Jia
2026-10-06 9:33 ` [PATCH 7/8] scsi: target: keep pscsi mode bytes inside the data sgs Jia Jia
2026-10-06 9:33 ` Jia Jia [this message]
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=20261006093338.27342-9-physicalmtea@gmail.com \
--to=physicalmtea@gmail.com \
--cc=James.Bottomley@suse.de \
--cc=akinobu.mita@gmail.com \
--cc=hare@suse.de \
--cc=jengelh@inai.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=mkp@kernel.org \
--cc=pbonzini@redhat.com \
--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.