All of lore.kernel.org
 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
  0 siblings, 0 replies; 10+ 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] 10+ messages in thread

* [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
@ 2013-06-20 11:48 ` Michael S. Tsirkin
  0 siblings, 0 replies; 10+ messages in thread
From: Michael S. Tsirkin @ 2013-06-20 11:48 UTC (permalink / raw)
  To: linux-kernel; +Cc: kvm, netdev, virtualization, David S. Miller

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] 10+ messages in thread

* Re: [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
  -1 siblings, 0 replies; 10+ 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] 10+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
@ 2013-06-20 12:47   ` Sergei Shtylyov
  0 siblings, 0 replies; 10+ messages in thread
From: Sergei Shtylyov @ 2013-06-20 12:47 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kvm, netdev, linux-kernel, virtualization, David S. Miller

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] 10+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
  2013-06-20 11:48 ` Michael S. Tsirkin
@ 2013-06-21  6:50   ` Jason Wang
  -1 siblings, 0 replies; 10+ 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] 10+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
@ 2013-06-21  6:50   ` Jason Wang
  0 siblings, 0 replies; 10+ messages in thread
From: Jason Wang @ 2013-06-21  6:50 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: kvm, netdev, linux-kernel, virtualization, David S. Miller

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] 10+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
  2013-06-20 11:48 ` Michael S. Tsirkin
@ 2013-06-21  7:20   ` Asias He
  -1 siblings, 0 replies; 10+ 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] 10+ messages in thread

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

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] 10+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
  2013-06-20 11:48 ` Michael S. Tsirkin
@ 2013-06-24  7:01   ` David Miller
  -1 siblings, 0 replies; 10+ 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] 10+ messages in thread

* Re: [PATCH net] vhost-net: fix use-after-free in vhost_net_flush
@ 2013-06-24  7:01   ` David Miller
  0 siblings, 0 replies; 10+ messages in thread
From: David Miller @ 2013-06-24  7:01 UTC (permalink / raw)
  To: mst; +Cc: kvm, netdev, linux-kernel, virtualization

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] 10+ messages in thread

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

Thread overview: 10+ 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 11:48 ` Michael S. Tsirkin
2013-06-20 12:47 ` Sergei Shtylyov
2013-06-20 12:47   ` Sergei Shtylyov
2013-06-21  6:50 ` Jason Wang
2013-06-21  6:50   ` Jason Wang
2013-06-21  7:20 ` Asias He
2013-06-21  7:20   ` Asias He
2013-06-24  7:01 ` David Miller
2013-06-24  7:01   ` David Miller

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.