CVE-2014-2568 net: potential info leak when ubuf backed skbs are zero copied (rhbz 1079012 1079013)

This commit is contained in:
Josh Boyer 2014-03-28 11:04:39 -04:00
commit 736e49f22d
2 changed files with 126 additions and 0 deletions

View file

@ -793,6 +793,9 @@ Patch25045: netfilter-nf_conntrack_dccp-fix-skb_header_pointer-A.patch
#CVE-2014-0131 rhbz 1074589 1079006
Patch25048: skbuff-zero-copy.patch
#CVE-2014-2568 rhbz 1079012 1079013
Patch25049: nfqueue-Orphan-frags-in-nfqnl_zcopy-and-handle-error.patch
# END OF PATCH DEFINITIONS
%endif
@ -1532,6 +1535,9 @@ ApplyPatch netfilter-nf_conntrack_dccp-fix-skb_header_pointer-A.patch
#CVE-2014-0131 rhbz 1074589 1079006
ApplyPatch skbuff-zero-copy.patch
#CVE-2014-2568 rhbz 1079012 1079013
ApplyPatch nfqueue-Orphan-frags-in-nfqnl_zcopy-and-handle-error.patch
# END OF PATCH APPLICATIONS
%endif
@ -2344,6 +2350,9 @@ fi
# and build.
%changelog
* Fri Mar 28 2014 Josh Boyer <jwboyer@fedoraproject.org>
- CVE-2014-2568 net: potential info leak when ubuf backed skbs are zero copied (rhbz 1079012 1079013)
* Mon Mar 24 2014 Justin M. Forbes <jforbes@fedoraproject.org> - 3.13.7-100
- Linux v3.13.7

View file

@ -0,0 +1,117 @@
Bugzilla: 1079013
Upstream-status: Queued in netdev tree, backport for 3.13.y sent
From 93f7cfcac69051641d5b10325164a0f313ef5185 Mon Sep 17 00:00:00 2001
From: Josh Boyer <jwboyer@fedoraproject.org>
Date: Fri, 28 Mar 2014 09:32:19 -0400
Subject: [PATCH] nfqueue: Orphan frags in nfqnl_zcopy and handle errors
Backport of upstream commit 36d5fe6a0007 to 3.13.y
nfqnl_zcopy 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 caller 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>
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
---
net/netfilter/nfnetlink_queue_core.c | 31 ++++++++++++++++++++++---------
1 file changed, 22 insertions(+), 9 deletions(-)
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c
index 21258cf..b241654 100644
--- a/net/netfilter/nfnetlink_queue_core.c
+++ b/net/netfilter/nfnetlink_queue_core.c
@@ -235,22 +235,23 @@ nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn, unsigned long data)
spin_unlock_bh(&queue->lock);
}
-static void
-nfqnl_zcopy(struct sk_buff *to, const struct sk_buff *from, int len, int hlen)
+static int
+nfqnl_zcopy(struct sk_buff *to, 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 struct sk_buff *from, int len, int hlen)
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 struct sk_buff *from, int len, int hlen)
j++;
}
skb_shinfo(to)->nr_frags = j;
+
+ return 0;
}
static int
@@ -374,13 +382,16 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
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 *net, struct nfqnl_instance *queue,
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;
--
1.8.5.3