]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Jul 2014 00:59:04 +0000 (17:59 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Jul 2014 00:59:04 +0000 (17:59 -0700)
added patches:
core-nfqueue-openvswitch-orphan-frags-in-skb_zerocopy-and.patch

queue-3.10/core-nfqueue-openvswitch-orphan-frags-in-skb_zerocopy-and.patch [new file with mode: 0644]
queue-3.10/series

diff --git a/queue-3.10/core-nfqueue-openvswitch-orphan-frags-in-skb_zerocopy-and.patch b/queue-3.10/core-nfqueue-openvswitch-orphan-frags-in-skb_zerocopy-and.patch
new file mode 100644 (file)
index 0000000..15648cc
--- /dev/null
@@ -0,0 +1,115 @@
+From 36d5fe6a000790f56039afe26834265db0a3ad4c Mon Sep 17 00:00:00 2001
+From: Zoltan Kiss <zoltan.kiss@citrix.com>
+Date: Wed, 26 Mar 2014 22:37:45 +0000
+Subject: core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors
+
+From: Zoltan Kiss <zoltan.kiss@citrix.com>
+
+commit 36d5fe6a000790f56039afe26834265db0a3ad4c upstream.
+
+skb_zerocopy can copy elements of the frags array between skbs, but it doesn't
+orphan them. Also, it doesn't handle errors, so this patch takes care of that
+as well, and modify the callers accordingly. skb_tx_error() is also added to
+the callers so they will signal the failed delivery towards the creator of the
+skb.
+
+Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+[bwh: Backported to 3.13: skb_zerocopy() is new in 3.14, but was moved from a
+ static function in nfnetlink_queue.  We need to patch that and its caller, but
+ not openvswitch.]
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/nfnetlink_queue_core.c |   29 +++++++++++++++++++++--------
+ 1 file changed, 21 insertions(+), 8 deletions(-)
+
+--- a/net/netfilter/nfnetlink_queue_core.c
++++ b/net/netfilter/nfnetlink_queue_core.c
+@@ -227,22 +227,23 @@ nfqnl_flush(struct nfqnl_instance *queue
+       spin_unlock_bh(&queue->lock);
+ }
+-static void
++static int
+ nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
+ {
+       int i, j = 0;
+       int plen = 0; /* length of skb->head fragment */
++      int ret;
+       struct page *page;
+       unsigned int offset;
+       /* dont bother with small payloads */
+-      if (len <= skb_tailroom(to)) {
+-              skb_copy_bits(from, 0, skb_put(to, len), len);
+-              return;
+-      }
++      if (len <= skb_tailroom(to))
++              return skb_copy_bits(from, 0, skb_put(to, len), len);
+       if (hlen) {
+-              skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
++              ret = skb_copy_bits(from, 0, skb_put(to, hlen), hlen);
++              if (unlikely(ret))
++                      return ret;
+               len -= hlen;
+       } else {
+               plen = min_t(int, skb_headlen(from), len);
+@@ -260,6 +261,11 @@ nfqnl_zcopy(struct sk_buff *to, const st
+       to->len += len + plen;
+       to->data_len += len + plen;
++      if (unlikely(skb_orphan_frags(from, GFP_ATOMIC))) {
++              skb_tx_error(from);
++              return -ENOMEM;
++      }
++
+       for (i = 0; i < skb_shinfo(from)->nr_frags; i++) {
+               if (!len)
+                       break;
+@@ -270,6 +276,8 @@ nfqnl_zcopy(struct sk_buff *to, const st
+               j++;
+       }
+       skb_shinfo(to)->nr_frags = j;
++
++      return 0;
+ }
+ static int nfqnl_put_packet_info(struct sk_buff *nlskb, struct sk_buff *packet)
+@@ -355,13 +363,16 @@ nfqnl_build_packet_message(struct nfqnl_
+       skb = nfnetlink_alloc_skb(&init_net, size, queue->peer_portid,
+                                 GFP_ATOMIC);
+-      if (!skb)
++      if (!skb) {
++              skb_tx_error(entskb);
+               return NULL;
++      }
+       nlh = nlmsg_put(skb, 0, 0,
+                       NFNL_SUBSYS_QUEUE << 8 | NFQNL_MSG_PACKET,
+                       sizeof(struct nfgenmsg), 0);
+       if (!nlh) {
++              skb_tx_error(entskb);
+               kfree_skb(skb);
+               return NULL;
+       }
+@@ -481,13 +492,15 @@ nfqnl_build_packet_message(struct nfqnl_
+               nla->nla_type = NFQA_PAYLOAD;
+               nla->nla_len = nla_attr_size(data_len);
+-              nfqnl_zcopy(skb, entskb, data_len, hlen);
++              if (nfqnl_zcopy(skb, entskb, data_len, hlen))
++                      goto nla_put_failure;
+       }
+       nlh->nlmsg_len = skb->len;
+       return skb;
+ nla_put_failure:
++      skb_tx_error(entskb);
+       kfree_skb(skb);
+       net_err_ratelimited("nf_queue: error creating packet message\n");
+       return NULL;
index 3062fff6c2c64329ade222887644b0a228f89fce..53694ccc25cad1ce7774d75e66920e345412858b 100644 (file)
@@ -18,3 +18,4 @@ mm-hugetlb-fix-copy_hugetlb_page_range.patch
 fix-gcc-4.9.0-miscompilation-of-load_balance-in-scheduler.patch
 s390-ptrace-fix-psw-mask-check.patch
 x86-efi-include-a-.bss-section-within-the-pe-coff-headers.patch
+core-nfqueue-openvswitch-orphan-frags-in-skb_zerocopy-and.patch