public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Ian Campbell <ian.campbell@citrix.com>,
	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>,
	Jan Beulich <JBeulich@suse.com>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 27/86] xen/netback: shutdown the ring if it contains garbage.
Date: Tue, 26 Mar 2013 13:21:26 -0400	[thread overview]
Message-ID: <20130326173604.209769776@goodmis.org> (raw)
In-Reply-To: 20130326172059.136127374@goodmis.org

[-- Attachment #1: 0027-xen-netback-shutdown-the-ring-if-it-contains-garbage.patch --]
[-- Type: text/plain, Size: 8349 bytes --]

3.6.11.1 stable review patch.
If anyone has any objections, please let me know.

------------------

From: Ian Campbell <Ian.Campbell@citrix.com>

[ Upstream commit 48856286b64e4b66ec62b94e504d0b29c1ade664 ]

A buggy or malicious frontend should not be able to confuse netback.
If we spot anything which is not as it should be then shutdown the
device and don't try to continue with the ring in a potentially
hostile state. Well behaved and non-hostile frontends will not be
penalised.

As well as making the existing checks for such errors fatal also add a
new check that ensures that there isn't an insane number of requests
on the ring (i.e. more than would fit in the ring). If the ring
contains garbage then previously is was possible to loop over this
insane number, getting an error each time and therefore not generating
any more pending requests and therefore not exiting the loop in
xen_netbk_tx_build_gops for an externded period.

Also turn various netdev_dbg calls which no precipitate a fatal error
into netdev_err, they are rate limited because the device is shutdown
afterwards.

This fixes at least one known DoS/softlockup of the backend domain.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Acked-by: Jan Beulich <JBeulich@suse.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
 drivers/net/xen-netback/common.h    |    3 ++
 drivers/net/xen-netback/interface.c |   23 ++++++++-----
 drivers/net/xen-netback/netback.c   |   62 +++++++++++++++++++++++++----------
 3 files changed, 62 insertions(+), 26 deletions(-)

diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 94b79c3..9d7f172 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -151,6 +151,9 @@ void xen_netbk_queue_tx_skb(struct xenvif *vif, struct sk_buff *skb);
 /* Notify xenvif that ring now has space to send an skb to the frontend */
 void xenvif_notify_tx_completion(struct xenvif *vif);
 
+/* Prevent the device from generating any further traffic. */
+void xenvif_carrier_off(struct xenvif *vif);
+
 /* Returns number of ring slots required to send an skb to the frontend */
 unsigned int xen_netbk_count_skb_slots(struct xenvif *vif, struct sk_buff *skb);
 
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index b7d41f8..b8c5193 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -343,17 +343,22 @@ err:
 	return err;
 }
 
-void xenvif_disconnect(struct xenvif *vif)
+void xenvif_carrier_off(struct xenvif *vif)
 {
 	struct net_device *dev = vif->dev;
-	if (netif_carrier_ok(dev)) {
-		rtnl_lock();
-		netif_carrier_off(dev); /* discard queued packets */
-		if (netif_running(dev))
-			xenvif_down(vif);
-		rtnl_unlock();
-		xenvif_put(vif);
-	}
+
+	rtnl_lock();
+	netif_carrier_off(dev); /* discard queued packets */
+	if (netif_running(dev))
+		xenvif_down(vif);
+	rtnl_unlock();
+	xenvif_put(vif);
+}
+
+void xenvif_disconnect(struct xenvif *vif)
+{
+	if (netif_carrier_ok(vif->dev))
+		xenvif_carrier_off(vif);
 
 	atomic_dec(&vif->refcnt);
 	wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0);
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 682633b..efdbf8f 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -859,6 +859,13 @@ static void netbk_tx_err(struct xenvif *vif,
 	xenvif_put(vif);
 }
 
+static void netbk_fatal_tx_err(struct xenvif *vif)
+{
+	netdev_err(vif->dev, "fatal error; disabling device\n");
+	xenvif_carrier_off(vif);
+	xenvif_put(vif);
+}
+
 static int netbk_count_requests(struct xenvif *vif,
 				struct xen_netif_tx_request *first,
 				struct xen_netif_tx_request *txp,
@@ -872,19 +879,22 @@ static int netbk_count_requests(struct xenvif *vif,
 
 	do {
 		if (frags >= work_to_do) {
-			netdev_dbg(vif->dev, "Need more frags\n");
+			netdev_err(vif->dev, "Need more frags\n");
+			netbk_fatal_tx_err(vif);
 			return -frags;
 		}
 
 		if (unlikely(frags >= MAX_SKB_FRAGS)) {
-			netdev_dbg(vif->dev, "Too many frags\n");
+			netdev_err(vif->dev, "Too many frags\n");
+			netbk_fatal_tx_err(vif);
 			return -frags;
 		}
 
 		memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags),
 		       sizeof(*txp));
 		if (txp->size > first->size) {
-			netdev_dbg(vif->dev, "Frags galore\n");
+			netdev_err(vif->dev, "Frag is bigger than frame.\n");
+			netbk_fatal_tx_err(vif);
 			return -frags;
 		}
 
@@ -892,8 +902,9 @@ static int netbk_count_requests(struct xenvif *vif,
 		frags++;
 
 		if (unlikely((txp->offset + txp->size) > PAGE_SIZE)) {
-			netdev_dbg(vif->dev, "txp->offset: %x, size: %u\n",
+			netdev_err(vif->dev, "txp->offset: %x, size: %u\n",
 				 txp->offset, txp->size);
+			netbk_fatal_tx_err(vif);
 			return -frags;
 		}
 	} while ((txp++)->flags & XEN_NETTXF_more_data);
@@ -1066,7 +1077,8 @@ static int xen_netbk_get_extras(struct xenvif *vif,
 
 	do {
 		if (unlikely(work_to_do-- <= 0)) {
-			netdev_dbg(vif->dev, "Missing extra info\n");
+			netdev_err(vif->dev, "Missing extra info\n");
+			netbk_fatal_tx_err(vif);
 			return -EBADR;
 		}
 
@@ -1075,8 +1087,9 @@ static int xen_netbk_get_extras(struct xenvif *vif,
 		if (unlikely(!extra.type ||
 			     extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) {
 			vif->tx.req_cons = ++cons;
-			netdev_dbg(vif->dev,
+			netdev_err(vif->dev,
 				   "Invalid extra type: %d\n", extra.type);
+			netbk_fatal_tx_err(vif);
 			return -EINVAL;
 		}
 
@@ -1092,13 +1105,15 @@ static int netbk_set_skb_gso(struct xenvif *vif,
 			     struct xen_netif_extra_info *gso)
 {
 	if (!gso->u.gso.size) {
-		netdev_dbg(vif->dev, "GSO size must not be zero.\n");
+		netdev_err(vif->dev, "GSO size must not be zero.\n");
+		netbk_fatal_tx_err(vif);
 		return -EINVAL;
 	}
 
 	/* Currently only TCPv4 S.O. is supported. */
 	if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
-		netdev_dbg(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type);
+		netdev_err(vif->dev, "Bad GSO type %d.\n", gso->u.gso.type);
+		netbk_fatal_tx_err(vif);
 		return -EINVAL;
 	}
 
@@ -1235,9 +1250,25 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)
 
 		/* Get a netif from the list with work to do. */
 		vif = poll_net_schedule_list(netbk);
+		/* This can sometimes happen because the test of
+		 * list_empty(net_schedule_list) at the top of the
+		 * loop is unlocked.  Just go back and have another
+		 * look.
+		 */
 		if (!vif)
 			continue;
 
+		if (vif->tx.sring->req_prod - vif->tx.req_cons >
+		    XEN_NETIF_TX_RING_SIZE) {
+			netdev_err(vif->dev,
+				   "Impossible number of requests. "
+				   "req_prod %d, req_cons %d, size %ld\n",
+				   vif->tx.sring->req_prod, vif->tx.req_cons,
+				   XEN_NETIF_TX_RING_SIZE);
+			netbk_fatal_tx_err(vif);
+			continue;
+		}
+
 		RING_FINAL_CHECK_FOR_REQUESTS(&vif->tx, work_to_do);
 		if (!work_to_do) {
 			xenvif_put(vif);
@@ -1265,17 +1296,14 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)
 			work_to_do = xen_netbk_get_extras(vif, extras,
 							  work_to_do);
 			idx = vif->tx.req_cons;
-			if (unlikely(work_to_do < 0)) {
-				netbk_tx_err(vif, &txreq, idx);
+			if (unlikely(work_to_do < 0))
 				continue;
-			}
 		}
 
 		ret = netbk_count_requests(vif, &txreq, txfrags, work_to_do);
-		if (unlikely(ret < 0)) {
-			netbk_tx_err(vif, &txreq, idx - ret);
+		if (unlikely(ret < 0))
 			continue;
-		}
+
 		idx += ret;
 
 		if (unlikely(txreq.size < ETH_HLEN)) {
@@ -1287,11 +1315,11 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)
 
 		/* No crossing a page as the payload mustn't fragment. */
 		if (unlikely((txreq.offset + txreq.size) > PAGE_SIZE)) {
-			netdev_dbg(vif->dev,
+			netdev_err(vif->dev,
 				   "txreq.offset: %x, size: %u, end: %lu\n",
 				   txreq.offset, txreq.size,
 				   (txreq.offset&~PAGE_MASK) + txreq.size);
-			netbk_tx_err(vif, &txreq, idx);
+			netbk_fatal_tx_err(vif);
 			continue;
 		}
 
@@ -1319,8 +1347,8 @@ static unsigned xen_netbk_tx_build_gops(struct xen_netbk *netbk)
 			gso = &extras[XEN_NETIF_EXTRA_TYPE_GSO - 1];
 
 			if (netbk_set_skb_gso(vif, skb, gso)) {
+				/* Failure in netbk_set_skb_gso is fatal. */
 				kfree_skb(skb);
-				netbk_tx_err(vif, &txreq, idx);
 				continue;
 			}
 		}
-- 
1.7.10.4



  parent reply	other threads:[~2013-03-26 17:58 UTC|newest]

Thread overview: 91+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-26 17:20 [PATCH 00/86] [ANNOUNCE] The new 3.6.11.x short-term extended stable series (stable review) Steven Rostedt
2013-03-26 17:21 ` [PATCH 01/86] sparc: huge_ptep_set_* functions need to call set_huge_pte_at() Steven Rostedt
2013-03-26 17:21 ` [PATCH 02/86] batman-adv: fix random jitter calculation Steven Rostedt
2013-03-26 17:21 ` [PATCH 03/86] inet: Fix kmemleak in tcp_v4/6_syn_recv_sock and dccp_v4/6_request_recv_sock Steven Rostedt
2013-03-26 17:21 ` [PATCH 04/86] net: sched: integer overflow fix Steven Rostedt
2013-03-26 17:21 ` [PATCH 05/86] tcp: fix MSG_SENDPAGE_NOTLAST logic Steven Rostedt
2013-03-26 17:21 ` [PATCH 06/86] tcp: tcp_replace_ts_recent() should not be called from tcp_validate_incoming() Steven Rostedt
2013-03-26 17:21 ` [PATCH 07/86] tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation Steven Rostedt
2013-03-26 17:21 ` [PATCH 08/86] net: prevent setting ttl=0 via IP_TTL Steven Rostedt
2013-03-26 17:21 ` [PATCH 09/86] ipv6: fix the noflags test in addrconf_get_prefix_route Steven Rostedt
2013-03-26 17:21 ` [PATCH 10/86] MAINTAINERS: Stephen Hemminger email change Steven Rostedt
2013-03-26 17:21 ` [PATCH 11/86] ipv6: fix header length calculation in ip6_append_data() Steven Rostedt
2013-03-26 17:21 ` [PATCH 12/86] net: calxedaxgmac: throw away overrun frames Steven Rostedt
2013-03-26 17:21 ` [PATCH 13/86] net/mlx4_en: Fix bridged vSwitch configuration for non SRIOV mode Steven Rostedt
2013-03-26 17:21 ` [PATCH 14/86] net/mlx4_core: Set number of msix vectors under SRIOV mode to firmware defaults Steven Rostedt
2013-03-26 17:21 ` [PATCH 15/86] isdn/gigaset: fix zero size border case in debug dump Steven Rostedt
2013-03-26 17:21 ` [PATCH 16/86] netxen: fix off by one bug in netxen_release_tx_buffer() Steven Rostedt
2013-03-26 17:21 ` [PATCH 17/86] r8169: remove the obsolete and incorrect AMD workaround Steven Rostedt
2013-03-26 17:21 ` [PATCH 18/86] net: loopback: fix a dst refcounting issue Steven Rostedt
2013-03-26 17:21 ` [PATCH 19/86] pktgen: correctly handle failures when adding a device Steven Rostedt
2013-03-26 17:21 ` [PATCH 20/86] ipv6: do not create neighbor entries for local delivery Steven Rostedt
2013-03-26 17:21 ` [PATCH 21/86] via-rhine: Fix bugs in NAPI support Steven Rostedt
2013-03-26 17:21 ` [PATCH 22/86] packet: fix leakage of tx_ring memory Steven Rostedt
2013-03-26 17:21 ` [PATCH 23/86] atm/iphase: rename fregt_t -> ffreg_t Steven Rostedt
2013-03-26 17:21 ` [PATCH 24/86] sctp: refactor sctp_outq_teardown to insure proper re-initalization Steven Rostedt
2013-03-26 17:21 ` [PATCH 25/86] net: sctp: sctp_setsockopt_auth_key: use kzfree instead of kfree Steven Rostedt
2013-03-26 17:21 ` [PATCH 26/86] net: sctp: sctp_endpoint_free: zero out secret key data Steven Rostedt
2013-03-26 17:21 ` Steven Rostedt [this message]
2013-03-26 17:21 ` [PATCH 28/86] xen/netback: dont leak pages on failure in xen_netbk_tx_check_gop Steven Rostedt
2013-03-26 17:21 ` [PATCH 29/86] xen/netback: free already allocated memory on failure in xen_netbk_get_requests Steven Rostedt
2013-03-26 17:21 ` [PATCH 30/86] netback: correct netbk_tx_err to handle wrap around Steven Rostedt
2013-03-26 17:21 ` [PATCH 31/86] tcp: frto should not set snd_cwnd to 0 Steven Rostedt
2013-03-26 17:21 ` [PATCH 32/86] tcp: fix for zero packets_in_flight was too broad Steven Rostedt
2013-03-26 17:21 ` [PATCH 33/86] bridge: Pull ip header into skb->data before looking into ip header Steven Rostedt
2013-03-26 17:21 ` [PATCH 34/86] tg3: Avoid null pointer dereference in tg3_interrupt in netconsole mode Steven Rostedt
2013-03-26 17:21 ` [PATCH 35/86] tg3: Fix crc errors on jumbo frame receive Steven Rostedt
2013-03-26 17:21 ` [PATCH 36/86] sunvdc: Fix off-by-one in generic_request() Steven Rostedt
2013-03-26 17:21 ` [PATCH 37/86] bridge: set priority of STP packets Steven Rostedt
2013-03-26 17:21 ` [PATCH 38/86] net: fix infinite loop in __skb_recv_datagram() Steven Rostedt
2013-03-26 17:21 ` [PATCH 39/86] xen-netback: correctly return errors from netbk_count_requests() Steven Rostedt
2013-03-26 17:21 ` [PATCH 40/86] xen-netback: cancel the credit timer when taking the vif down Steven Rostedt
2013-03-26 17:21 ` [PATCH 41/86] net: fix a compile error when SOCK_REFCNT_DEBUG is enabled Steven Rostedt
2013-03-26 17:21 ` [PATCH 42/86] ipv4: fix a bug in ping_err() Steven Rostedt
2013-03-26 17:21 ` [PATCH 43/86] ipv6: use a stronger hash for tcp Steven Rostedt
2013-03-26 17:21 ` [PATCH 44/86] sock_diag: Fix out-of-bounds access to sock_diag_handlers[] Steven Rostedt
2013-03-26 17:21 ` [PATCH 45/86] vlan: adjust vlan_set_encap_proto() for its callers Steven Rostedt
2013-03-26 17:21 ` [PATCH 46/86] l2tp: Restore socket refcount when sendmsg succeeds Steven Rostedt
2013-03-26 17:21 ` [PATCH 47/86] rds: limit the size allocated by rds_message_alloc() Steven Rostedt
2013-03-26 17:21 ` [PATCH 48/86] net: ipv6: Dont purge default router if accept_ra=2 Steven Rostedt
2013-03-26 17:21 ` [PATCH 49/86] tcp: fix double-counted receiver RTT when leaving receiver fast path Steven Rostedt
2013-03-26 17:21 ` [PATCH 50/86] tun: add a missing nf_reset() in tun_net_xmit() Steven Rostedt
2013-03-26 17:21 ` [PATCH 51/86] macvlan: Set IFF_UNICAST_FLT flag to prevent unnecessary promisc mode Steven Rostedt
2013-03-26 17:21 ` [PATCH 52/86] netlabel: fix build problems when CONFIG_IPV6=n Steven Rostedt
2013-03-26 17:21 ` [PATCH 53/86] netlabel: correctly list all the static label mappings Steven Rostedt
2013-03-26 17:21 ` [PATCH 54/86] bridging: fix rx_handlers return code Steven Rostedt
2013-03-26 17:21 ` [PATCH 55/86] ipv6: stop multicast forwarding to process interface scoped addresses Steven Rostedt
2013-03-26 17:21 ` [PATCH 56/86] rtnl: fix info leak on RTM_GETLINK request for VF devices Steven Rostedt
2013-03-26 17:21 ` [PATCH 57/86] dcbnl: fix various netlink info leaks Steven Rostedt
2013-03-26 17:21 ` [PATCH 58/86] 6lowpan: Fix endianness issue in is_addr_link_local() Steven Rostedt
2013-03-26 17:21 ` [PATCH 59/86] ipv6: Change skb->data before using icmpv6_notify() to propagate redirect Steven Rostedt
2013-03-26 17:21 ` [PATCH 60/86] mac802154: fix NOHZ local_softirq_pending 08 warning Steven Rostedt
2013-03-26 17:22 ` [PATCH 61/86] sctp: jsctp_sf_eat_sack: fix jprobes function signature mismatch Steven Rostedt
2013-03-26 17:22 ` [PATCH 62/86] macvlan: fix macvlan_get_size() Steven Rostedt
2013-03-26 17:22 ` [PATCH 63/86] tcp: fix incorrect LOCKDROPPEDICMPS counter Steven Rostedt
2013-03-26 17:22 ` [PATCH 64/86] IP_GRE: Fix kernel panic in IP_GRE with GRE csum Steven Rostedt
2013-03-27  4:28   ` Ben Hutchings
2013-03-27  4:35     ` Steven Rostedt
2013-03-26 17:22 ` [PATCH 65/86] ipv4: Remove output route check in ipv4_mtu Steven Rostedt
2013-03-26 17:22 ` [PATCH 66/86] ipv4: Dont update the pmtu on mtu locked routes Steven Rostedt
2013-03-26 17:22 ` [PATCH 67/86] ipv6: Add an error handler for icmp6 Steven Rostedt
2013-03-26 17:22 ` [PATCH 68/86] ipv4: Invalidate the socket cached route on pmtu events if possible Steven Rostedt
2013-03-26 17:22 ` [PATCH 69/86] ipv4: Add a socket release callback for datagram sockets Steven Rostedt
2013-03-26 17:22 ` [PATCH 70/86] ipv4: Fix route refcount on pmtu discovery Steven Rostedt
2013-03-26 17:22 ` [PATCH 71/86] tcp: detect SYN/data drop when F-RTO is disabled Steven Rostedt
2013-03-26 17:22 ` [PATCH 72/86] tcp: fix an infinite loop in tcp_slow_start() Steven Rostedt
2013-03-26 17:22 ` [PATCH 73/86] tcp: dont abort splice() after small transfers Steven Rostedt
2013-03-26 17:22 ` [PATCH 74/86] tcp: splice: fix an infinite loop in tcp_read_sock() Steven Rostedt
2013-03-26 17:22 ` [PATCH 75/86] tcp: fix splice() and tcp collapsing interaction Steven Rostedt
2013-03-26 17:22 ` [PATCH 76/86] net: splice: avoid high order page splitting Steven Rostedt
2013-03-26 17:22 ` [PATCH 77/86] net: splice: fix __splice_segment() Steven Rostedt
2013-03-26 17:22 ` [PATCH 78/86] sparc64: Add missing HAVE_ARCH_TRANSPARENT_HUGEPAGE Steven Rostedt
2013-03-26 17:22 ` [PATCH 79/86] sparc64: Fix gfp_flags setting in tsb_grow() Steven Rostedt
2013-03-26 17:22 ` [PATCH 80/86] xfrm: release neighbor upon dst destruction Steven Rostedt
2013-03-26 17:22 ` [PATCH 81/86] ppp: set qdisc_tx_busylock to avoid LOCKDEP splat Steven Rostedt
2013-03-26 17:22 ` [PATCH 82/86] ipv6: fix race condition regarding dst->expires and dst->from Steven Rostedt
2013-03-26 17:22 ` [PATCH 83/86] ipv4: fix error handling in icmp_protocol Steven Rostedt
2013-03-26 17:22 ` [PATCH 84/86] tcp: fix SYN-data space mis-accounting Steven Rostedt
2013-03-26 17:22 ` [PATCH 85/86] mlx4_en: fix allocation of CPU affinity reverse-map Steven Rostedt
2013-03-28  8:47   ` Amir Vadai
2013-03-26 17:22 ` [PATCH 86/86] team: unsyc the devices addresses when port is removed Steven Rostedt
2013-03-26 17:46 ` [PATCH 00/86] [ANNOUNCE] The new 3.6.11.x short-term extended stable series (stable review) Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130326173604.209769776@goodmis.org \
    --to=rostedt@goodmis.org \
    --cc=JBeulich@suse.com \
    --cc=davem@davemloft.net \
    --cc=ian.campbell@citrix.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox