]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.39/patches.drivers/fcoe-fix-frame-length-validati.diff
Updated kernel (2.6.27.41).
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.drivers / fcoe-fix-frame-length-validati.diff
diff --git a/src/patches/suse-2.6.27.39/patches.drivers/fcoe-fix-frame-length-validati.diff b/src/patches/suse-2.6.27.39/patches.drivers/fcoe-fix-frame-length-validati.diff
deleted file mode 100644 (file)
index f623dba..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-From: Chris Leech <christopher.leech@intel.com>
-Subject: [FcOE] fix frame length validation in the early receive path
-References: bnc #459142
-
-Validation of the frame length was missing before accessing the FC and FCoE
-headers.  Some of the later checks were bogus, because of the way the fr_len
-variable and skb->len were being manipulated they could never fail.
-
-Signed-off-by: Chris Leech <christopher.leech@intel.com>
-Acked-by: Bernhard Walle <bwalle@suse.de>
----
-
- drivers/scsi/fcoe/libfcoe.c |   48 +++++++++++++++++++++-----------------------
- include/scsi/fc/fc_fcoe.h   |   12 +++++++++++
- include/scsi/fc_frame.h     |    2 -
- 3 files changed, 36 insertions(+), 26 deletions(-)
-
-
---- a/drivers/scsi/fcoe/libfcoe.c
-+++ b/drivers/scsi/fcoe/libfcoe.c
-@@ -184,7 +184,6 @@ int fcoe_rcv(struct sk_buff *skb, struct
-       struct fcoe_rcv_info *fr;
-       struct fcoe_softc *fc;
-       struct fcoe_dev_stats *stats;
--      u8 *data;
-       struct fc_frame_header *fh;
-       unsigned short oxid;
-       int cpu_idx;
-@@ -211,9 +210,18 @@ int fcoe_rcv(struct sk_buff *skb, struct
-               FC_DBG("wrong FC type frame");
-               goto err;
-       }
--      data = skb->data;
--      data += sizeof(struct fcoe_hdr);
--      fh = (struct fc_frame_header *)data;
-+
-+      /*
-+       * Check for minimum frame length, and make sure required FCoE
-+       * and FC headers are pulled into the linear data area.
-+       */
-+      if (unlikely((skb->len < FCOE_MIN_FRAME) ||
-+          !pskb_may_pull(skb, FCOE_HEADER_LEN)))
-+              goto err;
-+
-+      skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
-+      fh = (struct fc_frame_header *) skb_transport_header(skb);
-+
-       oxid = ntohs(fh->fh_ox_id);
-       fr = fcoe_dev_from_skb(skb);
-@@ -514,8 +522,6 @@ int fcoe_percpu_receive_thread(void *arg
- {
-       struct fcoe_percpu_s *p = arg;
-       u32 fr_len;
--      unsigned int hlen;
--      unsigned int tlen;
-       struct fc_lport *lp;
-       struct fcoe_rcv_info *fr;
-       struct fcoe_dev_stats *stats;
-@@ -572,10 +578,12 @@ int fcoe_percpu_receive_thread(void *arg
-                       skb_linearize(skb);     /* not ideal */
-               /*
--               * Check the header and pull it off.
-+               * Frame length checks and setting up the header pointers
-+               * was done in fcoe_rcv already.
-                */
--              hlen = sizeof(struct fcoe_hdr);
--              hp = (struct fcoe_hdr *)skb->data;
-+              hp = (struct fcoe_hdr *) skb_network_header(skb);
-+              fh = (struct fc_frame_header *) skb_transport_header(skb);
-+
-               if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
-                       if (stats) {
-                               if (stats->ErrorFrames < 5)
-@@ -586,22 +594,10 @@ int fcoe_percpu_receive_thread(void *arg
-                       kfree_skb(skb);
-                       continue;
-               }
-+
-               skb_pull(skb, sizeof(struct fcoe_hdr));
--              tlen = sizeof(struct fcoe_crc_eof);
--              fr_len = skb->len - tlen;
--              skb_trim(skb, fr_len);
-+              fr_len = skb->len - sizeof(struct fcoe_crc_eof);
--              if (unlikely(fr_len > skb->len)) {
--                      if (stats) {
--                              if (stats->ErrorFrames < 5)
--                                      FC_DBG("length error fr_len 0x%x "
--                                             "skb->len 0x%x", fr_len,
--                                             skb->len);
--                              stats->ErrorFrames++;
--                      }
--                      kfree_skb(skb);
--                      continue;
--              }
-               if (stats) {
-                       stats->RxFrames++;
-                       stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
-@@ -610,9 +606,11 @@ 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_eof(fp) = cp->fcoe_eof;
--              fr_sof(fp) = hp->fcoe_sof;
-               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);
-               /*
-                * We only check CRC if no offload is available and if it is
---- a/include/scsi/fc/fc_fcoe.h
-+++ b/include/scsi/fc/fc_fcoe.h
-@@ -85,6 +85,18 @@ struct fcoe_crc_eof {
- } __attribute__((packed));
- /*
-+ * Minimum FCoE + FC header length
-+ * 14 bytes FCoE header + 24 byte FC header = 38 bytes
-+ */
-+#define FCOE_HEADER_LEN 38
-+
-+/*
-+ * Minimum FCoE frame size
-+ * 14 bytes FCoE header + 24 byte FC header + 8 byte FCoE trailer = 46 bytes
-+ */
-+#define FCOE_MIN_FRAME 46
-+
-+/*
-  * fc_fcoe_set_mac - Store OUI + DID into MAC address field.
-  * @mac: mac address to be set
-  * @did: fc dest id to use
---- a/include/scsi/fc_frame.h
-+++ b/include/scsi/fc_frame.h
-@@ -66,10 +66,10 @@ 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 */
-+      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 */
--      u16             fr_max_payload; /* max FC payload */
- };
- /*