vhost: fix crash on port deletion
authorGaoxiang Liu <liugaoxiang@huawei.com>
Thu, 2 Sep 2021 15:45:53 +0000 (23:45 +0800)
committerMaxime Coquelin <maxime.coquelin@redhat.com>
Tue, 14 Sep 2021 11:21:57 +0000 (13:21 +0200)
commit451dc0fad83d07d194e688f52093c7e888d2e317
tree562b294e1d30202aeaa80c75a423d712ec5646ba
parent848e93d9001e74fdbcb31b7ac5cdc1991b9e3f03
vhost: fix crash on port deletion

The rte_vhost_driver_unregister() and vhost_user_read_cb()
can be called at the same time by 2 threads.
when memory of vsocket is freed in rte_vhost_driver_unregister(),
the invalid memory of vsocket is accessed in vhost_user_read_cb().
It's a bug of both mode for vhost as server or client.

E.g., vhostuser port is created as server.
Thread1 calls rte_vhost_driver_unregister().
Before the listen fd is deleted from poll waiting fds,
"vhost-events" thread then calls vhost_user_server_new_connection(),
then a new conn fd is added in fdset when trying to reconnect.
"vhost-events" thread then calls vhost_user_read_cb() and
accesses invalid memory of socket while thread1 frees the memory of
vsocket.

E.g., vhostuser port is created as client.
Thread1 calls rte_vhost_driver_unregister().
Before vsocket of reconn is deleted from reconn list,
"vhost_reconn" thread then calls vhost_user_add_connection()
then a new conn fd is added in fdset when trying to reconnect.
"vhost-events" thread then calls vhost_user_read_cb() and
accesses invalid memory of socket while thread1 frees the memory of
vsocket.

The fix is to move the "fdset_try_del" in front of free memory of conn,
then avoid the race condition.

The core trace is:
Program terminated with signal 11, Segmentation fault.

Fixes: 52d874dc6705 ("vhost: fix crash on closing in client mode")
Cc: stable@dpdk.org
Signed-off-by: Gaoxiang Liu <liugaoxiang@huawei.com>
Reviewed-by: Chenbo Xia <chenbo.xia@intel.com>
lib/vhost/socket.c