aboutsummaryrefslogtreecommitdiffstats
path: root/main/linux-grsec/xsa39-pvops-0001-xen-netback-shutdown-the-ring-if-it-contains-garbage.patch
diff options
context:
space:
mode:
authorNatanael Copa <ncopa@alpinelinux.org>2013-03-01 10:30:27 +0000
committerNatanael Copa <ncopa@alpinelinux.org>2013-03-01 12:43:13 +0000
commitb9cbd017e432ec37dc412188593393a3edc8032c (patch)
treeb77e06bd5d5c9e1648783c474f7655ab9687f534 /main/linux-grsec/xsa39-pvops-0001-xen-netback-shutdown-the-ring-if-it-contains-garbage.patch
parent6f73908b67b80410b08d2a5b8a96e6d866da70b1 (diff)
downloadaports-b9cbd017e432ec37dc412188593393a3edc8032c.tar.bz2
aports-b9cbd017e432ec37dc412188593393a3edc8032c.tar.xz
main/linux-grsec: port stable fixes up to 3.4.34
Diffstat (limited to 'main/linux-grsec/xsa39-pvops-0001-xen-netback-shutdown-the-ring-if-it-contains-garbage.patch')
-rw-r--r--main/linux-grsec/xsa39-pvops-0001-xen-netback-shutdown-the-ring-if-it-contains-garbage.patch253
1 files changed, 0 insertions, 253 deletions
diff --git a/main/linux-grsec/xsa39-pvops-0001-xen-netback-shutdown-the-ring-if-it-contains-garbage.patch b/main/linux-grsec/xsa39-pvops-0001-xen-netback-shutdown-the-ring-if-it-contains-garbage.patch
deleted file mode 100644
index 3f983028f2..0000000000
--- a/main/linux-grsec/xsa39-pvops-0001-xen-netback-shutdown-the-ring-if-it-contains-garbage.patch
+++ /dev/null
@@ -1,253 +0,0 @@
-From 7dd7ce44593a8c4c715fa665027af8e07245c8cf Mon Sep 17 00:00:00 2001
-From: Ian Campbell <ian.campbell@citrix.com>
-Date: Fri, 11 Jan 2013 14:26:29 +0000
-Subject: [PATCH 1/4] xen/netback: shutdown the ring if it contains garbage.
-
-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>
----
- drivers/net/xen-netback/common.h | 3 ++
- drivers/net/xen-netback/interface.c | 23 ++++++++-----
- drivers/net/xen-netback/netback.c | 63 +++++++++++++++++++++++++---------
- 3 files changed, 63 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 f2d6b78..1a449f9 100644
---- a/drivers/net/xen-netback/netback.c
-+++ b/drivers/net/xen-netback/netback.c
-@@ -888,6 +888,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,
-@@ -901,19 +908,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;
- }
-
-@@ -921,8 +931,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);
-@@ -1095,7 +1106,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;
- }
-
-@@ -1104,8 +1116,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;
- }
-
-@@ -1121,13 +1134,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;
- }
-
-@@ -1264,9 +1279,26 @@ 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);
-@@ -1294,17 +1326,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)) {
-@@ -1316,11 +1345,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;
- }
-
-@@ -1348,8 +1377,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.2.5
-