Blob Blame History Raw
From: Bart van Assche <bart.vanassche@sandisk.com>
Date: Fri, 5 Aug 2016 08:36:12 +0200
Subject: target: work around data corruption issue in tfc_io
References: bsc#990245
Patch-Mainline: submitted linux-target 2016/08/05

Bart found a subtle data corruption issue in tfc_io.c; skbs are
sent asynchronously but the data will be freed as soon as the
final status is generated.
This can lead to data corruption as data might be freed while
the skbs are still queued.

Signed-off-by: Bart van Assche <bart.vanassche@sandisk.com>
Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/target/tcm_fc/tfc_io.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/target/tcm_fc/tfc_io.c b/drivers/target/tcm_fc/tfc_io.c
index 6f7c65a..f4821da 100644
--- a/drivers/target/tcm_fc/tfc_io.c
+++ b/drivers/target/tcm_fc/tfc_io.c
@@ -97,9 +97,21 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
 		page = sg_page(sg);
 	}
 
+#if 0
 	/* no scatter/gather in skb for odd word length due to fc_seq_send() */
 	use_sg = !(remaining % 4);
-
+#else
+	/*
+	 * Note: since libfc_function_template.seq_send() sends frames
+	 * asynchronously and since the SCST data buffer is freed as soon as
+	 * scst_tgt_cmd_done() has been invoked, data has to be copied into
+	 * the skb instead of only copying a pointer to the data. To do: defer
+	 * invocation of scst_tgt_cmd_done() until sending the data frames
+	 * finished once the paged fragment destructor or an equivalent is
+	 * upstream.
+	 */
+	use_sg = false;
+#endif
 	while (remaining) {
 		struct fc_seq *seq = cmd->seq;
 
-- 
1.8.5.6