diff --git a/src/flatpak-exports-private.h b/src/flatpak-exports-private.h
index 6da3bef4b0714874090e745154b7a117a903519e..6e382fa2d9fd4e5ac41a34ee7c3c6622390aecc6 100644
--- a/src/flatpak-exports-private.h
+++ b/src/flatpak-exports-private.h
@@ -62,5 +62,8 @@ FlatpakFilesystemMode flatpak_exports_path_get_mode (FlatpakExports *exports,
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (FlatpakExports, flatpak_exports_free);
 
+void flatpak_exports_take_host_fd (FlatpakExports *exports,
+                                   int             fd);
+
 
 #endif /* __FLATPAK_EXPORTS_H__ */
diff --git a/src/flatpak-exports.c b/src/flatpak-exports.c
index eb072a21ed0928b92984f266727df5d6e4b3ca58..99d4de03687395bf7c61cd41e942d64657cb46de 100644
--- a/src/flatpak-exports.c
+++ b/src/flatpak-exports.c
@@ -110,8 +110,59 @@ struct _FlatpakExports
   GHashTable           *hash;
   FlatpakFilesystemMode host_etc;
   FlatpakFilesystemMode host_os;
+  int                   host_fd;
 };
 
+/*
+ * When populating /run/host, pretend @fd was the root of the host
+ * filesystem.
+ */
+void
+flatpak_exports_take_host_fd (FlatpakExports *exports,
+                              int fd)
+{
+  glnx_close_fd (&exports->host_fd);
+
+  if (fd >= 0)
+    exports->host_fd = fd;
+}
+
+static gboolean
+flatpak_exports_stat_in_host (FlatpakExports *exports,
+                              const char *abs_path,
+                              struct stat *buf,
+                              int flags,
+                              GError **error)
+{
+  g_return_val_if_fail (abs_path[0] == '/', FALSE);
+
+  if (exports->host_fd >= 0)
+    {
+      /* If abs_path is "/usr", then stat "usr" relative to host_fd.
+       * As a special case, if abs_path is "/", stat host_fd itself,
+       * due to the use of AT_EMPTY_PATH. */
+      return glnx_fstatat (exports->host_fd, &abs_path[1], buf,
+                           AT_EMPTY_PATH | flags,
+                           error);
+    }
+
+  return glnx_fstatat (AT_FDCWD, abs_path, buf, flags, error);
+}
+
+static gchar *
+flatpak_exports_readlink_in_host (FlatpakExports *exports,
+                                  const char *abs_path,
+                                  GError **error)
+{
+  g_return_val_if_fail (abs_path[0] == '/', FALSE);
+
+  if (exports->host_fd >= 0)
+    return glnx_readlinkat_malloc (exports->host_fd, &abs_path[1],
+                                   NULL, error);
+
+  return glnx_readlinkat_malloc (AT_FDCWD, abs_path, NULL, error);
+}
+
 static void
 exported_path_free (ExportedPath *exported_path)
 {
@@ -125,6 +176,7 @@ flatpak_exports_new (void)
   FlatpakExports *exports = g_new0 (FlatpakExports, 1);
 
   exports->hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GFreeFunc) exported_path_free);
+  exports->host_fd = -1;
   return exports;
 }
 
@@ -250,15 +302,15 @@ path_is_symlink (const char *path)
 typedef struct
 {
   const char *name;
-  GFileTest test;
+  int ifmt;
 } LibsNeedEtc;
 
 static const LibsNeedEtc libs_need_etc[] =
 {
   /* glibc */
-  { "ld.so.cache", G_FILE_TEST_IS_REGULAR },
+  { "ld.so.cache", S_IFREG },
   /* Used for executables and a few libraries on e.g. Debian */
-  { "alternatives", G_FILE_TEST_IS_DIR }
+  { "alternatives", S_IFDIR }
 };
 
 void
@@ -269,6 +321,7 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports,
   g_autofree const char **keys = (const char **) g_hash_table_get_keys_as_array (exports->hash, &n_keys);
   g_autoptr(GList) eps = NULL;
   GList *l;
+  struct stat buf;
 
   eps = g_hash_table_get_values (exports->hash);
   eps = g_list_sort (eps, (GCompareFunc) compare_eps);
@@ -332,7 +385,8 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports,
       if (exports->host_os == FLATPAK_FILESYSTEM_MODE_READ_ONLY)
         os_bind_mode = "--ro-bind";
 
-      if (g_file_test ("/usr", G_FILE_TEST_IS_DIR))
+      if (flatpak_exports_stat_in_host (exports, "/usr", &buf, 0, NULL) &&
+          S_ISDIR (buf.st_mode))
         flatpak_bwrap_add_args (bwrap,
                                 os_bind_mode, "/usr", "/run/host/usr", NULL);
 
@@ -345,7 +399,7 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports,
           g_assert (subdir[0] == '/');
           /* e.g. /run/host/lib32 */
           run_host_subdir = g_strconcat ("/run/host", subdir, NULL);
-          target = glnx_readlinkat_malloc (-1, subdir, NULL, NULL);
+          target = flatpak_exports_readlink_in_host (exports, subdir, NULL);
 
           if (target != NULL &&
               g_str_has_prefix (target, "usr/"))
@@ -367,7 +421,8 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports,
                                       "--symlink", target + 1, run_host_subdir,
                                       NULL);
             }
-          else if (g_file_test (subdir, G_FILE_TEST_IS_DIR))
+          else if (flatpak_exports_stat_in_host (exports, subdir, &buf, 0, NULL) &&
+                   S_ISDIR (buf.st_mode))
             {
               /* e.g. /lib32 is a symlink to /opt/compat/ia32/lib,
                * or is a plain directory because the host OS has not
@@ -394,7 +449,9 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports,
               const LibsNeedEtc *item = &libs_need_etc[i];
               g_autofree gchar *host_path = g_strconcat ("/etc/", item->name, NULL);
 
-              if (g_file_test (host_path, item->test))
+              if (flatpak_exports_stat_in_host (exports, host_path,
+                                                &buf, 0, NULL) &&
+                  (buf.st_mode & S_IFMT) == item->ifmt)
                 {
                   g_autofree gchar *run_host_path = g_strconcat ("/run/host/etc/", item->name, NULL);
 
@@ -416,7 +473,8 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports,
       if (exports->host_etc == FLATPAK_FILESYSTEM_MODE_READ_ONLY)
         etc_bind_mode = "--ro-bind";
 
-      if (g_file_test ("/etc", G_FILE_TEST_IS_DIR))
+      if (flatpak_exports_stat_in_host (exports, "/etc", &buf, 0, NULL) &&
+          S_ISDIR (buf.st_mode))
         flatpak_bwrap_add_args (bwrap,
                                 etc_bind_mode, "/etc", "/run/host/etc", NULL);
     }
@@ -424,9 +482,9 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports,
   /* As per the os-release specification https://www.freedesktop.org/software/systemd/man/os-release.html
    * always read-only bind-mount /etc/os-release if it exists, or /usr/lib/os-release as a fallback from
    * the host into the application's /run/host */
-  if (g_file_test ("/etc/os-release", G_FILE_TEST_EXISTS))
+  if (flatpak_exports_stat_in_host (exports, "/etc/os-release", &buf, 0, NULL))
     flatpak_bwrap_add_args (bwrap, "--ro-bind", "/etc/os-release", "/run/host/os-release", NULL);
-  else if (g_file_test ("/usr/lib/os-release", G_FILE_TEST_EXISTS))
+  else if (flatpak_exports_stat_in_host (exports, "/usr/lib/os-release", &buf, 0, NULL))
     flatpak_bwrap_add_args (bwrap, "--ro-bind", "/usr/lib/os-release", "/run/host/os-release", NULL);
 }