All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Krasnyansky <maxk@qualcomm.com>
To: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
Cc: Eric Dumazet <eric.dumazet@gmail.com>, <netdev@vger.kernel.org>,
	<davem@davemloft.net>
Subject: Re: [PATCH] Crash in tun
Date: Thu, 19 Jul 2012 10:44:01 -0700	[thread overview]
Message-ID: <50084761.1030602@qualcomm.com> (raw)
In-Reply-To: <alpine.DEB.2.00.1207191746170.7550@artax.karlin.mff.cuni.cz>

On 07/19/2012 09:13 AM, Mikulas Patocka wrote:
> 
> 
> On Thu, 19 Jul 2012, Eric Dumazet wrote:
> 
>> Hi Mikulas
>>
>> A fix for this problem is : http://patchwork.ozlabs.org/patch/170440/
> 
> If you call tun_free_netdev beacuse of a jump to an error label 
> err_free_sk, your patch still calls it with NULL file, causing a memory 
> corruption and a possible crash.
> 
> Your patch doesn't fix sockets_in_use underflow.
> 
> Maybe we can commit this patch --- it introduces a new flag 
> SOCK_EXTERNALLY_ALLOCATED to work around both problems. (it looks quite 
> nicer than my previous patch with file = (void *)1).


I definitely like this second version better. Less hacky an all.

btw I don't remember now who added the socket business to tun_struct and why.
It seems to be messy in general. Originally version, back when I was still paying attention to it,
didn't have sockets at all. Only char and net devices. It was much cleaner.

Max






> ---
> 
> tun: fix a crash bug and a memory leak
> 
> This patch fixes a crash
> tun_chr_close -> netdev_run_todo -> tun_free_netdev -> sk_release_kernel ->
> sock_release -> iput(SOCK_INODE(sock))
> introduced by commit 1ab5ecb90cb6a3df1476e052f76a6e8f6511cb3d
> 
> The problem is that this socket is embedded in struct tun_struct, it has
> no inode, iput is called on invalid inode, which modifies invalid memory
> and optionally causes a crash.
> 
> sock_release also decrements sockets_in_use, this causes a bug that
> "sockets: used" field in /proc/*/net/sockstat keeps on decreasing when
> creating and closing tun devices.
> 
> This patch introduces a flag SOCK_EXTERNALLY_ALLOCATED that instructs
> sock_release to not free the inode and not decrement sockets_in_use,
> fixing both memory corruption and sockets_in_use underflow.
> 
> It should be backported to 3.3 an 3.4 stabke.
> 
> Signed-off-by: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
> Cc: stable@kernel.org
> 
> ---
>  drivers/net/tun.c   |    3 +++
>  include/linux/net.h |    1 +
>  net/socket.c        |    3 +++
>  3 files changed, 7 insertions(+)
> 
> Index: linux-3.4.5-fast/drivers/net/tun.c
> ===================================================================
> --- linux-3.4.5-fast.orig/drivers/net/tun.c	2012-07-19 17:55:16.000000000 +0200
> +++ linux-3.4.5-fast/drivers/net/tun.c	2012-07-19 17:58:30.000000000 +0200
> @@ -358,6 +358,8 @@ static void tun_free_netdev(struct net_d
>  {
>  	struct tun_struct *tun = netdev_priv(dev);
>  
> +	BUG_ON(!test_bit(SOCK_EXTERNALLY_ALLOCATED, &tun->socket.flags));
> +
>  	sk_release_kernel(tun->socket.sk);
>  }
>  
> @@ -1115,6 +1117,7 @@ static int tun_set_iff(struct net *net,
>  		tun->flags = flags;
>  		tun->txflt.count = 0;
>  		tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr);
> +		set_bit(SOCK_EXTERNALLY_ALLOCATED, &tun->socket.flags);
>  
>  		err = -ENOMEM;
>  		sk = sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, &tun_proto);
> Index: linux-3.4.5-fast/include/linux/net.h
> ===================================================================
> --- linux-3.4.5-fast.orig/include/linux/net.h	2012-07-19 17:54:31.000000000 +0200
> +++ linux-3.4.5-fast/include/linux/net.h	2012-07-19 17:55:03.000000000 +0200
> @@ -72,6 +72,7 @@ struct net;
>  #define SOCK_NOSPACE		2
>  #define SOCK_PASSCRED		3
>  #define SOCK_PASSSEC		4
> +#define SOCK_EXTERNALLY_ALLOCATED 5
>  
>  #ifndef ARCH_HAS_SOCKET_TYPES
>  /**
> Index: linux-3.4.5-fast/net/socket.c
> ===================================================================
> --- linux-3.4.5-fast.orig/net/socket.c	2012-07-19 17:56:55.000000000 +0200
> +++ linux-3.4.5-fast/net/socket.c	2012-07-19 17:57:50.000000000 +0200
> @@ -522,6 +522,9 @@ void sock_release(struct socket *sock)
>  	if (rcu_dereference_protected(sock->wq, 1)->fasync_list)
>  		printk(KERN_ERR "sock_release: fasync list not empty!\n");
>  
> +	if (test_bit(SOCK_EXTERNALLY_ALLOCATED, &sock->flags))
> +		return;
> +
>  	percpu_sub(sockets_in_use, 1);
>  	if (!sock->file) {
>  		iput(SOCK_INODE(sock));
> 

  reply	other threads:[~2012-07-19 17:44 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-19  1:12 [PATCH] Crash in tun Mikulas Patocka
2012-07-19  6:09 ` Eric Dumazet
2012-07-19 15:28   ` David Miller
2012-07-19 16:13   ` Mikulas Patocka
2012-07-19 17:44     ` Max Krasnyansky [this message]
2012-07-19 17:47       ` David Miller
2012-07-19 17:57         ` Max Krasnyansky
2012-07-20 18:23     ` David Miller
2012-07-21  7:55       ` Al Viro
2012-07-21  7:55         ` Al Viro
2012-07-21  9:53         ` Nicholas A. Bellinger
2012-07-21  9:53           ` Nicholas A. Bellinger
2012-07-23  9:43         ` David Laight
2012-07-23  9:43           ` David Laight

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=50084761.1030602@qualcomm.com \
    --to=maxk@qualcomm.com \
    --cc=davem@davemloft.net \
    --cc=eric.dumazet@gmail.com \
    --cc=mikulas@artax.karlin.mff.cuni.cz \
    --cc=netdev@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.