[SRU B/C/D] vhost/vsock: fix vhost vsock cid hashing inconsistent

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[SRU B/C/D] vhost/vsock: fix vhost vsock cid hashing inconsistent

Stefan Bader-2
From: Zha Bin <[hidden email]>

BugLink: https://bugs.launchpad.net/bugs/1813934

The vsock core only supports 32bit CID, but the Virtio-vsock spec define
CID (dst_cid and src_cid) as u64 and the upper 32bits is reserved as
zero. This inconsistency causes one bug in vhost vsock driver. The
scenarios is:

  0. A hash table (vhost_vsock_hash) is used to map an CID to a vsock
  object. And hash_min() is used to compute the hash key. hash_min() is
  defined as:
  (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)).
  That means the hash algorithm has dependency on the size of macro
  argument 'val'.
  0. In function vhost_vsock_set_cid(), a 64bit CID is passed to
  hash_min() to compute the hash key when inserting a vsock object into
  the hash table.
  0. In function vhost_vsock_get(), a 32bit CID is passed to hash_min()
  to compute the hash key when looking up a vsock for an CID.

Because the different size of the CID, hash_min() returns different hash
key, thus fails to look up the vsock object for an CID.

To fix this bug, we keep CID as u64 in the IOCTLs and virtio message
headers, but explicitly convert u64 to u32 when deal with the hash table
and vsock core.

Fixes: 834e772c8db0 ("vhost/vsock: fix use-after-free in network stack callers")
Link: https://github.com/stefanha/virtio/blob/vsock/trunk/content.tex
Signed-off-by: Zha Bin <[hidden email]>
Reviewed-by: Liu Jiang <[hidden email]>
Reviewed-by: Stefan Hajnoczi <[hidden email]>
Acked-by: Jason Wang <[hidden email]>
Signed-off-by: David S. Miller <[hidden email]>

(backported from commit 7fbe078c37aba3088359c9256c1a1d0c3e39ee81)
[minor context adjustment]
Signed-off-by: Stefan Bader <[hidden email]>
---

The same backport applied to all trees. Since it is in v5.0-rc3, it will
not be needed for unstable.

-Stefan

 drivers/vhost/vsock.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index c6f550155f53..fe1dd9cd5d4e 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -634,7 +634,7 @@ static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid)
  hash_del_rcu(&vsock->hash);
 
  vsock->guest_cid = guest_cid;
- hash_add_rcu(vhost_vsock_hash, &vsock->hash, guest_cid);
+ hash_add_rcu(vhost_vsock_hash, &vsock->hash, vsock->guest_cid);
  spin_unlock_bh(&vhost_vsock_lock);
 
  return 0;
--
2.17.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

ACK: [SRU B/C/D] vhost/vsock: fix vhost vsock cid hashing inconsistent

Colin Ian King-2
On 30/01/2019 13:45, Stefan Bader wrote:

> From: Zha Bin <[hidden email]>
>
> BugLink: https://bugs.launchpad.net/bugs/1813934
>
> The vsock core only supports 32bit CID, but the Virtio-vsock spec define
> CID (dst_cid and src_cid) as u64 and the upper 32bits is reserved as
> zero. This inconsistency causes one bug in vhost vsock driver. The
> scenarios is:
>
>   0. A hash table (vhost_vsock_hash) is used to map an CID to a vsock
>   object. And hash_min() is used to compute the hash key. hash_min() is
>   defined as:
>   (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)).
>   That means the hash algorithm has dependency on the size of macro
>   argument 'val'.
>   0. In function vhost_vsock_set_cid(), a 64bit CID is passed to
>   hash_min() to compute the hash key when inserting a vsock object into
>   the hash table.
>   0. In function vhost_vsock_get(), a 32bit CID is passed to hash_min()
>   to compute the hash key when looking up a vsock for an CID.
>
> Because the different size of the CID, hash_min() returns different hash
> key, thus fails to look up the vsock object for an CID.
>
> To fix this bug, we keep CID as u64 in the IOCTLs and virtio message
> headers, but explicitly convert u64 to u32 when deal with the hash table
> and vsock core.
>
> Fixes: 834e772c8db0 ("vhost/vsock: fix use-after-free in network stack callers")
> Link: https://github.com/stefanha/virtio/blob/vsock/trunk/content.tex
> Signed-off-by: Zha Bin <[hidden email]>
> Reviewed-by: Liu Jiang <[hidden email]>
> Reviewed-by: Stefan Hajnoczi <[hidden email]>
> Acked-by: Jason Wang <[hidden email]>
> Signed-off-by: David S. Miller <[hidden email]>
>
> (backported from commit 7fbe078c37aba3088359c9256c1a1d0c3e39ee81)
> [minor context adjustment]
> Signed-off-by: Stefan Bader <[hidden email]>
> ---
>
> The same backport applied to all trees. Since it is in v5.0-rc3, it will
> not be needed for unstable.
>
> -Stefan
>
>  drivers/vhost/vsock.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
> index c6f550155f53..fe1dd9cd5d4e 100644
> --- a/drivers/vhost/vsock.c
> +++ b/drivers/vhost/vsock.c
> @@ -634,7 +634,7 @@ static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid)
>   hash_del_rcu(&vsock->hash);
>  
>   vsock->guest_cid = guest_cid;
> - hash_add_rcu(vhost_vsock_hash, &vsock->hash, guest_cid);
> + hash_add_rcu(vhost_vsock_hash, &vsock->hash, vsock->guest_cid);
>   spin_unlock_bh(&vhost_vsock_lock);
>  
>   return 0;
>

Backport looks good to me. Thanks Stefan,

Acked-by: Colin Ian King <[hidden email]>

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

Re: [SRU B/C/D] vhost/vsock: fix vhost vsock cid hashing inconsistent

Seth Forshee
In reply to this post by Stefan Bader-2
On Wed, Jan 30, 2019 at 02:45:50PM +0100, Stefan Bader wrote:

> From: Zha Bin <[hidden email]>
>
> BugLink: https://bugs.launchpad.net/bugs/1813934
>
> The vsock core only supports 32bit CID, but the Virtio-vsock spec define
> CID (dst_cid and src_cid) as u64 and the upper 32bits is reserved as
> zero. This inconsistency causes one bug in vhost vsock driver. The
> scenarios is:
>
>   0. A hash table (vhost_vsock_hash) is used to map an CID to a vsock
>   object. And hash_min() is used to compute the hash key. hash_min() is
>   defined as:
>   (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)).
>   That means the hash algorithm has dependency on the size of macro
>   argument 'val'.
>   0. In function vhost_vsock_set_cid(), a 64bit CID is passed to
>   hash_min() to compute the hash key when inserting a vsock object into
>   the hash table.
>   0. In function vhost_vsock_get(), a 32bit CID is passed to hash_min()
>   to compute the hash key when looking up a vsock for an CID.
>
> Because the different size of the CID, hash_min() returns different hash
> key, thus fails to look up the vsock object for an CID.
>
> To fix this bug, we keep CID as u64 in the IOCTLs and virtio message
> headers, but explicitly convert u64 to u32 when deal with the hash table
> and vsock core.
>
> Fixes: 834e772c8db0 ("vhost/vsock: fix use-after-free in network stack callers")
> Link: https://github.com/stefanha/virtio/blob/vsock/trunk/content.tex
> Signed-off-by: Zha Bin <[hidden email]>
> Reviewed-by: Liu Jiang <[hidden email]>
> Reviewed-by: Stefan Hajnoczi <[hidden email]>
> Acked-by: Jason Wang <[hidden email]>
> Signed-off-by: David S. Miller <[hidden email]>
>
> (backported from commit 7fbe078c37aba3088359c9256c1a1d0c3e39ee81)
> [minor context adjustment]
> Signed-off-by: Stefan Bader <[hidden email]>

Acked-by: Seth Forshee <[hidden email]>

Applied to disco/master-next, thanks!

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

ACK: [SRU B/C/D] vhost/vsock: fix vhost vsock cid hashing inconsistent

Khaled Elmously
In reply to this post by Stefan Bader-2
On 2019-01-30 14:45:50 , Stefan Bader wrote:

> From: Zha Bin <[hidden email]>
>
> BugLink: https://bugs.launchpad.net/bugs/1813934
>
> The vsock core only supports 32bit CID, but the Virtio-vsock spec define
> CID (dst_cid and src_cid) as u64 and the upper 32bits is reserved as
> zero. This inconsistency causes one bug in vhost vsock driver. The
> scenarios is:
>
>   0. A hash table (vhost_vsock_hash) is used to map an CID to a vsock
>   object. And hash_min() is used to compute the hash key. hash_min() is
>   defined as:
>   (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)).
>   That means the hash algorithm has dependency on the size of macro
>   argument 'val'.
>   0. In function vhost_vsock_set_cid(), a 64bit CID is passed to
>   hash_min() to compute the hash key when inserting a vsock object into
>   the hash table.
>   0. In function vhost_vsock_get(), a 32bit CID is passed to hash_min()
>   to compute the hash key when looking up a vsock for an CID.
>
> Because the different size of the CID, hash_min() returns different hash
> key, thus fails to look up the vsock object for an CID.
>
> To fix this bug, we keep CID as u64 in the IOCTLs and virtio message
> headers, but explicitly convert u64 to u32 when deal with the hash table
> and vsock core.
>
> Fixes: 834e772c8db0 ("vhost/vsock: fix use-after-free in network stack callers")
> Link: https://github.com/stefanha/virtio/blob/vsock/trunk/content.tex
> Signed-off-by: Zha Bin <[hidden email]>
> Reviewed-by: Liu Jiang <[hidden email]>
> Reviewed-by: Stefan Hajnoczi <[hidden email]>
> Acked-by: Jason Wang <[hidden email]>
> Signed-off-by: David S. Miller <[hidden email]>
>
> (backported from commit 7fbe078c37aba3088359c9256c1a1d0c3e39ee81)
> [minor context adjustment]
> Signed-off-by: Stefan Bader <[hidden email]>
> ---
>
> The same backport applied to all trees. Since it is in v5.0-rc3, it will
> not be needed for unstable.
>
> -Stefan
>
>  drivers/vhost/vsock.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
> index c6f550155f53..fe1dd9cd5d4e 100644
> --- a/drivers/vhost/vsock.c
> +++ b/drivers/vhost/vsock.c
> @@ -634,7 +634,7 @@ static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid)
>   hash_del_rcu(&vsock->hash);
>  
>   vsock->guest_cid = guest_cid;
> - hash_add_rcu(vhost_vsock_hash, &vsock->hash, guest_cid);
> + hash_add_rcu(vhost_vsock_hash, &vsock->hash, vsock->guest_cid);
>   spin_unlock_bh(&vhost_vsock_lock);
>  
>   return 0;

Acked-by: Khalid Elmously <[hidden email]>


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

APPLIED(B,C): [SRU B/C/D] vhost/vsock: fix vhost vsock cid hashing inconsistent

Khaled Elmously
In reply to this post by Stefan Bader-2

On 2019-02-04 00:22:25 , Khaled Elmously wrote:

> On 2019-01-30 14:45:50 , Stefan Bader wrote:
> > From: Zha Bin <[hidden email]>
> >
> > BugLink: https://bugs.launchpad.net/bugs/1813934
> >
> > The vsock core only supports 32bit CID, but the Virtio-vsock spec define
> > CID (dst_cid and src_cid) as u64 and the upper 32bits is reserved as
> > zero. This inconsistency causes one bug in vhost vsock driver. The
> > scenarios is:
> >
> >   0. A hash table (vhost_vsock_hash) is used to map an CID to a vsock
> >   object. And hash_min() is used to compute the hash key. hash_min() is
> >   defined as:
> >   (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)).
> >   That means the hash algorithm has dependency on the size of macro
> >   argument 'val'.
> >   0. In function vhost_vsock_set_cid(), a 64bit CID is passed to
> >   hash_min() to compute the hash key when inserting a vsock object into
> >   the hash table.
> >   0. In function vhost_vsock_get(), a 32bit CID is passed to hash_min()
> >   to compute the hash key when looking up a vsock for an CID.
> >
> > Because the different size of the CID, hash_min() returns different hash
> > key, thus fails to look up the vsock object for an CID.
> >
> > To fix this bug, we keep CID as u64 in the IOCTLs and virtio message
> > headers, but explicitly convert u64 to u32 when deal with the hash table
> > and vsock core.
> >
> > Fixes: 834e772c8db0 ("vhost/vsock: fix use-after-free in network stack callers")
> > Link: https://github.com/stefanha/virtio/blob/vsock/trunk/content.tex
> > Signed-off-by: Zha Bin <[hidden email]>
> > Reviewed-by: Liu Jiang <[hidden email]>
> > Reviewed-by: Stefan Hajnoczi <[hidden email]>
> > Acked-by: Jason Wang <[hidden email]>
> > Signed-off-by: David S. Miller <[hidden email]>
> >
> > (backported from commit 7fbe078c37aba3088359c9256c1a1d0c3e39ee81)
> > [minor context adjustment]
> > Signed-off-by: Stefan Bader <[hidden email]>
> > ---
> >
> > The same backport applied to all trees. Since it is in v5.0-rc3, it will
> > not be needed for unstable.
> >
> > -Stefan
> >
> >  drivers/vhost/vsock.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
> > index c6f550155f53..fe1dd9cd5d4e 100644
> > --- a/drivers/vhost/vsock.c
> > +++ b/drivers/vhost/vsock.c
> > @@ -634,7 +634,7 @@ static int vhost_vsock_set_cid(struct vhost_vsock *vsock, u64 guest_cid)
> >   hash_del_rcu(&vsock->hash);
> >  
> >   vsock->guest_cid = guest_cid;
> > - hash_add_rcu(vhost_vsock_hash, &vsock->hash, guest_cid);
> > + hash_add_rcu(vhost_vsock_hash, &vsock->hash, vsock->guest_cid);
> >   spin_unlock_bh(&vhost_vsock_lock);
> >  
> >   return 0;
>
> Acked-by: Khalid Elmously <[hidden email]>
>

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team