diff -Nru glib2.0-2.68.4/debian/changelog glib2.0-2.68.4/debian/changelog --- glib2.0-2.68.4/debian/changelog 2021-10-12 06:39:07.000000000 -0600 +++ glib2.0-2.68.4/debian/changelog 2021-12-21 16:38:43.000000000 -0700 @@ -1,3 +1,9 @@ +glib2.0 (2.68.4-1ubuntu2) impish; urgency=medium + + * Backport gspawn fixes. + + -- Dan Nicholson Tue, 21 Dec 2021 16:38:43 -0700 + glib2.0 (2.68.4-1ubuntu1) impish; urgency=medium * Cherry-pick merge request 2291 to fix network monitoring with latest diff -Nru glib2.0-2.68.4/debian/patches/0001-gspawn-use-close_and_invalidate-more.patch glib2.0-2.68.4/debian/patches/0001-gspawn-use-close_and_invalidate-more.patch --- glib2.0-2.68.4/debian/patches/0001-gspawn-use-close_and_invalidate-more.patch 1969-12-31 17:00:00.000000000 -0700 +++ glib2.0-2.68.4/debian/patches/0001-gspawn-use-close_and_invalidate-more.patch 2021-12-21 16:38:43.000000000 -0700 @@ -0,0 +1,25 @@ +From 33b58789947e965585ad49aec9cc8d52c6da2bcd Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Tue, 14 Dec 2021 13:36:24 -0600 +Subject: [PATCH 1/3] gspawn: use close_and_invalidate more + +--- + glib/gspawn.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/glib/gspawn.c b/glib/gspawn.c +index a15fb1ca13..5d8422869b 100644 +--- a/glib/gspawn.c ++++ b/glib/gspawn.c +@@ -1710,7 +1710,7 @@ do_exec (gint child_err_report_fd, + child_err_report_fd = safe_dup (child_err_report_fd); + + safe_dup2 (source_fds[i], target_fds[i]); +- (void) close (source_fds[i]); ++ close_and_invalidate (&source_fds[i]); + } + } + } +-- +2.30.2 + diff -Nru glib2.0-2.68.4/debian/patches/0002-gspawn-fix-hangs-when-duping-child_err_report_fd.patch glib2.0-2.68.4/debian/patches/0002-gspawn-fix-hangs-when-duping-child_err_report_fd.patch --- glib2.0-2.68.4/debian/patches/0002-gspawn-fix-hangs-when-duping-child_err_report_fd.patch 1969-12-31 17:00:00.000000000 -0700 +++ glib2.0-2.68.4/debian/patches/0002-gspawn-fix-hangs-when-duping-child_err_report_fd.patch 2021-12-21 16:38:43.000000000 -0700 @@ -0,0 +1,57 @@ +From 26511458f3c6fb21e7febe47398aaae3e9e86f7a Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Tue, 14 Dec 2021 13:36:26 -0600 +Subject: [PATCH 2/3] gspawn: fix hangs when duping child_err_report_fd + +In case child_err_report_fd conflicts with one of the target_fds, the +code here is careful to dup child_err_report_fd in order to avoid +conflating the two. It was a good idea, but evidently was not tested, +because the newly-created fd is not created with CLOEXEC set. This means +it stays open in the child process, causing the parent to hang forever +waiting to read from the other end of the pipe. Oops! + +The fix is simple: just set CLOEXEC. This removes our only usage of the +safe_dup() function, so it can be dropped. + +Fixes #2506 +--- + glib/gspawn.c | 16 +--------------- + 1 file changed, 1 insertion(+), 15 deletions(-) + +diff --git a/glib/gspawn.c b/glib/gspawn.c +index 5d8422869b..673889ce7d 100644 +--- a/glib/gspawn.c ++++ b/glib/gspawn.c +@@ -1500,20 +1500,6 @@ safe_closefrom (int lowfd) + #endif + } + +-/* This function is called between fork() and exec() and hence must be +- * async-signal-safe (see signal-safety(7)). */ +-static gint +-safe_dup (gint fd) +-{ +- gint ret; +- +- do +- ret = dup (fd); +- while (ret < 0 && (errno == EINTR || errno == EBUSY)); +- +- return ret; +-} +- + /* This function is called between fork() and exec() and hence must be + * async-signal-safe (see signal-safety(7)). */ + static gint +@@ -1707,7 +1693,7 @@ do_exec (gint child_err_report_fd, + else + { + if (target_fds[i] == child_err_report_fd) +- child_err_report_fd = safe_dup (child_err_report_fd); ++ child_err_report_fd = dupfd_cloexec (child_err_report_fd); + + safe_dup2 (source_fds[i], target_fds[i]); + close_and_invalidate (&source_fds[i]); +-- +2.30.2 + diff -Nru glib2.0-2.68.4/debian/patches/0003-gspawn-fix-fd-remapping-conflation-issue.patch glib2.0-2.68.4/debian/patches/0003-gspawn-fix-fd-remapping-conflation-issue.patch --- glib2.0-2.68.4/debian/patches/0003-gspawn-fix-fd-remapping-conflation-issue.patch 1969-12-31 17:00:00.000000000 -0700 +++ glib2.0-2.68.4/debian/patches/0003-gspawn-fix-fd-remapping-conflation-issue.patch 2021-12-21 16:38:43.000000000 -0700 @@ -0,0 +1,123 @@ +From 9e5f20fc2f4d90b48d8d96912757d357c07bd561 Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Tue, 14 Dec 2021 13:36:27 -0600 +Subject: [PATCH 3/3] gspawn: fix fd remapping conflation issue + +We currently dup all source fds to avoid possible conflation with the +target fds, but fail to consider that the result of a dup might itself +conflict with one of the target fds. Solve this the easy way by duping +all source_fds to values that are greater than the largest fd in +target_fds. + +Fixes #2503 +--- + glib/gspawn.c | 49 +++++++++++++++++++++++++++++++------------------ + 1 file changed, 31 insertions(+), 18 deletions(-) + +diff --git a/glib/gspawn.c b/glib/gspawn.c +index 673889ce7d..e45e1ebf70 100644 +--- a/glib/gspawn.c ++++ b/glib/gspawn.c +@@ -1258,13 +1258,13 @@ unset_cloexec (int fd) + /* This function is called between fork() and exec() and hence must be + * async-signal-safe (see signal-safety(7)). */ + static int +-dupfd_cloexec (int parent_fd) ++dupfd_cloexec (int old_fd, int new_fd_min) + { + int fd, errsv; + #ifdef F_DUPFD_CLOEXEC + do + { +- fd = fcntl (parent_fd, F_DUPFD_CLOEXEC, 3); ++ fd = fcntl (old_fd, F_DUPFD_CLOEXEC, new_fd_min); + errsv = errno; + } + while (fd == -1 && errsv == EINTR); +@@ -1275,7 +1275,7 @@ dupfd_cloexec (int parent_fd) + int result, flags; + do + { +- fd = fcntl (parent_fd, F_DUPFD, 3); ++ fd = fcntl (old_fd, F_DUPFD, new_fd_min); + errsv = errno; + } + while (fd == -1 && errsv == EINTR); +@@ -1563,6 +1563,7 @@ do_exec (gint child_err_report_fd, + gpointer user_data) + { + gsize i; ++ gint max_target_fd = 0; + + if (working_directory && chdir (working_directory) < 0) + write_err_and_exit (child_err_report_fd, +@@ -1661,39 +1662,51 @@ do_exec (gint child_err_report_fd, + /* + * Work through the @source_fds and @target_fds mapping. + * +- * Based on code derived from ++ * Based on code originally derived from + * gnome-terminal:src/terminal-screen.c:terminal_screen_child_setup(), +- * used under the LGPLv2+ with permission from author. ++ * used under the LGPLv2+ with permission from author. (The code has ++ * since migrated to vte:src/spawn.cc:SpawnContext::exec and is no longer ++ * terribly similar to what we have here.) + */ + +- /* Basic fd assignments (where source == target) we can just unset FD_CLOEXEC +- * +- * If we're doing remapping fd assignments, we need to handle +- * the case where the user has specified e.g.: +- * 5 -> 4, 4 -> 6 +- * +- * We do this by duping the source fds temporarily in a first pass. +- * +- * If any of the @target_fds conflict with @child_err_report_fd, dup the +- * latter so it doesn’t get conflated. +- */ + if (n_fds > 0) + { ++ for (i = 0; i < n_fds; i++) ++ max_target_fd = MAX (max_target_fd, target_fds[i]); ++ ++ if (max_target_fd == G_MAXINT) ++ { ++ errno = EINVAL; ++ write_err_and_exit (child_err_report_fd, CHILD_DUP2_FAILED); ++ } ++ ++ /* If we're doing remapping fd assignments, we need to handle ++ * the case where the user has specified e.g. 5 -> 4, 4 -> 6. ++ * We do this by duping all source fds, taking care to ensure the new ++ * fds are larger than any target fd to avoid introducing new conflicts. ++ */ + for (i = 0; i < n_fds; i++) + { + if (source_fds[i] != target_fds[i]) +- source_fds[i] = dupfd_cloexec (source_fds[i]); ++ source_fds[i] = dupfd_cloexec (source_fds[i], max_target_fd + 1); + } ++ + for (i = 0; i < n_fds; i++) + { ++ /* For basic fd assignments (where source == target), we can just ++ * unset FD_CLOEXEC. ++ */ + if (source_fds[i] == target_fds[i]) + { + unset_cloexec (source_fds[i]); + } + else + { ++ /* If any of the @target_fds conflict with @child_err_report_fd, ++ * dup it so it doesn’t get conflated. ++ */ + if (target_fds[i] == child_err_report_fd) +- child_err_report_fd = dupfd_cloexec (child_err_report_fd); ++ child_err_report_fd = dupfd_cloexec (child_err_report_fd, max_target_fd + 1); + + safe_dup2 (source_fds[i], target_fds[i]); + close_and_invalidate (&source_fds[i]); +-- +2.30.2 + diff -Nru glib2.0-2.68.4/debian/patches/series glib2.0-2.68.4/debian/patches/series --- glib2.0-2.68.4/debian/patches/series 2021-10-12 06:39:00.000000000 -0600 +++ glib2.0-2.68.4/debian/patches/series 2021-12-21 16:38:43.000000000 -0700 @@ -14,3 +14,6 @@ debian/testfilemonitor-Skip-if-we-are-avoiding-flaky-tests.patch debian/gdbus-server-auth-Normally-skip-flaky-DBUS_COOKIE_SHA1-te.patch gnetworkmonitornm-Stop-using-removed-PropertiesChang.patch +0001-gspawn-use-close_and_invalidate-more.patch +0002-gspawn-fix-hangs-when-duping-child_err_report_fd.patch +0003-gspawn-fix-fd-remapping-conflation-issue.patch