aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000/e1000_main.c
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2010-01-19 09:15:38 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-20 19:21:22 -0500
commit40a14deaf411592b57cb0720f0e8004293ab9865 (patch)
treefc485d84b49042915e5d03a03f9bb988e8c3d175 /drivers/net/e1000/e1000_main.c
parentc1fa347f20f17f14a4a1575727fa24340e8a9117 (diff)
e1000: enhance frame fragment detection
Originally From: Neil Horman <nhorman@tuxdriver.com> Modified by: Jesse Brandeburg <jesse.brandeburg@intel.com> Hey all- A security discussion was recently given: http://events.ccc.de/congress/2009/Fahrplan//events/3596.en.html And a patch that I submitted awhile back was brought up. Apparently some of their testing revealed that they were able to force a buffer fragment in e1000 in which the trailing fragment was greater than 4 bytes. As a result the fragment check I introduced failed to detect the fragement and a partial invalid frame was passed up into the network stack. I've written this patch to correct it. I'm in the process of testing it now, but it makes good logical sense to me. Effectively it maintains a per-adapter state variable which detects a non-EOP frame, and discards it and subsequent non-EOP frames leading up to _and_ _including_ the next positive-EOP frame (as it is by definition the last fragment). This should prevent any and all partial frames from entering the network stack from e1000. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Acked-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-rw-r--r--drivers/net/e1000/e1000_main.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index b3f67b41627f..a53a2017c537 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3850,13 +3850,22 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
3850 3850
3851 length = le16_to_cpu(rx_desc->length); 3851 length = le16_to_cpu(rx_desc->length);
3852 /* !EOP means multiple descriptors were used to store a single 3852 /* !EOP means multiple descriptors were used to store a single
3853 * packet, also make sure the frame isn't just CRC only */ 3853 * packet, if thats the case we need to toss it. In fact, we
3854 if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) { 3854 * to toss every packet with the EOP bit clear and the next
3855 * frame that _does_ have the EOP bit set, as it is by
3856 * definition only a frame fragment
3857 */
3858 if (unlikely(!(status & E1000_RXD_STAT_EOP)))
3859 adapter->discarding = true;
3860
3861 if (adapter->discarding) {
3855 /* All receives must fit into a single buffer */ 3862 /* All receives must fit into a single buffer */
3856 E1000_DBG("%s: Receive packet consumed multiple" 3863 E1000_DBG("%s: Receive packet consumed multiple"
3857 " buffers\n", netdev->name); 3864 " buffers\n", netdev->name);
3858 /* recycle */ 3865 /* recycle */
3859 buffer_info->skb = skb; 3866 buffer_info->skb = skb;
3867 if (status & E1000_RXD_STAT_EOP)
3868 adapter->discarding = false;
3860 goto next_desc; 3869 goto next_desc;
3861 } 3870 }
3862 3871