]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/libfc-make-sure-we-access-the.diff
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / libfc-make-sure-we-access-the.diff
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/libfc-make-sure-we-access-the.diff b/src/patches/suse-2.6.27.31/patches.drivers/libfc-make-sure-we-access-the.diff
new file mode 100644 (file)
index 0000000..a1bba0c
--- /dev/null
@@ -0,0 +1,114 @@
+From: Chris Leech <christopher.leech@intel.com>
+Subject: [FcOE] make sure we access the CRC safely
+References: bnc #459142
+
+Even when fcoe verified that the EOF and CRC trailer bytes were there, when
+the CRC check was delayed for solicited SCSI data libfc would look past what
+was marked as valid data in the frame to find the CRC in the FCoE trailer.
+
+Instead, pass the CRC to libfc in the context block.
+
+Signed-off-by: Chris Leech <christopher.leech@intel.com>
+Acked-by: Bernhard Walle <bwalle@suse.de>
+---
+
+ drivers/scsi/fcoe/libfcoe.c   |   20 ++++++++++++++------
+ drivers/scsi/libfc/fc_fcp.c   |    2 +-
+ drivers/scsi/libfc/fc_frame.c |    2 +-
+ include/scsi/fc_frame.h       |    3 +++
+ 4 files changed, 19 insertions(+), 8 deletions(-)
+
+
+--- a/drivers/scsi/fcoe/libfcoe.c
++++ b/drivers/scsi/fcoe/libfcoe.c
+@@ -527,7 +527,7 @@ int fcoe_percpu_receive_thread(void *arg
+       struct fcoe_dev_stats *stats;
+       struct fc_frame_header *fh;
+       struct sk_buff *skb;
+-      struct fcoe_crc_eof *cp;
++      struct fcoe_crc_eof crc_eof;
+       struct fc_frame *fp;
+       u8 *mac = NULL;
+       struct fcoe_softc *fc;
+@@ -604,13 +604,21 @@ int fcoe_percpu_receive_thread(void *arg
+               }
+               fp = (struct fc_frame *)skb;
+-              cp = (struct fcoe_crc_eof *)(skb->data + fr_len);
+               fc_frame_init(fp);
+               fr_dev(fp) = lp;
+               fr_sof(fp) = hp->fcoe_sof;
+-              fr_eof(fp) = cp->fcoe_eof;
+-              /* trim off the CRC and EOF trailer*/
+-              skb_trim(skb, fr_len);
++
++              /* Copy out the CRC and EOF trailer for access */
++              if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
++                      kfree_skb(skb);
++                      continue;
++              }
++              fr_eof(fp) = crc_eof.fcoe_eof;
++              fr_crc(fp) = crc_eof.fcoe_crc32;
++              if (pskb_trim(skb, fr_len)) {
++                      kfree_skb(skb);
++                      continue;
++              }
+               /*
+                * We only check CRC if no offload is available and if it is
+@@ -629,7 +637,7 @@ int fcoe_percpu_receive_thread(void *arg
+                       continue;
+               }
+               if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
+-                      if (le32_to_cpu(cp->fcoe_crc32) !=
++                      if (le32_to_cpu(fr_crc(fp)) !=
+                           ~crc32(~0, skb->data, fr_len)) {
+                               if (debug_fcoe || stats->InvalidCRCCount < 5)
+                                       printk(KERN_WARNING "fcoe: dropping "
+--- a/drivers/scsi/libfc/fc_fcp.c
++++ b/drivers/scsi/libfc/fc_fcp.c
+@@ -356,7 +356,7 @@ static void fc_fcp_recv_data(struct fc_f
+                       len += 4 - (len % 4);
+               }
+-              if (~crc != le32_to_cpu(*(__le32 *)(buf + len))) {
++              if (~crc != le32_to_cpu(fr_crc(fp))) {
+ crc_err:
+                       stats = lp->dev_stats[smp_processor_id()];
+                       stats->ErrorFrames++;
+--- a/drivers/scsi/libfc/fc_frame.c
++++ b/drivers/scsi/libfc/fc_frame.c
+@@ -42,7 +42,7 @@ u32 fc_frame_crc_check(struct fc_frame *
+       len = (fr_len(fp) + 3) & ~3;    /* round up length to include fill */
+       bp = (const u8 *) fr_hdr(fp);
+       crc = ~crc32(~0, bp, len);
+-      error = crc ^ *(u32 *) (bp + len);
++      error = crc ^ fr_crc(fp);
+       return error;
+ }
+ EXPORT_SYMBOL(fc_frame_crc_check);
+--- a/include/scsi/fc_frame.h
++++ b/include/scsi/fc_frame.h
+@@ -56,6 +56,7 @@
+ #define fr_max_payload(fp)    (fr_cb(fp)->fr_max_payload)
+ #define fr_cmd(fp)    (fr_cb(fp)->fr_cmd)
+ #define fr_dir(fp)    (fr_cmd(fp)->sc_data_direction)
++#define fr_crc(fp)    (fr_cb(fp)->fr_crc)
+ struct fc_frame {
+       struct sk_buff skb;
+@@ -66,12 +67,14 @@ struct fcoe_rcv_info {
+       struct fc_lport *fr_dev;        /* transport layer private pointer */
+       struct fc_seq   *fr_seq;        /* for use with exchange manager */
+       struct scsi_cmnd *fr_cmd;       /* for use of scsi command */
++      u32             fr_crc;
+       u16             fr_max_payload; /* max FC payload */
+       enum fc_sof     fr_sof;         /* start of frame delimiter */
+       enum fc_eof     fr_eof;         /* end of frame delimiter */
+       u8              fr_flags;       /* flags - see below */
+ };
++
+ /*
+  * Get fc_frame pointer for an skb that's already been imported.
+  */