[PATCH 1/2] libvhost-user: accept the postcopy client base ack in vu_add_mem_reg()

Bin Guo <[email protected]>
Newsgroups gmane.comp.emulators.qemu
Message-ID <[email protected]>
In postcopy mode QEMU signals that it has collected all the postcopy client
bases by sending a VHOST_USER_ADD_MEM_REG message with a u64 payload of 0
and no file descriptor (see vhost_user_add_remove_regions()).
vu_add_mem_reg() has a case for that message, but only reaches it after
validating the fd count of a regular region, so the ack is rejected first:

  VHOST_USER_ADD_MEM_REG received 0 fds - only 1 fd should be sent for
  this message type

This kills the backend during memory table setup, making postcopy unusable
for any libvhost-user backend that negotiates
VHOST_USER_PROTOCOL_F_CONFIGURE_MEM_SLOTS.

Recognise the ack before validating the fd count.

Fixes: 9f4e63491b ("libvhost-user: Add vu_add_mem_reg input validation")
Signed-off-by: Bin Guo <[email protected]>
---
 subprojects/libvhost-user/libvhost-user.c | 26 ++++++++++++-----------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/subprojects/libvhost-user/libvhost-user.c b/subprojects/libvhost-user/libvhost-user.c
index a74d814bb4..248550aae1 100644
--- a/subprojects/libvhost-user/libvhost-user.c
+++ b/subprojects/libvhost-user/libvhost-user.c
@@ -948,6 +948,20 @@ static bool
 vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
     VhostUserMemoryRegion m = vmsg->payload.memreg.region, *msg_region = &m;
 
+    /*
+     * If we are in postcopy mode and we receive a u64 payload with a 0 value
+     * we know all the postcopy client bases have been received, and we
+     * should start generating faults.  This message carries no file
+     * descriptor, so it has to be recognised before the fd count of a real
+     * region is validated below.
+     */
+    if (dev->postcopy_listening &&
+        vmsg->size == sizeof(vmsg->payload.u64) &&
+        vmsg->payload.u64 == 0) {
+        (void)generate_faults(dev);
+        return false;
+    }
+
     if (vmsg->fd_num != 1) {
         vmsg_close_fds(vmsg);
         vu_panic(dev, "VHOST_USER_ADD_MEM_REG received %d fds - only 1 fd "
@@ -971,18 +985,6 @@ vu_add_mem_reg(VuDev *dev, VhostUserMsg *vmsg) {
         return false;
     }
 
-    /*
-     * If we are in postcopy mode and we receive a u64 payload with a 0 value
-     * we know all the postcopy client bases have been received, and we
-     * should start generating faults.
-     */
-    if (dev->postcopy_listening &&
-        vmsg->size == sizeof(vmsg->payload.u64) &&
-        vmsg->payload.u64 == 0) {
-        (void)generate_faults(dev);
-        return false;
-    }
-
     _vu_add_mem_reg(dev, msg_region, vmsg->fds[0]);
     close(vmsg->fds[0]);
 
-- 
2.50.1 (Apple Git-155)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.