nfqueue: Orphan frags in nfqnl_zcopy() and handle errors (CVE-2014-2568)
svn path=/dists/sid/linux/; revision=21190
This commit is contained in:
parent
9f6a808fee
commit
1d8877c3c3
|
@ -58,6 +58,7 @@ linux (3.13.7-1) UNRELEASED; urgency=medium
|
|||
|
||||
[ Ben Hutchings ]
|
||||
* [arm] mm: Avoid ABI change in 3.13.6 (fixes FTBFS)
|
||||
* nfqueue: Orphan frags in nfqnl_zcopy() and handle errors (CVE-2014-2568)
|
||||
|
||||
-- Ben Hutchings <ben@decadent.org.uk> Fri, 21 Mar 2014 19:47:01 +0000
|
||||
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
Subject: [v4] core, nfqueue, openvswitch: Orphan frags in skb_zerocopy and handle errors
|
||||
From: Zoltan Kiss <zoltan.kiss@citrix.com>
|
||||
Date: Fri, 21 Mar 2014 10:31:34 +0000
|
||||
Origin: https://patchwork.ozlabs.org/patch/332544/
|
||||
|
||||
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>
|
||||
Acked-by: Thomas Graf <tgraf@redhat.com>
|
||||
[bwh: 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.]
|
||||
---
|
||||
--- a/net/netfilter/nfnetlink_queue_core.c
|
||||
+++ b/net/netfilter/nfnetlink_queue_core.c
|
||||
@@ -235,22 +235,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);
|
||||
@@ -268,6 +269,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;
|
||||
@@ -278,6 +284,8 @@ nfqnl_zcopy(struct sk_buff *to, const st
|
||||
j++;
|
||||
}
|
||||
skb_shinfo(to)->nr_frags = j;
|
||||
+
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -374,13 +382,16 @@ nfqnl_build_packet_message(struct net *n
|
||||
|
||||
skb = nfnetlink_alloc_skb(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;
|
||||
}
|
||||
@@ -504,13 +515,15 @@ nfqnl_build_packet_message(struct net *n
|
||||
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;
|
|
@ -93,3 +93,4 @@ debian/netdev-avoid-abi-change-in-3.13.6.patch
|
|||
debian/can-avoid-abi-change-in-3.13.6.patch
|
||||
debian/arm-mm-avoid-abi-change-in-3.13.6.patch
|
||||
debian/fireware-avoid-abi-change-in-3.13.7.patch
|
||||
bugfix/all/net-core-nfqueue-openvswitch-Orphan-frags-in-skb_zerocopy-and-handle-errors.patch
|
||||
|
|
Loading…
Reference in New Issue