diff --git a/meson.build b/meson.build
index 217500ef0156641262042d29fb8bee29e7d599e6..906d63c2712a57c85e0255628eee07ba647630e8 100644
--- a/meson.build
+++ b/meson.build
@@ -171,6 +171,8 @@ executable(
     'src/bwrap-lock.h',
     'src/glib-backports.c',
     'src/glib-backports.h',
+    'src/flatpak-utils-base.c',
+    'src/flatpak-utils-base-private.h',
     'src/flatpak-utils.c',
     'src/flatpak-utils-private.h',
     'src/utils.c',
@@ -203,6 +205,8 @@ executable(
     'src/flatpak-bwrap-private.h',
     'src/flatpak-run.c',
     'src/flatpak-run-private.h',
+    'src/flatpak-utils-base.c',
+    'src/flatpak-utils-base-private.h',
     'src/flatpak-utils.c',
     'src/flatpak-utils-private.h',
     'src/utils.c',
diff --git a/src/flatpak-bwrap.c b/src/flatpak-bwrap.c
index 626e8eaa060393f43c0c589171cdbf005c9704ce..7356a97dc6093eae2ec8152713d06bf75b1afc2d 100644
--- a/src/flatpak-bwrap.c
+++ b/src/flatpak-bwrap.c
@@ -34,6 +34,7 @@
 #include "libglnx.h"
 
 #include "flatpak-bwrap-private.h"
+#include "flatpak-utils-base-private.h"
 #include "flatpak-utils-private.h"
 
 #include "glib-backports.h"
diff --git a/src/flatpak-run.c b/src/flatpak-run.c
index 20c4fbcd997d5e4c8d31ca19efd349c0a4e46776..e4ccd6c8dadcc96691d9746ed7f741101a25b0ea 100644
--- a/src/flatpak-run.c
+++ b/src/flatpak-run.c
@@ -27,6 +27,7 @@
 #include <X11/Xauth.h>
 #include <gio/gio.h>
 
+#include "flatpak-utils-base-private.h"
 #include "flatpak-utils-private.h"
 
 /* In Flatpak this is optional, in pressure-vessel not so much */
diff --git a/src/flatpak-utils-base-private.h b/src/flatpak-utils-base-private.h
new file mode 100644
index 0000000000000000000000000000000000000000..181a0c9587f95368693a38c8b4fa5157595f3077
--- /dev/null
+++ b/src/flatpak-utils-base-private.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2019 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __FLATPAK_UTILS_BASE_H__
+#define __FLATPAK_UTILS_BASE_H__
+
+#include <glib.h>
+
+char *flatpak_get_timezone (void);
+
+char * flatpak_readlink (const char *path,
+                         GError    **error);
+char * flatpak_resolve_link (const char *path,
+                             GError    **error);
+char * flatpak_canonicalize_filename (const char *path);
+void   flatpak_close_fds_workaround (int start_fd);
+
+#endif /* __FLATPAK_UTILS_BASE_H__ */
diff --git a/src/flatpak-utils-base.c b/src/flatpak-utils-base.c
new file mode 100644
index 0000000000000000000000000000000000000000..aa535a4a4cdebca8a459980012f9da77b37191ba
--- /dev/null
+++ b/src/flatpak-utils-base.c
@@ -0,0 +1,115 @@
+/*
+ * Taken from Flatpak
+ * Copyright © 2019 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *       Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "flatpak-utils-base-private.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <gio/gio.h>
+#include "libglnx.h"
+
+char *
+flatpak_get_timezone (void)
+{
+  g_autofree gchar *symlink = NULL;
+  gchar *etc_timezone = NULL;
+  const gchar *tzdir;
+
+  tzdir = getenv ("TZDIR");
+  if (tzdir == NULL)
+    tzdir = "/usr/share/zoneinfo";
+
+  symlink = flatpak_resolve_link ("/etc/localtime", NULL);
+  if (symlink != NULL)
+    {
+      /* Resolve relative path */
+      g_autofree gchar *canonical = flatpak_canonicalize_filename (symlink);
+      char *canonical_suffix;
+
+      /* Strip the prefix and slashes if possible. */
+      if (g_str_has_prefix (canonical, tzdir))
+        {
+          canonical_suffix = canonical + strlen (tzdir);
+          while (*canonical_suffix == '/')
+            canonical_suffix++;
+
+          return g_strdup (canonical_suffix);
+        }
+    }
+
+  if (g_file_get_contents ("/etc/timezeone", &etc_timezone,
+                           NULL, NULL))
+    {
+      g_strchomp (etc_timezone);
+      return etc_timezone;
+    }
+
+  /* Final fall-back is UTC */
+  return g_strdup ("UTC");
+}
+
+char *
+flatpak_readlink (const char *path,
+                  GError    **error)
+{
+  return glnx_readlinkat_malloc (-1, path, NULL, error);
+}
+
+char *
+flatpak_resolve_link (const char *path,
+                      GError    **error)
+{
+  g_autofree char *link = flatpak_readlink (path, error);
+  g_autofree char *dirname = NULL;
+
+  if (link == NULL)
+    return NULL;
+
+  if (g_path_is_absolute (link))
+    return g_steal_pointer (&link);
+
+  dirname = g_path_get_dirname (path);
+  return g_build_filename (dirname, link, NULL);
+}
+
+char *
+flatpak_canonicalize_filename (const char *path)
+{
+  g_autoptr(GFile) file = g_file_new_for_path (path);
+  return g_file_get_path (file);
+}
+
+/* There is a dead-lock in glib versions before 2.60 when it closes
+ * the fds. See:  https://gitlab.gnome.org/GNOME/glib/merge_requests/490
+ * This was hitting the test-suite a lot, so we work around it by using
+ * the G_SPAWN_LEAVE_DESCRIPTORS_OPEN/G_SUBPROCESS_FLAGS_INHERIT_FDS flag
+ * and setting CLOEXEC ourselves.
+ */
+void
+flatpak_close_fds_workaround (int start_fd)
+{
+  int max_open_fds = sysconf (_SC_OPEN_MAX);
+  int fd;
+
+  for (fd = start_fd; fd < max_open_fds; fd++)
+    fcntl (fd, F_SETFD, FD_CLOEXEC);
+}
diff --git a/src/flatpak-utils-private.h b/src/flatpak-utils-private.h
index 736cca1a7248d0cb360797f06c97ebdbfacd7b40..2c7cbf4a954d7b26e4f9b9668ff20a91a1fd5de6 100644
--- a/src/flatpak-utils-private.h
+++ b/src/flatpak-utils-private.h
@@ -37,17 +37,10 @@
  * it as a path into the sandbox */
 char * flatpak_get_real_xdg_runtime_dir (void);
 
-char *flatpak_get_timezone (void);
 
 char * flatpak_quote_argv (const char *argv[],
                            gssize      len);
 
-char * flatpak_readlink (const char *path,
-                         GError    **error);
-char * flatpak_resolve_link (const char *path,
-                             GError    **error);
-char * flatpak_canonicalize_filename (const char *path);
-
 gboolean flatpak_buffer_to_sealed_memfd_or_tmpfile (GLnxTmpfile *tmpf,
                                                     const char  *name,
                                                     const char  *str,
diff --git a/src/flatpak-utils.c b/src/flatpak-utils.c
index 04112cdac1074a85614f1a5f6ef2a70078d83d9e..fbea468e8754bab96a0a65ba83bce9828fe31ee1 100644
--- a/src/flatpak-utils.c
+++ b/src/flatpak-utils.c
@@ -1,7 +1,7 @@
 /*
  * A cut-down version of common/flatpak-utils from Flatpak
  *
- * Copyright © 2014 Red Hat, Inc
+ * Copyright © 2014-2019 Red Hat, Inc
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -37,6 +37,9 @@
 #include <sys/ioctl.h>
 #include <termios.h>
 
+#include <glib.h>
+#include "flatpak-utils-base-private.h"
+
 /* To keep this more similar to the original file, we explicitly disable
  * this warning rather than fixing it */
 #pragma GCC diagnostic ignored "-Wshadow"
@@ -51,46 +54,6 @@ flatpak_get_real_xdg_runtime_dir (void)
   return realpath (g_get_user_runtime_dir (), NULL);
 }
 
-char *
-flatpak_get_timezone (void)
-{
-  g_autofree gchar *symlink = NULL;
-  gchar *etc_timezone = NULL;
-  const gchar *tzdir;
-
-  tzdir = getenv ("TZDIR");
-  if (tzdir == NULL)
-    tzdir = "/usr/share/zoneinfo";
-
-  symlink = flatpak_resolve_link ("/etc/localtime", NULL);
-  if (symlink != NULL)
-    {
-      /* Resolve relative path */
-      g_autofree gchar *canonical = flatpak_canonicalize_filename (symlink);
-      char *canonical_suffix;
-
-      /* Strip the prefix and slashes if possible. */
-      if (g_str_has_prefix (canonical, tzdir))
-        {
-          canonical_suffix = canonical + strlen (tzdir);
-          while (*canonical_suffix == '/')
-            canonical_suffix++;
-
-          return g_strdup (canonical_suffix);
-        }
-    }
-
-  if (g_file_get_contents ("/etc/timezeone", &etc_timezone,
-                           NULL, NULL))
-    {
-      g_strchomp (etc_timezone);
-      return etc_timezone;
-    }
-
-  /* Final fall-back is UTC */
-  return g_strdup ("UTC");
-}
-
 static gboolean
 needs_quoting (const char *arg)
 {
@@ -134,37 +97,6 @@ flatpak_quote_argv (const char *argv[],
   return g_string_free (res, FALSE);
 }
 
-char *
-flatpak_readlink (const char *path,
-                  GError    **error)
-{
-  return glnx_readlinkat_malloc (-1, path, NULL, error);
-}
-
-char *
-flatpak_resolve_link (const char *path,
-                      GError    **error)
-{
-  g_autofree char *link = flatpak_readlink (path, error);
-  g_autofree char *dirname = NULL;
-
-  if (link == NULL)
-    return NULL;
-
-  if (g_path_is_absolute (link))
-    return g_steal_pointer (&link);
-
-  dirname = g_path_get_dirname (path);
-  return g_build_filename (dirname, link, NULL);
-}
-
-char *
-flatpak_canonicalize_filename (const char *path)
-{
-  g_autoptr(GFile) file = g_file_new_for_path (path);
-  return g_file_get_path (file);
-}
-
 /* If memfd_create() is available, generate a sealed memfd with contents of
  * @str. Otherwise use an O_TMPFILE @tmpf in anonymous mode, write @str to
  * @tmpf, and lseek() back to the start. See also similar uses in e.g.
diff --git a/src/utils.c b/src/utils.c
index 1076a78ecbf001d3732a7f59be449f477815808f..bf7e537147d31f20038b5a89f9250ce2b855db66 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -30,6 +30,7 @@
 
 #include "glib-backports.h"
 #include "flatpak-bwrap-private.h"
+#include "flatpak-utils-base-private.h"
 #include "flatpak-utils-private.h"
 
 /**
diff --git a/src/wrap.c b/src/wrap.c
index 7d0c864490433ea5c4ff2922ac7441444c808318..85cf36e1809d59ffaa542423d5fd9d46a8a113f4 100644
--- a/src/wrap.c
+++ b/src/wrap.c
@@ -41,6 +41,7 @@
 #include "bwrap-lock.h"
 #include "flatpak-bwrap-private.h"
 #include "flatpak-run-private.h"
+#include "flatpak-utils-base-private.h"
 #include "flatpak-utils-private.h"
 #include "utils.h"
 #include "wrap-interactive.h"