From d4e5ea72d7cec814c33f855932356e7f09d3821d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 29 Jul 2014 17:59:04 -0700 Subject: [PATCH] 3.10-stable patches added patches: core-nfqueue-openvswitch-orphan-frags-in-skb_zerocopy-and.patch --- ...tch-orphan-frags-in-skb_zerocopy-and.patch | 115 ++++++++++++++++++ queue-3.10/series | 1 + 2 files changed, 116 insertions(+) create mode 100644 queue-3.10/core-nfqueue-openvswitch-orphan-frags-in-skb_zerocopy-and.patch 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 index 00000000000..15648cc97fc --- /dev/null +++ b/queue-3.10/core-nfqueue-openvswitch-orphan-frags-in-skb_zerocopy-and.patch @@ -0,0 +1,115 @@ +From 36d5fe6a000790f56039afe26834265db0a3ad4c Mon Sep 17 00:00:00 2001 +From: Zoltan Kiss +Date: Wed, 26 Mar 2014 22:37:45 +0000 +Subject: core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors + +From: Zoltan Kiss + +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 +Signed-off-by: David S. Miller +[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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-3.10/series b/queue-3.10/series index 3062fff6c2c..53694ccc25c 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -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 -- 2.47.3