All of lore.kernel.org
 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.2 10/30] netlink, mmap: transform mmap skb into full skb on taps
Date: Thu,  1 Oct 2015 11:21:32 +0200	[thread overview]
Message-ID: <20151001092038.642643630@linuxfoundation.org> (raw)
In-Reply-To: <20151001092038.213304276@linuxfoundation.org>

4.2-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
@@ -124,6 +124,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))
@@ -205,7 +223,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);
@@ -278,11 +300,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;
@@ -834,7 +851,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:22 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-01  9:21 [PATCH 4.2 00/30] 4.2.3-stable review Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 01/30] phylib: fix device deletion order in mdiobus_unregister() Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 02/30] sock, diag: fix panic in sock_diag_put_filterinfo Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 03/30] ipv6: fix exthdrs offload registration in out_rt path Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 04/30] net: fec: clear receive interrupts before processing a packet Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 05/30] net: eth: altera: fix napi poll_list corruption Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 06/30] net/ipv6: Correct PIM6 mrt_lock handling Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 07/30] net: dsa: bcm_sf2: Fix ageing conditions and operation Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 08/30] ipv6: fix multipath route replace error recovery Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 09/30] net: dsa: bcm_sf2: Fix 64-bits register writes Greg Kroah-Hartman
2015-10-01  9:21 ` Greg Kroah-Hartman [this message]
2015-10-01  9:21 ` [PATCH 4.2 11/30] sctp: fix race on protocol/netns initialization Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 13/30] net: mvneta: fix DMA buffer unmapping in mvneta_rx() Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 14/30] rtnetlink: catch -EOPNOTSUPP errors from ndo_bridge_getlink Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 15/30] net/mlx4_en: really allow to change RSS key Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 16/30] macvtap: fix TUNSETSNDBUF values > 64k Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 17/30] netlink: Fix autobind race condition that leads to zero port ID Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 18/30] netlink: Replace rhash_portid with bound Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 19/30] net: dsa: actually force the speed on the CPU port Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 20/30] openvswitch: Zero flows on allocation Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 21/30] tcp: add proper TS val into RST packets Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 22/30] Fix AF_PACKET ABI breakage in 4.2 Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 23/30] net: revert "net_sched: move tp->root allocation into fw_init()" Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 24/30] fib_rules: fix fib rule dumps across multiple skbs Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 25/30] ppp: fix lockdep splat in ppp_dev_uninit() Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 26/30] net: dsa: bcm_sf2: Do not override speed settings Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 27/30] net: phy: fixed_phy: handle link-down case Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 28/30] of_mdio: add new DT property managed to specify the PHY management type Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 29/30] mvneta: use inband status only when explicitly enabled Greg Kroah-Hartman
2015-10-01  9:21 ` [PATCH 4.2 30/30] net/mlx4_core: Capping number of requested MSIXs to MAX_MSIX Greg Kroah-Hartman
2015-10-02  1:27 ` [PATCH 4.2 00/30] 4.2.3-stable review Guenter Roeck
2015-10-03 11:37   ` Greg Kroah-Hartman
2015-10-03 14:45     ` Guenter Roeck
2015-10-18  0:45       ` Greg Kroah-Hartman
2015-10-02  5:14 ` Sudip Mukherjee
2015-10-03 11:36   ` Greg Kroah-Hartman
2015-10-02 15:41 ` Shuah Khan
2015-10-03 11:36   ` Greg Kroah-Hartman

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=20151001092038.642643630@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.