diff mbox series

[v3,2/3] migration/multifd: Duplicate the fd for the outgoing_args

Message ID 20240315032040.7974-3-farosas@suse.de (mailing list archive)
State New, archived
Headers show
Series migration mapped-ram fixes | expand

Commit Message

Fabiano Rosas March 15, 2024, 3:20 a.m. UTC
We currently store the file descriptor used during the main outgoing
channel creation to use it again when creating the multifd
channels.

Since this fd is used for the first iochannel, there's risk that the
QIOChannel gets freed and the fd closed while outgoing_args.fd still
has it available. This could lead to an fd-reuse bug.

Duplicate the outgoing_args fd to avoid this issue.

Suggested-by: Peter Xu <peterx@redhat.com>
Signed-off-by: Fabiano Rosas <farosas@suse.de>
---
 migration/fd.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

Comments

Peter Xu March 15, 2024, 11:39 a.m. UTC | #1
On Fri, Mar 15, 2024 at 12:20:39AM -0300, Fabiano Rosas wrote:
> We currently store the file descriptor used during the main outgoing
> channel creation to use it again when creating the multifd
> channels.
> 
> Since this fd is used for the first iochannel, there's risk that the
> QIOChannel gets freed and the fd closed while outgoing_args.fd still
> has it available. This could lead to an fd-reuse bug.
> 
> Duplicate the outgoing_args fd to avoid this issue.
> 
> Suggested-by: Peter Xu <peterx@redhat.com>
> Signed-off-by: Fabiano Rosas <farosas@suse.de>

Reviewed-by: Peter Xu <peterx@redhat.com>
diff mbox series

Patch

diff --git a/migration/fd.c b/migration/fd.c
index c07030f715..fe0d096abd 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -49,8 +49,7 @@  void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
 {
     QIOChannel *ioc;
     int fd = monitor_get_fd(monitor_cur(), fdname, errp);
-
-    outgoing_args.fd = -1;
+    int newfd;
 
     if (fd == -1) {
         return;
@@ -63,7 +62,17 @@  void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **
         return;
     }
 
-    outgoing_args.fd = fd;
+    /*
+     * This is dup()ed just to avoid referencing an fd that might
+     * be already closed by the iochannel.
+     */
+    newfd = dup(fd);
+    if (newfd == -1) {
+        error_setg_errno(errp, errno, "Could not dup FD %d", fd);
+        object_unref(ioc);
+        return;
+    }
+    outgoing_args.fd = newfd;
 
     qio_channel_set_name(ioc, "migration-fd-outgoing");
     migration_channel_connect(s, ioc, NULL, NULL);