From nobody Fri Oct 2 10:54:03 2026 Received: from mail-pg1-f180.google.com (mail-pg1-f180.google.com [209.85.215.180]) (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 7325C29BDBB for ; Sat, 1 Aug 2026 13:36:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785591416; cv=none; b=JB2JVr3oHTVG5AqDJ5Eb7uEkHp6ZLX5F1+JJ1/QlmrYl05nojPu1MgqTwXg8Zmp/1iIR4SEHpAlc8aF9X5nZErDkZ/EDVyQIAhEwLYe+mXG3j76bWxcG5Cgp0mcf9jlGqh8x/OWnBcn0VKgNYNrjN6CC2rU91IfdJNgAXjIgP8Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785591416; c=relaxed/simple; bh=eB58HO5QK1YXyRAqhrYWSTOZcsExz4TPhNofK2YkZlA=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=rGutuvTtrAO3WppI9jSLLKNs1hX03xvz+A+eFtRO2A4xL+JwjOurlTF5ygHytL6qQC+1apJ6yTbxUz7BuclqEXGu+C5h0EMCdT7A7QZ5le4/iV+1d2YFu7KKnKf+mLEeHrqPVx8ABoL5+DcSklHq6XEL9qT7PKIeQA7uLnvxhHc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=isslab.korea.ac.kr; spf=none smtp.mailfrom=isslab.korea.ac.kr; dkim=pass (2048-bit key) header.d=isslab-korea-ac-kr.20251104.gappssmtp.com header.i=@isslab-korea-ac-kr.20251104.gappssmtp.com header.b=F6LeQmu4; arc=none smtp.client-ip=209.85.215.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=isslab.korea.ac.kr Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=isslab.korea.ac.kr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=isslab-korea-ac-kr.20251104.gappssmtp.com header.i=@isslab-korea-ac-kr.20251104.gappssmtp.com header.b="F6LeQmu4" Received: by mail-pg1-f180.google.com with SMTP id 41be03b00d2f7-cbe3fed2f58so573142a12.3 for ; Sat, 01 Aug 2026 06:36:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=isslab-korea-ac-kr.20251104.gappssmtp.com; s=20251104; t=1785591411; x=1786196211; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=upVI1OEGifNaxUYsdgzmCaYduKWqMNtXXmGmafq6qHQ=; b=F6LeQmu4MAj2IN1Wjh4xt+n+h/ye25jIM74vLVy1zyLbZQXqiyHCrUWc9pJRGJkF5b B2ZpbuL1T/1TcjxgZAWDSaaMRg982JbBYnCSC9B1lqrkqbvcCndcQH7ILvJe3ENrmIIp 1f9iadfJbRzAcbX6MEKmCR7vr/lGopeGrvY2dhpi8d+hCADogvMHXcGRLmDUg4mObdNO 6FetkXGRpdvy6yW5ZqFuROdOfXkkG4gKsM5kCWhAokoAMk/buxbJaflDwFvejWMBQDvE zCvBenbNMI3SwS0N8ypqD7Zemjfz39imFwiUNEsrhTt72TarzzIZglP01W/NBQqZogDa PBuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1785591412; x=1786196212; h=content-transfer-encoding:mime-version: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=upVI1OEGifNaxUYsdgzmCaYduKWqMNtXXmGmafq6qHQ=; b=QysDQDqoTX96eeNSczgqWoVOyexOLOs+hmmlcbtIYlQib9x2Oe+US9f5JM7N1WYEUa xFCXIk0yLsc/hLMrVpTQJdDXz01INcEuwVPJa3mPk9KmfhLgKYftVT2y0CqNKChpJZfb LaT/6J/LKj9lLkm0I7iAyEz/OiPWNR74v44E0rT5BmqghLPm/KK9rxqEMP7rB2t19Bh7 5Jr0zV+lpR7n/0/PK8Xra4uWYg7wmV73TPmBpwTmxxNFjUjSckAeLTlLVTxvb1bt2e1H /AmIrhLS8Nf7O+Lu41nwLfsGcKPfYegdxg+wJrBSsVa5utvCSg4/+WWi2WKlpuGNwK4b Dibw== X-Forwarded-Encrypted: i=1; AHgh+Rom28CTY5DEZgbqk2MuVT0COClkb/9TF1GCMOqwfM9pNG9vMqeaDgISazhFJlI8UNpVO7JIL1jcZtThPVM=@vger.kernel.org X-Gm-Message-State: AOJu0Yzd4g9dApcEGjQHOXdhxldxrpjs7u3H9n6lCEZxAnMN04L9vmZA ASKl8Vs9sW+bAgPSVnRv6n0pIriCYHvbQPBy5eUo2fOGgkPl01ren5zgEaamy7o2f3Q= X-Gm-Gg: AR+sD12wsI9XO7MPtbjzcHdNYwkm+gH8BlIfJWqAOlzQufIV9Ta4j1tseboHJgOaNQp FxLpDE0MFxNx3QjaIICRO6sbMxinLAiqeBTXXKUciIjQ1OwRUfNaIQdE/p5IdYyufwbuQof24SO RDiOzBV/NVk+A4oNVwCag2ILH9Q4UTtv+KsseqbNE/jNPY3xLwP8+kEdtLr41lh/O7nUXiJq+h5 tFCLDmLOoM2Zl7GnarJbiiAJvx1LtI+ImUd/6zefz0L34bB9JjGI9CwBs2gfG8sF21XmoJYHy21 jsoe2TH4bUQfsNpHb5G7vwvY9cVY1FYdN9dWjvVXoj9Qs0rKK+GQ66/6GfP3ItoYa9Q0yig9Kk/ C185eslLWmH/zj4aAbgnVObU96sEYxnC8wYAhGfIM21z2CxkvtMs7XIR4B+9Kvb7WSMI+7kxfNB PbIE5j3Te0kT3wWRThkGkP7PnC9ucQVcCuFGpY0uWYHcFD1jjEnOJKGtxve+YBrJT8X7ksR8X6A +KcClcnOGbe4STFuWlHZg== X-Received: by 2002:a05:6a21:6e92:b0:3c0:f772:8128 with SMTP id adf61e73a8af0-3c92a889548mr3898837637.54.1785591411530; Sat, 01 Aug 2026 06:36:51 -0700 (PDT) Received: from localhost.localdomain ([2406:5900:1044:110c:c329:7b28:fe02:5dc8]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-cbe39ea9c50sm1697375a12.27.2026.08.01.06.36.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Aug 2026 06:36:51 -0700 (PDT) From: Yehyeong Lee To: lduncan@suse.com, cleech@redhat.com, michael.christie@oracle.com, James.Bottomley@HansenPartnership.com, martin.petersen@oracle.com Cc: open-iscsi@googlegroups.com, linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, Yehyeong Lee , stable@vger.kernel.org Subject: [PATCH] scsi: libiscsi_tcp: check the data direction of a Data-In PDU Date: Sat, 1 Aug 2026 22:36:35 +0900 Message-ID: <20260801133635.1986706-1-yhlee@isslab.korea.ac.kr> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Data-In branch of iscsi_tcp_hdr_dissect() resolves the ITT to a task and copies the PDU's data segment into that command's scatterlist without asking whether the command was reading. iscsi_tcp_r2t_rsp() in the same file does ask, and rejects an R2T for a command that is not DMA_TO_DEVICE. A target that answers a WRITE command's ITT with a Data-In therefore has the initiator write target-supplied bytes into the pages that write was about to send. Those are the caller's own pinned pages for an O_DIRECT write, and page cache pages for a buffered one. Observed against a test target that emits one 512-byte Data-In naming a 128 KB write's ITT, after the R2T for that write. With O_DIRECT the caller's buffer ends up holding 512 bytes of the target's data while pwrite() returns 131072. Buffered is quieter: pwrite() and fsync() both succeed, nothing is logged, and reading those blocks back returns the target's bytes out of the page cache without a command going on the wire. Check the direction before using the scatterlist, the way the R2T path already does. Cc: stable@vger.kernel.org Signed-off-by: Yehyeong Lee Reviewed-by: Mike Christie --- Reproduced on v7.2-rc5 with the in-tree initiator over TCP against tgt 1.0.= 97 on loopback, HeaderDigest and DataDigest both None, InitialR2T=3DYes, ImmediateData=3DYes, FirstBurstLength=3D65536, MaxXmitDataSegmentLength=3D8= 192. A 128 KB O_DIRECT write goes out as 8192 bytes of immediate data, one R2T f= or the remaining 122880 at offset 8192, and 15 Data-Out PDUs. The test target inserts one Data-In after that R2T: ITT of the write, DataSN 1, buffer offs= et 8192, 512 bytes, no S bit. Its payload is a repeating 16-byte marker so the extent can be measured exactly. arm caller's buffer after pwrite() target backing st= ore no injection marker 0, non-0x5a 0 of 131072 0x5a 8192 of 8192 injection marker 32 at offset 8192, marker 32, non-0x5a 512 of 131072 0x5a 7680 of 8192 injection, patched marker 0, non-0x5a 0 of 131072 marker 0 pwrite() returns 131072 in the first two rows. With the patch the PDU is rejected with ISCSI_ERR_PROTO, the same return the R2T path uses for the sa= me kind of violation, and the write fails. Two runs per arm; a 4 KB write and the 128 KB write both still complete normally on the patched kernel. The same injection against a buffered write of the same size: arm read back after fsync() target backing store no injection marker 0, non-0x5a 0 of 131072 0x5a 131072 of 131072 injection marker 32 at offset 8192, marker 32, 0x5a 1305= 60 non-0x5a 512 of 131072 injection, patched marker 0 nothing written pwrite() and fsync() both return success in the first two rows and nothing = is logged. The read back uses a descriptor opened before the write and puts no command on the wire -- bracketing it with a 512-byte O_DIRECT read at a fix= ed LBA shows nothing in between on the target side -- so those bytes come out = of the page cache. With the patch fsync() fails with EIO and the write does n= ot land. Injecting at offset 126976 instead of 8192 behaves the same. Eight runs of the injected arm at offset 8192 and six at 126976. The read back was corrupt in every one. drivers/scsi/libiscsi_tcp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index e90805ba868f..0283c4444cd0 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -480,6 +480,9 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, s= truct iscsi_task *task) int datasn =3D be32_to_cpu(rhdr->datasn); unsigned total_in_length =3D task->sc->sdb.length; =20 + if (task->sc->sc_data_direction !=3D DMA_FROM_DEVICE) + return ISCSI_ERR_PROTO; + /* * lib iscsi will update this in the completion handling if there * is status. --=20 2.43.0