stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	Ken-ichirou MATSUZAWA <chamaken@gmail.com>,
	Daniel Borkmann <daniel@iogearbox.net>,
	"David S. Miller" <davem@davemloft.net>
Subject: [PATCH 4.1 13/29] netlink, mmap: transform mmap skb into full skb on taps
Date: Thu,  1 Oct 2015 11:31:49 +0200	[thread overview]
Message-ID: <20151001093146.290595837@linuxfoundation.org> (raw)
In-Reply-To: <20151001093145.730759857@linuxfoundation.org>

4.1-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Daniel Borkmann <daniel@iogearbox.net>

[ Upstream commit 1853c949646005b5959c483becde86608f548f24 ]

Ken-ichirou reported that running netlink in mmap mode for receive in
combination with nlmon will throw a NULL pointer dereference in
__kfree_skb() on nlmon_xmit(), in my case I can also trigger an "unable
to handle kernel paging request". The problem is the skb_clone() in
__netlink_deliver_tap_skb() for skbs that are mmaped.

I.e. the cloned skb doesn't have a destructor, whereas the mmap netlink
skb has it pointed to netlink_skb_destructor(), set in the handler
netlink_ring_setup_skb(). There, skb->head is being set to NULL, so
that in such cases, __kfree_skb() doesn't perform a skb_release_data()
via skb_release_all(), where skb->head is possibly being freed through
kfree(head) into slab allocator, although netlink mmap skb->head points
to the mmap buffer. Similarly, the same has to be done also for large
netlink skbs where the data area is vmalloced. Therefore, as discussed,
make a copy for these rather rare cases for now. This fixes the issue
on my and Ken-ichirou's test-cases.

Reference: http://thread.gmane.org/gmane.linux.network/371129
Fixes: bcbde0d449ed ("net: netlink: virtual tap device management")
Reported-by: Ken-ichirou MATSUZAWA <chamaken@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Tested-by: Ken-ichirou MATSUZAWA <chamaken@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/netlink/af_netlink.c |   30 +++++++++++++++++++++++-------
 net/netlink/af_netlink.h |    9 +++++++++
 2 files changed, 32 insertions(+), 7 deletions(-)

--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -123,6 +123,24 @@ static inline u32 netlink_group_mask(u32
 	return group ? 1 << (group - 1) : 0;
 }
 
+static struct sk_buff *netlink_to_full_skb(const struct sk_buff *skb,
+					   gfp_t gfp_mask)
+{
+	unsigned int len = skb_end_offset(skb);
+	struct sk_buff *new;
+
+	new = alloc_skb(len, gfp_mask);
+	if (new == NULL)
+		return NULL;
+
+	NETLINK_CB(new).portid = NETLINK_CB(skb).portid;
+	NETLINK_CB(new).dst_group = NETLINK_CB(skb).dst_group;
+	NETLINK_CB(new).creds = NETLINK_CB(skb).creds;
+
+	memcpy(skb_put(new, len), skb->data, len);
+	return new;
+}
+
 int netlink_add_tap(struct netlink_tap *nt)
 {
 	if (unlikely(nt->dev->type != ARPHRD_NETLINK))
@@ -204,7 +222,11 @@ static int __netlink_deliver_tap_skb(str
 	int ret = -ENOMEM;
 
 	dev_hold(dev);
-	nskb = skb_clone(skb, GFP_ATOMIC);
+
+	if (netlink_skb_is_mmaped(skb) || is_vmalloc_addr(skb->head))
+		nskb = netlink_to_full_skb(skb, GFP_ATOMIC);
+	else
+		nskb = skb_clone(skb, GFP_ATOMIC);
 	if (nskb) {
 		nskb->dev = dev;
 		nskb->protocol = htons((u16) sk->sk_protocol);
@@ -276,11 +298,6 @@ static void netlink_rcv_wake(struct sock
 }
 
 #ifdef CONFIG_NETLINK_MMAP
-static bool netlink_skb_is_mmaped(const struct sk_buff *skb)
-{
-	return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED;
-}
-
 static bool netlink_rx_is_mmaped(struct sock *sk)
 {
 	return nlk_sk(sk)->rx_ring.pg_vec != NULL;
@@ -832,7 +849,6 @@ static void netlink_ring_set_copied(stru
 }
 
 #else /* CONFIG_NETLINK_MMAP */
-#define netlink_skb_is_mmaped(skb)	false
 #define netlink_rx_is_mmaped(sk)	false
 #define netlink_tx_is_mmaped(sk)	false
 #define netlink_mmap			sock_no_mmap
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -59,6 +59,15 @@ static inline struct netlink_sock *nlk_s
 	return container_of(sk, struct netlink_sock, sk);
 }
 
+static inline bool netlink_skb_is_mmaped(const struct sk_buff *skb)
+{
+#ifdef CONFIG_NETLINK_MMAP
+	return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED;
+#else
+	return false;
+#endif /* CONFIG_NETLINK_MMAP */
+}
+
 struct netlink_table {
 	struct rhashtable	hash;
 	struct hlist_head	mc_list;



  parent reply	other threads:[~2015-10-01  9:32 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-01  9:31 [PATCH 4.1 00/29] 4.1.10-stable review Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 01/29] ip6_gre: release cached dst on tunnel removal Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 02/29] vxlan: re-ignore EADDRINUSE from igmp_join Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 03/29] cls_u32: complete the check for non-forced case in u32_destroy() Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 04/29] usbnet: Get EVENT_NO_RUNTIME_PM bit before it is cleared Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 05/29] sock, diag: fix panic in sock_diag_put_filterinfo Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 06/29] ipv6: fix exthdrs offload registration in out_rt path Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 07/29] net: fec: clear receive interrupts before processing a packet Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 08/29] net: eth: altera: fix napi poll_list corruption Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 09/29] net/ipv6: Correct PIM6 mrt_lock handling Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 10/29] net: dsa: bcm_sf2: Fix ageing conditions and operation Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 11/29] ipv6: fix multipath route replace error recovery Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 12/29] net: dsa: bcm_sf2: Fix 64-bits register writes Greg Kroah-Hartman
2015-10-01  9:31 ` Greg Kroah-Hartman [this message]
2015-10-01  9:31 ` [PATCH 4.1 14/29] sctp: fix race on protocol/netns initialization Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 16/29] net/mlx4_en: really allow to change RSS key Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 17/29] macvtap: fix TUNSETSNDBUF values > 64k Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 18/29] openvswitch: Zero flows on allocation Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 19/29] tcp: add proper TS val into RST packets Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 20/29] net: revert "net_sched: move tp->root allocation into fw_init()" Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 21/29] fib_rules: fix fib rule dumps across multiple skbs Greg Kroah-Hartman
2015-10-01  9:31 ` [PATCH 4.1 22/29] net: dsa: bcm_sf2: Do not override speed settings Greg Kroah-Hartman
2015-10-02  0:47   ` Ben Hutchings
2015-10-02  1:22     ` David Miller
2015-10-03 11:38       ` Greg KH
2015-10-01  9:31 ` [PATCH 4.1 23/29] net: phy: fixed_phy: handle link-down case Greg Kroah-Hartman
2015-10-01  9:32 ` [PATCH 4.1 24/29] of_mdio: add new DT property managed to specify the PHY management type Greg Kroah-Hartman
2015-10-01  9:32 ` [PATCH 4.1 25/29] mvneta: use inband status only when explicitly enabled Greg Kroah-Hartman
2015-10-01  9:32 ` [PATCH 4.1 26/29] netlink: Fix autobind race condition that leads to zero port ID Greg Kroah-Hartman
2015-10-01  9:32 ` [PATCH 4.1 27/29] netlink: Replace rhash_portid with bound Greg Kroah-Hartman
2015-10-01  9:32 ` [PATCH 4.1 28/29] zram: fix possible use after free in zcomp_create() Greg Kroah-Hartman
2015-10-01  9:32 ` [PATCH 4.1 29/29] hp-wmi: limit hotkey enable Greg Kroah-Hartman
     [not found] ` <20151001093146.372268230@linuxfoundation.org>
2015-10-01 23:13   ` [PATCH 4.1 15/29] bridge: fix igmpv3 / mldv2 report parsing Linus Lüssing
2015-10-02  1:29 ` [PATCH 4.1 00/29] 4.1.10-stable review Guenter Roeck
2015-10-02  6:23 ` Sudip Mukherjee
     [not found] ` <560e9a58.e127b40a.bc060.fffffb97@mx.google.com>
2015-10-02 15:04   ` Kevin Hilman
2015-10-02 15:41 ` Shuah Khan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20151001093146.290595837@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=chamaken@gmail.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).