]>
Commit | Line | Data |
---|---|---|
95777e06 GKH |
1 | From 7fbe078c37aba3088359c9256c1a1d0c3e39ee81 Mon Sep 17 00:00:00 2001 |
2 | From: Zha Bin <zhabin@linux.alibaba.com> | |
3 | Date: Tue, 8 Jan 2019 16:07:03 +0800 | |
4 | Subject: vhost/vsock: fix vhost vsock cid hashing inconsistent | |
5 | ||
6 | From: Zha Bin <zhabin@linux.alibaba.com> | |
7 | ||
8 | commit 7fbe078c37aba3088359c9256c1a1d0c3e39ee81 upstream. | |
9 | ||
10 | The vsock core only supports 32bit CID, but the Virtio-vsock spec define | |
11 | CID (dst_cid and src_cid) as u64 and the upper 32bits is reserved as | |
12 | zero. This inconsistency causes one bug in vhost vsock driver. The | |
13 | scenarios is: | |
14 | ||
15 | 0. A hash table (vhost_vsock_hash) is used to map an CID to a vsock | |
16 | object. And hash_min() is used to compute the hash key. hash_min() is | |
17 | defined as: | |
18 | (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits)). | |
19 | That means the hash algorithm has dependency on the size of macro | |
20 | argument 'val'. | |
21 | 0. In function vhost_vsock_set_cid(), a 64bit CID is passed to | |
22 | hash_min() to compute the hash key when inserting a vsock object into | |
23 | the hash table. | |
24 | 0. In function vhost_vsock_get(), a 32bit CID is passed to hash_min() | |
25 | to compute the hash key when looking up a vsock for an CID. | |
26 | ||
27 | Because the different size of the CID, hash_min() returns different hash | |
28 | key, thus fails to look up the vsock object for an CID. | |
29 | ||
30 | To fix this bug, we keep CID as u64 in the IOCTLs and virtio message | |
31 | headers, but explicitly convert u64 to u32 when deal with the hash table | |
32 | and vsock core. | |
33 | ||
34 | Fixes: 834e772c8db0 ("vhost/vsock: fix use-after-free in network stack callers") | |
35 | Link: https://github.com/stefanha/virtio/blob/vsock/trunk/content.tex | |
36 | Signed-off-by: Zha Bin <zhabin@linux.alibaba.com> | |
37 | Reviewed-by: Liu Jiang <gerry@linux.alibaba.com> | |
38 | Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> | |
39 | Acked-by: Jason Wang <jasowang@redhat.com> | |
40 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
41 | Signed-off-by: Shengjing Zhu <i@zhsj.me> | |
42 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
43 | ||
44 | ||
45 | --- | |
46 | drivers/vhost/vsock.c | 2 +- | |
47 | 1 file changed, 1 insertion(+), 1 deletion(-) | |
48 | ||
49 | --- a/drivers/vhost/vsock.c | |
50 | +++ b/drivers/vhost/vsock.c | |
51 | @@ -642,7 +642,7 @@ static int vhost_vsock_set_cid(struct vh | |
52 | hash_del_rcu(&vsock->hash); | |
53 | ||
54 | vsock->guest_cid = guest_cid; | |
55 | - hash_add_rcu(vhost_vsock_hash, &vsock->hash, guest_cid); | |
56 | + hash_add_rcu(vhost_vsock_hash, &vsock->hash, vsock->guest_cid); | |
57 | spin_unlock_bh(&vhost_vsock_lock); | |
58 | ||
59 | return 0; |