linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
@ 2013-06-20 11:48 Michael S. Tsirkin
  2013-06-20 12:47 ` Sergei Shtylyov
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Michael S. Tsirkin @ 2013-06-20 11:48 UTC (permalink / raw)
  To: linux-kernel
  Cc: David S. Miller, Asias He, Jason Wang, kvm, virtualization, netdev

vhost_net_ubuf_put_and_wait has a confusing name:
it will actually also free it's argument.
Thus since commit 1280c27f8e29acf4af2da914e80ec27c3dbd5c01
vhost_net_flush tries to use the argument after passing it
to vhost_net_ubuf_put_and_wait, this results
in use after free.
To fix, don't free the argument in vhost_net_ubuf_put_and_wait,
add an new API for callers that want to free ubufs.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---

Dave, this is needed for stable as well, but
the code has moved a bit since then.
I'll post a patch tweaked to apply against 3.9 and 3.8 separately.

 drivers/vhost/net.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 5c77d6a..534adb0 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -149,6 +149,11 @@ static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs)
 {
 	kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
 	wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
+}
+
+static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs)
+{
+	vhost_net_ubuf_put_and_wait(ubufs);
 	kfree(ubufs);
 }
 
@@ -1073,7 +1078,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
 	mutex_unlock(&vq->mutex);
 
 	if (oldubufs) {
-		vhost_net_ubuf_put_and_wait(oldubufs);
+		vhost_net_ubuf_put_wait_and_free(oldubufs);
 		mutex_lock(&vq->mutex);
 		vhost_zerocopy_signal_used(n, vq);
 		mutex_unlock(&vq->mutex);
@@ -1091,7 +1096,7 @@ err_used:
 	vq->private_data = oldsock;
 	vhost_net_enable_vq(n, vq);
 	if (ubufs)
-		vhost_net_ubuf_put_and_wait(ubufs);
+		vhost_net_ubuf_put_wait_and_free(ubufs);
 err_ubufs:
 	fput(sock->file);
 err_vq:
-- 
MST

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
  2013-06-20 11:48 [PATCH net] vhost-net: fix use-after-free in vhost_net_flush Michael S. Tsirkin
@ 2013-06-20 12:47 ` Sergei Shtylyov
  2013-06-21  6:50 ` Jason Wang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sergei Shtylyov @ 2013-06-20 12:47 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: linux-kernel, David S. Miller, Asias He, Jason Wang, kvm,
	virtualization, netdev

Hello.

On 20-06-2013 15:48, Michael S. Tsirkin wrote:

> vhost_net_ubuf_put_and_wait has a confusing name:
> it will actually also free it's argument.
> Thus since commit 1280c27f8e29acf4af2da914e80ec27c3dbd5c01

    Please also specify that commit's summary line in parens.

> vhost_net_flush tries to use the argument after passing it
> to vhost_net_ubuf_put_and_wait, this results
> in use after free.
> To fix, don't free the argument in vhost_net_ubuf_put_and_wait,
> add an new API for callers that want to free ubufs.

> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

WBR, Sergei


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
  2013-06-20 11:48 [PATCH net] vhost-net: fix use-after-free in vhost_net_flush Michael S. Tsirkin
  2013-06-20 12:47 ` Sergei Shtylyov
@ 2013-06-21  6:50 ` Jason Wang
  2013-06-21  7:20 ` Asias He
  2013-06-24  7:01 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Jason Wang @ 2013-06-21  6:50 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: linux-kernel, David S. Miller, Asias He, kvm, virtualization, netdev

On 06/20/2013 07:48 PM, Michael S. Tsirkin wrote:
> vhost_net_ubuf_put_and_wait has a confusing name:
> it will actually also free it's argument.
> Thus since commit 1280c27f8e29acf4af2da914e80ec27c3dbd5c01
> vhost_net_flush tries to use the argument after passing it
> to vhost_net_ubuf_put_and_wait, this results
> in use after free.
> To fix, don't free the argument in vhost_net_ubuf_put_and_wait,
> add an new API for callers that want to free ubufs.
>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>
> Dave, this is needed for stable as well, but
> the code has moved a bit since then.
> I'll post a patch tweaked to apply against 3.9 and 3.8 separately.
>
>  drivers/vhost/net.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 5c77d6a..534adb0 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -149,6 +149,11 @@ static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs)
>  {
>  	kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
>  	wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
> +}
> +
> +static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs)
> +{
> +	vhost_net_ubuf_put_and_wait(ubufs);
>  	kfree(ubufs);
>  }
>  
> @@ -1073,7 +1078,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
>  	mutex_unlock(&vq->mutex);
>  
>  	if (oldubufs) {
> -		vhost_net_ubuf_put_and_wait(oldubufs);
> +		vhost_net_ubuf_put_wait_and_free(oldubufs);
>  		mutex_lock(&vq->mutex);
>  		vhost_zerocopy_signal_used(n, vq);
>  		mutex_unlock(&vq->mutex);
> @@ -1091,7 +1096,7 @@ err_used:
>  	vq->private_data = oldsock;
>  	vhost_net_enable_vq(n, vq);
>  	if (ubufs)
> -		vhost_net_ubuf_put_and_wait(ubufs);
> +		vhost_net_ubuf_put_wait_and_free(ubufs);
>  err_ubufs:
>  	fput(sock->file);
>  err_vq:

Acked-by: Jason Wang <jasowang@redhat.com>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
  2013-06-20 11:48 [PATCH net] vhost-net: fix use-after-free in vhost_net_flush Michael S. Tsirkin
  2013-06-20 12:47 ` Sergei Shtylyov
  2013-06-21  6:50 ` Jason Wang
@ 2013-06-21  7:20 ` Asias He
  2013-06-24  7:01 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: Asias He @ 2013-06-21  7:20 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: linux-kernel, David S. Miller, Jason Wang, kvm, virtualization, netdev

On Thu, Jun 20, 2013 at 02:48:13PM +0300, Michael S. Tsirkin wrote:
> vhost_net_ubuf_put_and_wait has a confusing name:
> it will actually also free it's argument.
> Thus since commit 1280c27f8e29acf4af2da914e80ec27c3dbd5c01
> vhost_net_flush tries to use the argument after passing it
> to vhost_net_ubuf_put_and_wait, this results
> in use after free.
> To fix, don't free the argument in vhost_net_ubuf_put_and_wait,
> add an new API for callers that want to free ubufs.
> 
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

Acked-by: Asias He <asias@redhat.com>

> ---
> 
> Dave, this is needed for stable as well, but
> the code has moved a bit since then.
> I'll post a patch tweaked to apply against 3.9 and 3.8 separately.
> 
>  drivers/vhost/net.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index 5c77d6a..534adb0 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -149,6 +149,11 @@ static void vhost_net_ubuf_put_and_wait(struct vhost_net_ubuf_ref *ubufs)
>  {
>  	kref_put(&ubufs->kref, vhost_net_zerocopy_done_signal);
>  	wait_event(ubufs->wait, !atomic_read(&ubufs->kref.refcount));
> +}
> +
> +static void vhost_net_ubuf_put_wait_and_free(struct vhost_net_ubuf_ref *ubufs)
> +{
> +	vhost_net_ubuf_put_and_wait(ubufs);
>  	kfree(ubufs);
>  }
>  
> @@ -1073,7 +1078,7 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
>  	mutex_unlock(&vq->mutex);
>  
>  	if (oldubufs) {
> -		vhost_net_ubuf_put_and_wait(oldubufs);
> +		vhost_net_ubuf_put_wait_and_free(oldubufs);
>  		mutex_lock(&vq->mutex);
>  		vhost_zerocopy_signal_used(n, vq);
>  		mutex_unlock(&vq->mutex);
> @@ -1091,7 +1096,7 @@ err_used:
>  	vq->private_data = oldsock;
>  	vhost_net_enable_vq(n, vq);
>  	if (ubufs)
> -		vhost_net_ubuf_put_and_wait(ubufs);
> +		vhost_net_ubuf_put_wait_and_free(ubufs);
>  err_ubufs:
>  	fput(sock->file);
>  err_vq:
> -- 
> MST

-- 
Asias

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
  2013-06-20 11:48 [PATCH net] vhost-net: fix use-after-free in vhost_net_flush Michael S. Tsirkin
                   ` (2 preceding siblings ...)
  2013-06-21  7:20 ` Asias He
@ 2013-06-24  7:01 ` David Miller
  3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2013-06-24  7:01 UTC (permalink / raw)
  To: mst; +Cc: linux-kernel, asias, jasowang, kvm, virtualization, netdev

From: "Michael S. Tsirkin" <mst@redhat.com>
Date: Thu, 20 Jun 2013 14:48:13 +0300

> vhost_net_ubuf_put_and_wait has a confusing name:
> it will actually also free it's argument.
> Thus since commit 1280c27f8e29acf4af2da914e80ec27c3dbd5c01

Never reference commits only by SHA1 ID, it is never sufficient.

Always provide, after the SHA1 ID, in parenthesis, the header line
from the commit message.

To be honest, I'm kind of tired of telling people they need to do
this over and over again.

Maybe people keep forgetting because the reason why this is an issue
hasn't really sunk in.

If the patch you reference got backported into another tree, it will
not have the SHA1 ID, and therefore someone reading the "fix" won't
be able to find the fault causing change without going through a lot
of trouble.  By providing the commit header line you remove that
problem altogether, no ambiguity is possible.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-06-24  7:01 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-20 11:48 [PATCH net] vhost-net: fix use-after-free in vhost_net_flush Michael S. Tsirkin
2013-06-20 12:47 ` Sergei Shtylyov
2013-06-21  6:50 ` Jason Wang
2013-06-21  7:20 ` Asias He
2013-06-24  7:01 ` David Miller

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).