FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.

» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Ubuntu > Ubuntu Kernel Team

LinkBack Thread Tools
Old 09-21-2012, 04:27 PM
Tim Gardner
Default sfc: Fix maximum number of TSO segments and minimum TX queue size

From: Ben Hutchings <ben@decadent.org.uk>


BugLink: http://bugs.launchpad.net/bugs/1037456

This is related to commit 7e6d06f0de3f74ca929441add094518ae332257c
upstream, but looks very different because:

- TX queue size was constant before 2.6.37, so we don't need to check it
- The upstream fix relies on changes to the TCP stack and networking
core, which are not appropriate for stable updates. Instead we limit
number of segments in efx_enqueue_skb_tso(). This effectively drops
all the extra packets and seriously hurts TCP throughput if the limit
is ever hit, but this shouldn't affect any legitimate traffic.

The original commit message is:

Currently an skb requiring TSO may not fit within a minimum-size TX
queue. The TX queue selected for the skb may stall and trigger the TX
watchdog repeatedly (since the problem skb will be retried after the
TX reset). This issue is designated as CVE-2012-3412.

Set the maximum number of TSO segments for our devices to 100. This
should make no difference to behaviour unless the actual MSS is less
than about 700. Increase the minimum TX queue size accordingly to
allow for 2 worst-case skbs, so that there will definitely be space
to add an skb after we wake a queue.

To avoid invalidating existing configurations, change
efx_ethtool_set_ringparam() to fix up values that are too small rather
than returning -EINVAL.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
drivers/net/sfc/efx.h | 3 +++
drivers/net/sfc/tx.c | 15 +++++++++++++++
2 files changed, 18 insertions(+)

diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h
index 8141c76..dc0bd22 100644
--- a/drivers/net/sfc/efx.h
+++ b/drivers/net/sfc/efx.h
@@ -45,6 +45,9 @@ extern void efx_wake_queue(struct efx_nic *efx);

+/* Maximum number of TCP segments we support for soft-TSO */
+#define EFX_TSO_MAX_SEGS 100
/* RX */
extern int efx_probe_rx_queue(struct efx_rx_queue *rx_queue);
extern void efx_remove_rx_queue(struct efx_rx_queue *rx_queue);
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c
index 585772b..7fdbf78 100644
--- a/drivers/net/sfc/tx.c
+++ b/drivers/net/sfc/tx.c
@@ -1072,6 +1072,21 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
int frag_i, rc, rc2 = NETDEV_TX_OK;
struct tso_state state;

+ /* Since the stack does not limit the number of segments per
+ * skb, we must do so. Otherwise an attacker may be able to
+ * make the TCP produce skbs that will never fit in our TX
+ * queue, causing repeated resets.
+ */
+ if (unlikely(skb_shinfo(skb)->gso_segs > EFX_TSO_MAX_SEGS)) {
+ unsigned int excess =
+ (skb_shinfo(skb)->gso_segs - EFX_TSO_MAX_SEGS) *
+ skb_shinfo(skb)->gso_size;
+ if (__pskb_trim(skb, skb->len - excess)) {
+ dev_kfree_skb_any(skb);
+ return NETDEV_TX_OK;
+ }
+ }
/* Find the packet protocol and sanity-check it */
state.protocol = efx_tso_check_protocol(skb);


kernel-team mailing list

Thread Tools

All times are GMT. The time now is 03:14 PM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org