From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f49.google.com (mail-pj1-f49.google.com [209.85.216.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 902AE3DB31E for ; Tue, 6 Oct 2026 09:34:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.49 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791279290; cv=none; b=eMpyvMlQ/pK2aJc+Xmkqv3gkFRzPcIdg95Jrqd8kOQs75q18NqgcU6E5ji6VPntfh5uZDjwgjoI6rhPRAgaNeY/+27LxR9zFbTvYb1BxThc4MVZ8nlGJGmLZH8dDDmFcvi9DL5BN8SpVzoH9NFfnQ/ZCTADM6NfaFC1Q4QiNGK8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791279290; c=relaxed/simple; bh=v2LleU7DjwKjyo5byw/PeaE+ykCm1p6AnsUT0DG35ug=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=XcxUkkljFkr3AmDZ73Hm1d8nvLbCXNWYyqn3Fmc+Wdq+yX6jInk5Pmcu+UCPLk6XwPsMSIslRxVB0ryB5JK+kR0VQNo1S7uHRAPqUuu1wQRLDNzzg5gxW/QSh4QbFSl8rVJL33PPqeGdG+cl6v3XAt9StHxaQZDjgKsOiAzPnsY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Xma5nqY0; arc=none smtp.client-ip=209.85.216.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Xma5nqY0" Received: by mail-pj1-f49.google.com with SMTP id 98e67ed59e1d1-3a0aaa0fd13so949329a91.2 for ; Tue, 06 Oct 2026 02:34:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1791279281; x=1791884081; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OiH8I2vivbUrNosTf6kMbDPyLsej137IHvnAUOusej4=; b=Xma5nqY0pynAzbViNIbPat6cJO99vODJZn1Mta03msl0n95hdeViM1BuTVZC/NDfo9 JENZbkM+b3G/jrIaDOc8RpFvFrmRXxMYB2aF7lCi6D6fH4TnVZCp0Hti8jWQ9d4jd1x9 LYZtcRFrP8gKwBtu79IA8WO58O4NtUWwDwpOOeGXv/B5xo4YWBrkdkk0QXtN6DSiCd6E EnujXyUE4hyvb0OpfvkyQ4bLSRT5bHRZJBnUpgDxrmY3Q2lNOD8SyFclG2meuO9wGtAq gOebO4eZD1HJ8zoijJI3Phy9M8EW8lOwZBwd3ntPUrhfxzG3s1E6FJ0OJHSOvCB4IlPH tIZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1791279281; x=1791884081; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=OiH8I2vivbUrNosTf6kMbDPyLsej137IHvnAUOusej4=; b=AaB/7mQPaJzMo0nucsZwq6C7g/AJCHDwhZcxVuj4jx6Eek6a+oFn9bR+wCY3KyWYuC OLGNzEy9UFL4jmjn136in3LCCaXW6g+CggnAB1W7n2puKvbyjgWT0HQyjhhp/Roz3Dk3 3r+jqmPNcGSFyyq8V4vT/woNYtyTidUCVCfCTyTFHc0meZZozAluiWV77rsheZIJ2Zqn nGHt6JSnXQddyTQAiVBjgWD8ojCzv+L09YwAC4b/xbhoVDiZD41N1x134ZYcERGF6vwv 9wqWrRrb/4VgJwZFsMs6ugJah1BTdDwF3fu0gR999gkNqK4Vdf/wbFSCbW8DgDEdChHF bzSw== X-Forwarded-Encrypted: i=1; AKwUvBwMx3DD8W5PX6oC52gAJmOpi9KeftS9WI5QhQIp8Ans7hARXlGzTpPCw6oxp3UIABiyh5M6EyccNCbmbUQ=@vger.kernel.org X-Gm-Message-State: AFq9FYLFyo2m90qJtAbTaV4QCUV78DlxwQKw7Pkqvn+TGrromZQZbv2H m/twkc7NfT7/+G8WC3JIWJU3g4Cepx4lq0n1mccqSwTPhrOEoG3HXT03 X-Gm-Gg: AYBFou2gbihMUOW1yVskr0Mr2knhFmaBEacC/JgJ4iUv17r7aWtVeyp5DUzqgPwQFoI 7rgxOUW+P79bZ/MlFOqxm1N/cfV/DMIoVtKpERS08LNVw2LuTJRDxDV+Dt78PF9z26+dXejf1R0 xCcTOEZGueriG0txlEgo1NCoE+Nktntk4H707BgtrIngb6oH80VOY9hH4FOFOcXX0qJb4s49PXc 47Vqhx8iPaoBkO+YP4pZJazZmyj5cxSDb4lHMPxzDLVkRTjdKHkI68ihKJbHphP0STsKZDKa55/ cDlFUleR9nc43A7kLzvojJPYocdTfjzYQeD/M6kOBQ3ttqIkYmjyyUO2vGD5XxjqlJP6R4ph7Wf GrUwhrtNBwmfbH16BVszG6YUW6bK3Lk+fsAU2vpORdO2k8EWoxTC57F3LoQ7DlS55fD74RQYtVZ le8slGvPyMWMYXu8W16IgKby/Imt8hO61TLOt95R74sW2z45khwEX05QUaa4VLRB3oGQ1j1XeQG OOZYw14 X-Received: by 2002:a17:90b:4d02:b0:39d:f247:bab with SMTP id 98e67ed59e1d1-3a87267ea23mr746760a91.6.1791279280466; Tue, 06 Oct 2026 02:34:40 -0700 (PDT) Received: from gmail.com ([188.253.12.30]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3a8543ab76bsm3905277a91.13.2026.10.06.02.34.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Oct 2026 02:34:40 -0700 (PDT) From: Jia Jia To: "Martin K . Petersen" Cc: Jan Engelhardt , Hannes Reinecke , Paolo Bonzini , Akinobu Mita , James Bottomley , linux-scsi@vger.kernel.org, target-devel@vger.kernel.org, linux-kernel@vger.kernel.org, Jia Jia Subject: [PATCH 5/8] scsi: target: copy a DIF verify tuple across prot sgs Date: Tue, 6 Oct 2026 17:33:35 +0800 Message-Id: <20261006093338.27342-6-physicalmtea@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20261006093338.27342-1-physicalmtea@gmail.com> References: <20261006093338.27342-1-physicalmtea@gmail.com> Precedence: bulk X-Mailing-List: target-devel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit sbc_dif_verify() loads an 8 byte t10_pi_tuple while i < psg->length. A protection sg shorter than 8 bytes still enters the loop. vhost-scsi keeps each sg inside one page. Eight PI bytes that start at page offset 4092 are mapped as 4 bytes at that offset and 4 bytes on the next guest page. The first sg still satisfies i < length, and the tuple read continues into the next physical page. Software verify runs when the fabric does not advertise DOUT_STRIP. vhost-scsi advertises only DIN_PASS and DOUT_PASS. With fabric_prot_type 1, a WRITE is TARGET_PROT_DOUT_STRIP and sbc_dif_verify() reads the guest PI buffer. Copy the 8 byte tuple across protection sg entries before the check. Four bytes at the end of one entry and four at the start of the next stay one tuple. A tail with no following entry fails the command. KASAN reports: BUG: KASAN: use-after-free in sbc_dif_verify+0x5ab/0x790 [target_core_mod] Read of size 4 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 --- drivers/target/target_core_sbc.c | 117 ++++++++++++++++--------------- 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 12275ebad95c..c0aeb8886743 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -1492,81 +1492,84 @@ sbc_dif_verify(struct se_cmd *cmd, sector_t start, unsigned int sectors, unsigned int ei_lba, struct scatterlist *psg, int psg_off) { struct se_device *dev = cmd->se_dev; - struct t10_pi_tuple *sdt; struct scatterlist *dsg = cmd->t_data_sg; sector_t sector = start; void *daddr, *paddr; - int i; sense_reason_t rc; + unsigned int poff = psg_off; int dsg_off = 0; unsigned int block_size = dev->dev_attrib.block_size; - for (; psg && sector < start + sectors; psg = sg_next(psg)) { - paddr = kmap_atomic(sg_page(psg)) + psg->offset; - daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; - - for (i = psg_off; i < psg->length && - sector < start + sectors; - i += sizeof(*sdt)) { - __u16 crc; - unsigned int avail; - - if (dsg_off >= dsg->length) { - dsg_off -= dsg->length; - kunmap_atomic(daddr - dsg->offset); - dsg = sg_next(dsg); - if (!dsg) { - kunmap_atomic(paddr - psg->offset); - return 0; - } - daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; - } + if (!psg || !dsg) + return 0; - sdt = paddr + i; + paddr = kmap_local_page(sg_page(psg)) + psg->offset; + daddr = kmap_local_page(sg_page(dsg)) + dsg->offset; - pr_debug("DIF READ sector: %llu guard_tag: 0x%04x" - " app_tag: 0x%04x ref_tag: %u\n", - (unsigned long long)sector, sdt->guard_tag, - sdt->app_tag, be32_to_cpu(sdt->ref_tag)); + while (sector < start + sectors) { + struct t10_pi_tuple sdt; + __u16 crc; + unsigned int avail; - if (sdt->app_tag == T10_PI_APP_ESCAPE) { - dsg_off += block_size; - goto next; - } + if (poff >= psg->length && !sg_next(psg)) + break; + + if (!sbc_dif_prot_copy(&psg, &paddr, &poff, &dsg, &daddr, + &sdt, false)) { + cmd->sense_info = sector; + return TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED; + } - avail = min(block_size, dsg->length - dsg_off); - crc = crc_t10dif(daddr + dsg_off, avail); - if (avail < block_size) { - kunmap_atomic(daddr - dsg->offset); - dsg = sg_next(dsg); - if (!dsg) { - kunmap_atomic(paddr - psg->offset); - return 0; - } - daddr = kmap_atomic(sg_page(dsg)) + dsg->offset; - dsg_off = block_size - avail; - crc = crc_t10dif_update(crc, daddr, dsg_off); - } else { - dsg_off += block_size; + pr_debug("DIF READ sector: %llu guard_tag: 0x%04x app_tag: 0x%04x ref_tag: %u\n", + (unsigned long long)sector, sdt.guard_tag, + sdt.app_tag, be32_to_cpu(sdt.ref_tag)); + + if (sdt.app_tag == T10_PI_APP_ESCAPE) { + dsg_off += block_size; + goto next; + } + + if (dsg_off >= dsg->length) { + dsg_off -= dsg->length; + kunmap_local(daddr - dsg->offset); + dsg = sg_next(dsg); + if (!dsg) { + kunmap_local(paddr - psg->offset); + return 0; } + daddr = kmap_local_page(sg_page(dsg)) + dsg->offset; + } - rc = sbc_dif_v1_verify(cmd, sdt, crc, sector, ei_lba); - if (rc) { - kunmap_atomic(daddr - dsg->offset); - kunmap_atomic(paddr - psg->offset); - cmd->sense_info = sector; - return rc; + avail = min(block_size, dsg->length - dsg_off); + crc = crc_t10dif(daddr + dsg_off, avail); + if (avail < block_size) { + kunmap_local(daddr - dsg->offset); + dsg = sg_next(dsg); + if (!dsg) { + kunmap_local(paddr - psg->offset); + return 0; } -next: - sector++; - ei_lba++; + daddr = kmap_local_page(sg_page(dsg)) + dsg->offset; + dsg_off = block_size - avail; + crc = crc_t10dif_update(crc, daddr, dsg_off); + } else { + dsg_off += block_size; } - psg_off = 0; - kunmap_atomic(daddr - dsg->offset); - kunmap_atomic(paddr - psg->offset); + rc = sbc_dif_v1_verify(cmd, &sdt, crc, sector, ei_lba); + if (rc) { + kunmap_local(daddr - dsg->offset); + kunmap_local(paddr - psg->offset); + cmd->sense_info = sector; + return rc; + } +next: + sector++; + ei_lba++; } + kunmap_local(daddr - dsg->offset); + kunmap_local(paddr - psg->offset); return 0; } EXPORT_SYMBOL(sbc_dif_verify); -- 2.34.1