• Zha Bin's avatar
    vhost/vsock: fix vhost vsock cid hashing inconsistent · 7fbe078c
    Zha Bin authored
    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: 834e772c ("vhost/vsock: fix use-after-free in network stack callers")
    Link: https://github.com/stefanha/virtio/blob/vsock/trunk/content.tex
    Signed-off-by: default avatarZha Bin <zhabin@linux.alibaba.com>
    Reviewed-by: default avatarLiu Jiang <gerry@linux.alibaba.com>
    Reviewed-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
    Acked-by: default avatarJason Wang <jasowang@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>