[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#864028: stretch-pu: package flatpak/0.8.7-1~deb9u1



Control: retitle 864028 stretch-pu: package flatpak/0.8.7-1~deb9u1

On Sat, 03 Jun 2017 at 12:47:30 +0100, Simon McVittie wrote:
> I would like to update flatpak in stretch along the upstream 0.8.x branch

Updated diff for 0.8.7 attached. This fixes some security issues
(#865413) and would supersede the more minimal security update that
I proposed on that bug.

The diff has been filtered to exclude translations, generated HTML and
Autoconf noise.

    S
diffstat for flatpak-0.8.5 flatpak-0.8.7

 NEWS                                    |   43 ++++++
 common/flatpak-dir.c                    |  210 ++++++++++++++++++++++++++++----
 common/flatpak-run.c                    |  126 ++++++++++++++-----
 configure.ac                            |    4 
 dbus-proxy/flatpak-proxy.c              |    2 
 debian/changelog                        |   49 +++++++
 debian/gbp.conf                         |    2 
 document-portal/xdp-dbus.c              |   20 +--
 document-portal/xdp-dbus.h              |    2 
 gtk-doc.make                            |   53 +++-----
 lib/flatpak-version-macros.h            |    2 
 session-helper/flatpak-session-helper.c |    2 
 tests/package_version.txt               |    2 
 tests/test-run.sh                       |   33 ++++-
 tests/testlibrary.c                     |    4 
 15 files changed, 455 insertions(+), 99 deletions(-)

diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/common/flatpak-dir.c flatpak-0.8.7/common/flatpak-dir.c
--- flatpak-0.8.5/common/flatpak-dir.c	2017-04-03 12:44:28.000000000 +0100
+++ flatpak-0.8.7/common/flatpak-dir.c	2017-06-20 14:17:13.000000000 +0100
@@ -1306,7 +1306,44 @@
                          GCancellable *cancellable,
                          GError      **error)
 {
-  return flatpak_mkdir_p (self->basedir, cancellable, error);
+  /* In the system case, we use default perms */
+  if (!self->user)
+    return flatpak_mkdir_p (self->basedir, cancellable, error);
+  else
+    {
+      /* First make the parent */
+      g_autoptr(GFile) parent = g_file_get_parent (self->basedir);
+      if (!flatpak_mkdir_p (parent, cancellable, error))
+        return FALSE;
+      glnx_fd_close int parent_dfd = -1;
+      if (!glnx_opendirat (AT_FDCWD, flatpak_file_get_path_cached (parent), TRUE,
+                           &parent_dfd, error))
+        return FALSE;
+      g_autofree char *name = g_file_get_basename (self->basedir);
+      /* Use 0700 in the user case to neuter any suid or world-writable
+       * bits that happen to be in content; see
+       * https://github.com/flatpak/flatpak/pull/837
+       */
+      if (mkdirat (parent_dfd, name, 0700) < 0)
+        {
+          if (errno == EEXIST)
+            {
+              /* And fix up any existing installs that had too-wide perms */
+              struct stat stbuf;
+              if (fstatat (parent_dfd, name, &stbuf, 0) < 0)
+                return flatpak_fail (error, "fstatat");
+              if (stbuf.st_mode & S_IXOTH)
+                {
+                  if (fchmodat (parent_dfd, name, 0700, 0) < 0)
+                    return flatpak_fail (error, "fchmodat");
+                }
+            }
+          else
+            return flatpak_fail (error, "mkdirat");
+        }
+
+      return TRUE;
+    }
 }
 
 /* Warning: This is not threadsafe, don't use in libflatpak */
@@ -1724,7 +1761,6 @@
   g_autoptr(GVariant) new_commit = NULL;
   const char *refs_to_fetch[2];
   const char *revs_to_fetch[2];
-  gboolean res;
 
   g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
 
@@ -1764,8 +1800,9 @@
       !ostree_repo_load_commit (self, current_checksum, &old_commit, NULL, error))
     return FALSE;
 
-  res = ostree_repo_pull_with_options (self, remote_name, options,
-                                       progress, cancellable, error);
+  if (!ostree_repo_pull_with_options (self, remote_name, options,
+                                      progress, cancellable, error))
+    return FALSE;
 
   if (old_commit &&
       (flatpak_flags & FLATPAK_PULL_FLAGS_ALLOW_DOWNGRADE) == 0)
@@ -1783,7 +1820,7 @@
         return flatpak_fail (error, "Update is older then current version");
     }
 
-  return res;
+  return TRUE;
 }
 
 static void
@@ -2073,6 +2110,96 @@
   return TRUE;
 }
 
+static gboolean
+ensure_safe_objdir (int dir_fd, const char *rel_path, GError **error)
+{
+  g_auto(GLnxDirFdIterator) iter = {0};
+
+  if (!glnx_dirfd_iterator_init_at (dir_fd, rel_path, TRUE, &iter, error))
+    return FALSE;
+
+  while (TRUE)
+    {
+      struct dirent *dent;
+
+      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&iter, &dent, NULL, error))
+        return FALSE;
+
+      if (dent == NULL)
+        break;
+
+      if (dent->d_type == DT_DIR)
+        {
+          if (!ensure_safe_objdir (iter.fd, dent->d_name, error))
+            return FALSE;
+        }
+      else
+        {
+          struct stat stbuf;
+          if (fstatat (iter.fd, dent->d_name, &stbuf, 0) == 0 &&
+              ((stbuf.st_mode & ~S_IFMT) & ~0775) != 0)
+            return flatpak_fail (error, "Invalid file mode 0%04o", stbuf.st_mode);
+
+          if (g_str_has_suffix (dent->d_name, ".dirmeta"))
+            {
+              glnx_fd_close int dirmeta_fd = -1;
+              g_autoptr(GBytes) data = NULL;
+              g_autoptr(GVariant) variant = NULL;
+              guint32 mode;
+
+              dirmeta_fd = openat (iter.fd, dent->d_name, O_RDONLY | O_CLOEXEC);
+              if (dirmeta_fd < 0)
+                flatpak_fail(error, "Can't read dirmeta");
+
+              data = glnx_fd_readall_bytes (dirmeta_fd, NULL, error);
+              if (!data)
+                return FALSE;
+              variant = g_variant_new_from_bytes (OSTREE_DIRMETA_GVARIANT_FORMAT, data, TRUE);
+              g_variant_ref_sink (variant);
+
+              g_variant_get_child (variant, 2, "u", &mode);
+              mode = GUINT32_FROM_BE (mode);
+              if (((mode & ~S_IFMT) & ~0775) != 0)
+                return flatpak_fail (error, "Invalid directory mode 0%04o", mode);
+            }
+        }
+    }
+
+  return TRUE;
+}
+
+
+static gboolean
+ensure_safe_staging_permissions (OstreeRepo *repo, GError **error)
+{
+  g_auto(GLnxDirFdIterator) tmp_iter = {0};
+
+  /* We don't know which stage dir is in use, so check all */
+
+  if (!glnx_dirfd_iterator_init_at (ostree_repo_get_dfd (repo), "tmp", TRUE, &tmp_iter, error))
+    return FALSE;
+
+  while (TRUE)
+    {
+      struct dirent *dent;
+
+      if (!glnx_dirfd_iterator_next_dent_ensure_dtype (&tmp_iter, &dent, NULL, error))
+        return FALSE;
+
+      if (dent == NULL)
+        break;
+
+      if (dent->d_type == DT_DIR && g_str_has_prefix (dent->d_name, "staging-") &&
+          !ensure_safe_objdir (tmp_iter.fd, dent->d_name, error))
+        {
+          glnx_shutil_rm_rf_at (tmp_iter.fd, dent->d_name, NULL, NULL);
+          return FALSE;
+        }
+    }
+
+  return TRUE;
+}
+
 gboolean
 flatpak_dir_pull (FlatpakDir          *self,
                   const char          *repository,
@@ -2201,6 +2328,9 @@
     goto out;
 
 
+  if (!ensure_safe_staging_permissions (repo, error))
+    goto out;
+
   if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
     goto out;
 
@@ -3113,6 +3243,9 @@
                                       "X-Flatpak-Tags",
                                       (const char * const *) tags, length);
         }
+
+      /* Add a marker so consumers can easily find out that this launches a sandbox */
+      g_key_file_set_string (keyfile, "Desktop Entry", "X-Flatpak", app);
     }
 
   groups = g_key_file_get_groups (keyfile, NULL);
@@ -3408,21 +3541,33 @@
                     GCancellable *cancellable,
                     GError      **error)
 {
-  gboolean ret = FALSE;
+  const char *exported_subdirs[] = {
+    "share/applications",                  "../..",
+    "share/icons",                         "../..",
+    "share/dbus-1/services",               "../../.."
+  };
+  int i;
 
-  if (!flatpak_mkdir_p (destination, cancellable, error))
-    goto out;
+  for (i = 0; i < G_N_ELEMENTS(exported_subdirs); i = i + 2)
+    {
+      /* The fds are closed by this call */
+      g_autoptr(GFile) sub_source = g_file_resolve_relative_path (source, exported_subdirs[i]);
+      g_autoptr(GFile) sub_destination = g_file_resolve_relative_path (destination, exported_subdirs[i]);
+      g_autofree char *sub_symlink_prefix = g_build_filename (exported_subdirs[i+1], symlink_prefix, exported_subdirs[i], NULL);
 
-  /* The fds are closed by this call */
-  if (!export_dir (AT_FDCWD, flatpak_file_get_path_cached (source), symlink_prefix, "",
-                   AT_FDCWD, flatpak_file_get_path_cached (destination),
-                   cancellable, error))
-    goto out;
+      if (!g_file_query_exists (sub_source, cancellable))
+        continue;
 
-  ret = TRUE;
+      if (!flatpak_mkdir_p (sub_destination, cancellable, error))
+        return FALSE;
 
-out:
-  return ret;
+      if (!export_dir (AT_FDCWD, flatpak_file_get_path_cached (sub_source), sub_symlink_prefix, "",
+                       AT_FDCWD, flatpak_file_get_path_cached (sub_destination),
+                       cancellable, error))
+        return FALSE;
+    }
+
+  return TRUE;
 }
 
 gboolean
@@ -7292,13 +7437,17 @@
      flatpak_repo_set_* () family of functions) */
   static const char *const supported_params[] = {
     "xa.title",
-    "xa.default-branch", NULL
+    "xa.default-branch",
+    "xa.gpg-keys",
+    "xa.redirect-url",
+    NULL
   };
 
   g_autoptr(GVariant) summary = NULL;
   g_autoptr(GVariant) extensions = NULL;
   g_autoptr(GPtrArray) updated_params = NULL;
   GVariantIter iter;
+  g_autoptr(GBytes) gpg_keys = NULL;
 
   updated_params = g_ptr_array_new_with_free_func (g_free);
   summary = fetch_remote_summary_file (self, remote, cancellable, error);
@@ -7315,14 +7464,31 @@
 
       while (g_variant_iter_next (&iter, "{sv}", &key, &value_var))
         {
-          /* At the moment, every supported parameter are strings */
-          if (g_strv_contains (supported_params, key) &&
-              g_variant_get_type_string (value_var))
+          /* At the moment, every supported parameter except gpg-keys are strings */
+          if (strcmp (key, "xa.gpg-keys") == 0 &&
+              g_variant_is_of_type (value_var, G_VARIANT_TYPE_BYTESTRING))
+            {
+              const guchar *gpg_data = g_variant_get_data (value_var);
+              gsize gpg_size = g_variant_get_size (value_var);
+              g_autofree gchar *gpg_data_checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA256, gpg_data, gpg_size);
+
+              gpg_keys = g_bytes_new (gpg_data, gpg_size);
+
+              /* We store the hash so that we can detect when things changed or not
+                 instead of re-importing the key over-and-over */
+              g_ptr_array_add (updated_params, g_strdup ("xa.gpg-keys-hash"));
+              g_ptr_array_add (updated_params, g_steal_pointer (&gpg_data_checksum));
+            }
+          else if (g_strv_contains (supported_params, key) &&
+                   g_variant_is_of_type (value_var, G_VARIANT_TYPE_STRING))
             {
               const char *value = g_variant_get_string(value_var, NULL);
               if (value != NULL && *value != 0)
                 {
-                  g_ptr_array_add (updated_params, g_strdup (key));
+                  if (strcmp (key, "xa.redirect-url") == 0)
+                    g_ptr_array_add (updated_params, g_strdup ("url"));
+                  else
+                    g_ptr_array_add (updated_params, g_strdup (key));
                   g_ptr_array_add (updated_params, g_strdup (value));
                 }
             }
@@ -7389,7 +7555,7 @@
       }
 
     /* Update the local remote configuration with the updated info. */
-    if (!flatpak_dir_modify_remote (self, remote, config, NULL, cancellable, error))
+    if (!flatpak_dir_modify_remote (self, remote, config, gpg_keys, cancellable, error))
       return FALSE;
   }
 
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/common/flatpak-run.c flatpak-0.8.7/common/flatpak-run.c
--- flatpak-0.8.5/common/flatpak-run.c	2017-04-03 12:23:30.000000000 +0100
+++ flatpak-0.8.7/common/flatpak-run.c	2017-06-20 14:17:13.000000000 +0100
@@ -1969,8 +1969,16 @@
 flatpak_run_add_wayland_args (GPtrArray *argv_array,
                               char    ***envp_p)
 {
-  g_autofree char *wayland_socket = g_build_filename (g_get_user_runtime_dir (), "wayland-0", NULL);
-  g_autofree char *sandbox_wayland_socket = g_strdup_printf ("/run/user/%d/wayland-0", getuid ());
+  const char *wayland_display;
+  g_autofree char *wayland_socket = NULL;
+  g_autofree char *sandbox_wayland_socket = NULL;
+
+  wayland_display = g_getenv ("WAYLAND_DISPLAY");
+  if (!wayland_display)
+    wayland_display = "wayland-0";
+
+  wayland_socket = g_build_filename (g_get_user_runtime_dir (), wayland_display, NULL);
+  sandbox_wayland_socket = g_strdup_printf ("/run/user/%d/%s", getuid (), wayland_display);
 
   if (g_file_test (wayland_socket, G_FILE_TEST_EXISTS))
     {
@@ -2423,6 +2431,18 @@
   g_hash_table_insert (hash_table, ep->path, ep);
 }
 
+static gboolean
+never_export_as_symlink (const char *path)
+{
+  /* Don't export /tmp as a symlink even if it is on the host, because
+     that will fail with the pre-existing directory we created for /tmp,
+     and anyway, it being a symlink is not useful in the sandbox */
+  if (strcmp (path, "/tmp") == 0)
+    return TRUE;
+
+  return FALSE;
+}
+
 /* We use the level to make sure we get the ordering somewhat right.
  * For instance if /symlink -> /z_dir is exported, then we want to create
  * /z_dir before /symlink, because otherwise an export like /symlink/foo
@@ -2472,7 +2492,7 @@
       if (old_ep != NULL)
         old_mode = old_ep->mode;
 
-      if (S_ISLNK (st.st_mode))
+      if (S_ISLNK (st.st_mode) && !never_export_as_symlink (path))
         {
           g_autofree char *resolved = flatpak_resolve_link (path, NULL);
 
@@ -2747,11 +2767,11 @@
             "--dir", g_get_home_dir (),
             NULL);
 
-  /* Special case subdirectories of the cache, config and data xdg dirs.
-   * If these are accessible explicilty, in a read-write fashion, then
-   * we bind-mount these in the app-id dir. This allows applications to
-   * explicitly opt out of keeping some config/cache/data in the
-   * app-specific directory.
+  /* Special case subdirectories of the cache, config and data xdg
+   * dirs.  If these are accessible explicilty, then we bind-mount
+   * these in the app-id dir. This allows applications to explicitly
+   * opt out of keeping some config/cache/data in the app-specific
+   * directory.
    */
   if (app_id_dir)
     {
@@ -2766,17 +2786,18 @@
           xdg_path = get_xdg_dir_from_string (filesystem, &rest, &where);
 
           if (xdg_path != NULL && *rest != 0 &&
-              mode >= FLATPAK_FILESYSTEM_MODE_READ_WRITE)
+              mode >= FLATPAK_FILESYSTEM_MODE_READ_ONLY)
             {
               g_autoptr(GFile) app_version = g_file_get_child (app_id_dir, where);
               g_autoptr(GFile) app_version_subdir = g_file_resolve_relative_path (app_version, rest);
 
-              if (g_file_test (xdg_path, G_FILE_TEST_IS_DIR))
+              if (g_file_test (xdg_path, G_FILE_TEST_IS_DIR) ||
+                  g_file_test (xdg_path, G_FILE_TEST_IS_REGULAR))
                 {
                   g_autofree char *xdg_path_in_app = g_file_get_path (app_version_subdir);
-                  g_mkdir_with_parents (xdg_path_in_app, 0755);
                   add_args (argv_array,
-                            "--bind", xdg_path, xdg_path_in_app,
+                            mode == FLATPAK_FILESYSTEM_MODE_READ_ONLY ? "--ro-bind" : "--bind",
+                            xdg_path, xdg_path_in_app,
                             NULL);
                 }
             }
@@ -2872,6 +2893,7 @@
   {"XDG_CONFIG_DIRS", "/app/etc/xdg:/etc/xdg"},
   {"XDG_DATA_DIRS", "/app/share:/usr/share"},
   {"SHELL", "/bin/sh"},
+  {"TMPDIR", NULL}, /* Unset TMPDIR as it may not exist in the sandbox */
 };
 
 static const struct {const char *env;
@@ -2926,12 +2948,18 @@
   env_array = g_ptr_array_new_with_free_func (g_free);
 
   for (i = 0; i < G_N_ELEMENTS (default_exports); i++)
-    g_ptr_array_add (env_array, g_strdup_printf ("%s=%s", default_exports[i].env, default_exports[i].val));
+    {
+      if (default_exports[i].val)
+        g_ptr_array_add (env_array, g_strdup_printf ("%s=%s", default_exports[i].env, default_exports[i].val));
+    }
 
   if (devel)
     {
       for (i = 0; i < G_N_ELEMENTS(devel_exports); i++)
-        g_ptr_array_add (env_array, g_strdup_printf ("%s=%s", devel_exports[i].env, devel_exports[i].val));
+        {
+          if (devel_exports[i].val)
+            g_ptr_array_add (env_array, g_strdup_printf ("%s=%s", devel_exports[i].env, devel_exports[i].val));
+        }
     }
 
   for (i = 0; i < G_N_ELEMENTS (copy); i++)
@@ -2961,7 +2989,14 @@
   int i;
 
   for (i = 0; i < G_N_ELEMENTS (default_exports); i++)
-    envp = g_environ_setenv (envp, default_exports[i].env, default_exports[i].val, TRUE);
+    {
+      const char *value = default_exports[i].val;
+
+      if (value)
+        envp = g_environ_setenv (envp, default_exports[i].env, value, TRUE);
+      else
+        envp = g_environ_unsetenv (envp, default_exports[i].env);
+    }
 
   return envp;
 }
@@ -3225,10 +3260,11 @@
                                GError        **error)
 {
   g_autofree char *tmp_path = NULL;
-  int fd;
+  int fd, fd2;
   g_autoptr(GKeyFile) keyfile = NULL;
   g_autofree char *runtime_path = NULL;
   g_autofree char *fd_str = NULL;
+  g_autofree char *fd2_str = NULL;
   g_autofree char *old_dest = g_strdup_printf ("/run/user/%d/flatpak-info", getuid ());
   const char *group;
 
@@ -3276,6 +3312,17 @@
   if (!g_key_file_save_to_file (keyfile, tmp_path, error))
     return FALSE;
 
+  /* We want to create a file on /.flatpak-info that the app cannot modify, which
+     we do by creating a read-only bind mount. This way one can openat()
+     /proc/$pid/root, and if that succeeds use openat via that to find the
+     unfakable .flatpak-info file. However, there is a tiny race in that if
+     you manage to open /proc/$pid/root, but then the pid dies, then
+     every mount but the root is unmounted in the namespace, so the
+     .flatpak-info will be empty. We fix this by first creating a real file
+     with the real info in, then bind-mounting on top of that, the same info.
+     This way even if the bind-mount is unmounted we can find the real data.
+  */
+
   fd = open (tmp_path, O_RDONLY);
   if (fd == -1)
     {
@@ -3285,14 +3332,29 @@
       return FALSE;
     }
 
+  fd2 = open (tmp_path, O_RDONLY);
+  if (fd2 == -1)
+    {
+      close (fd);
+      int errsv = errno;
+      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+                   _("Failed to open temp file: %s"), g_strerror (errsv));
+      return FALSE;
+    }
+
   unlink (tmp_path);
 
   fd_str = g_strdup_printf ("%d", fd);
+  fd2_str = g_strdup_printf ("%d", fd2);
   if (fd_array)
-    g_array_append_val (fd_array, fd);
+    {
+      g_array_append_val (fd_array, fd);
+      g_array_append_val (fd_array, fd2);
+    }
 
   add_args (argv_array,
-            "--ro-bind-data", fd_str, "/.flatpak-info",
+            "--file", fd_str, "/.flatpak-info",
+            "--ro-bind-data", fd2_str, "/.flatpak-info",
             "--symlink", "../../../.flatpak-info", old_dest,
             NULL);
 
@@ -3326,12 +3388,10 @@
     {
       add_args (argv_array,
                 "--ro-bind", monitor_path, "/run/host/monitor",
-                NULL);
-      add_args (argv_array,
                 "--symlink", "/run/host/monitor/localtime", "/etc/localtime",
-                NULL);
-      add_args (argv_array,
                 "--symlink", "/run/host/monitor/resolv.conf", "/etc/resolv.conf",
+                "--symlink", "/run/host/monitor/host.conf", "/etc/host.conf",
+                "--symlink", "/run/host/monitor/hosts", "/etc/hosts",
                 NULL);
     }
   else
@@ -3362,11 +3422,17 @@
         }
 
       if (g_file_test ("/etc/resolv.conf", G_FILE_TEST_EXISTS))
-        {
-          add_args (argv_array,
-                    "--ro-bind", "/etc/resolv.conf", "/etc/resolv.conf",
-                    NULL);
-        }
+        add_args (argv_array,
+                  "--ro-bind", "/etc/resolv.conf", "/etc/resolv.conf",
+                  NULL);
+      if (g_file_test ("/etc/host.conf", G_FILE_TEST_EXISTS))
+        add_args (argv_array,
+                  "--ro-bind", "/etc/host.conf", "/etc/host.conf",
+                  NULL);
+      if (g_file_test ("/etc/hosts", G_FILE_TEST_EXISTS))
+        add_args (argv_array,
+                  "--ro-bind", "/etc/hosts", "/etc/hosts",
+                  NULL);
     }
 }
 
@@ -3521,7 +3587,9 @@
   g_ptr_array_add (bwrap_args, g_strdup (proxy_socket_dir));
   g_ptr_array_add (bwrap_args, g_strdup (proxy_socket_dir));
 
-  g_ptr_array_add (bwrap_args, g_strdup ("--ro-bind-data"));
+  /* This is a file rather than a bind mount, because it will then
+     not be unmounted from the namespace when the namespace dies. */
+  g_ptr_array_add (bwrap_args, g_strdup ("--file"));
   g_ptr_array_add (bwrap_args, g_strdup_printf ("%d", app_info_fd));
   g_ptr_array_add (bwrap_args, g_strdup ("/.flatpak-info"));
 
@@ -3986,6 +4054,8 @@
               strcmp (dent->d_name, "group") == 0 ||
               strcmp (dent->d_name, "machine-id") == 0 ||
               strcmp (dent->d_name, "resolv.conf") == 0 ||
+              strcmp (dent->d_name, "host.conf") == 0 ||
+              strcmp (dent->d_name, "hosts") == 0 ||
               strcmp (dent->d_name, "localtime") == 0)
             continue;
 
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/configure.ac flatpak-0.8.7/configure.ac
--- flatpak-0.8.5/configure.ac	2017-04-03 13:07:27.000000000 +0100
+++ flatpak-0.8.7/configure.ac	2017-06-20 14:24:11.000000000 +0100
@@ -15,8 +15,8 @@
 
 m4_define([flatpak_major_version], [0])
 m4_define([flatpak_minor_version], [8])
-m4_define([flatpak_micro_version], [5])
-m4_define([flatpak_interface_age], [5])
+m4_define([flatpak_micro_version], [7])
+m4_define([flatpak_interface_age], [7])
 m4_define([flatpak_binary_age],
           [m4_eval(10000 * flatpak_major_version + 100 * flatpak_minor_version + flatpak_micro_version)])
 m4_define([flatpak_version],
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/dbus-proxy/flatpak-proxy.c flatpak-0.8.7/dbus-proxy/flatpak-proxy.c
--- flatpak-0.8.5/dbus-proxy/flatpak-proxy.c	2017-04-03 12:44:16.000000000 +0100
+++ flatpak-0.8.7/dbus-proxy/flatpak-proxy.c	2017-06-20 14:17:13.000000000 +0100
@@ -1304,7 +1304,7 @@
   g_dbus_message_set_message_type (reply, G_DBUS_MESSAGE_TYPE_METHOD_RETURN);
   g_dbus_message_set_flags (reply, G_DBUS_MESSAGE_FLAGS_NO_REPLY_EXPECTED);
   g_dbus_message_set_reply_serial (reply, header->serial - client->serial_offset);
-  g_dbus_message_set_body (reply, g_variant_new_boolean (val));
+  g_dbus_message_set_body (reply, g_variant_new ("(b)", val));
 
   return reply;
 }
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/debian/changelog flatpak-0.8.7/debian/changelog
--- flatpak-0.8.5/debian/changelog	2017-04-24 12:59:09.000000000 +0100
+++ flatpak-0.8.7/debian/changelog	2017-06-21 12:36:34.000000000 +0100
@@ -1,3 +1,52 @@
+flatpak (0.8.7-1~deb9u1) stretch; urgency=medium
+
+  * Rebuild for stretch
+  * debian/gbp.conf: Switch branch to debian/stretch
+
+ -- Simon McVittie <smcv@debian.org>  Wed, 21 Jun 2017 12:36:34 +0100
+
+flatpak (0.8.7-1) unstable; urgency=high
+
+  * New upstream stable release
+    - Security: prevent deploying files with inappropriate permissions
+      (world-writable, setuid, etc.) (Closes: #865413)
+    - Security: make ~/.local/share/flatpak private to user to defend
+      against app vendors that might have released files with
+      inappropriate permissions in the past
+    - If an error occurs during pull, do not double-set an error,
+      which is considered to be invalid
+    - Increase some arbitrary timeouts in a test to make it more
+      reliable
+
+ -- Simon McVittie <smcv@debian.org>  Wed, 21 Jun 2017 09:50:09 +0100
+
+flatpak (0.8.6-1) unstable; urgency=medium
+
+  * New upstream release
+    - Fix the return value type for filtered NameHasOwner() D-Bus calls
+      (upstream issue 817)
+    - Security hardening: Only export .desktop files, D-Bus session
+      services and icons, but not other files that an app might try to
+      export
+    - Allow remote repositories to specify a new GPG key (for key rollover)
+      or a new URL (for location migration) in their signed metadata
+    - Let KDE apps bind-mount ~/.config/kdeglobals into the sandbox:
+      + Allow bind-mounting regular files in the XDG cache, config or data
+        directories, not just directories
+      + Allow bind-mounting files in the XDG directories read-only, not
+        just read/write
+    - Close a race condition in app identification by portals
+    - Cope with a non-default WAYLAND_DISPLAY
+    - Cope with /tmp on the host being a symlink
+    - Clear TMPDIR in the sandbox, fixing sandboxed Spotify
+    - Add X-Flatpak=$app_id to exported .desktop files
+      so that the desktop environment can identify what will be launched
+    - Make the host's /etc/hosts and /etc/host.conf available in the sandbox,
+      fixing sandboxed Spotify
+    - Update Hungarian translation
+
+ -- Simon McVittie <smcv@debian.org>  Mon, 05 Jun 2017 21:30:06 +0100
+
 flatpak (0.8.5-2) unstable; urgency=medium
 
   * flatpak Recommends xdg-desktop-portal-gtk | xdg-desktop-portal-backend,
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/debian/gbp.conf flatpak-0.8.7/debian/gbp.conf
--- flatpak-0.8.5/debian/gbp.conf	2017-04-24 12:59:09.000000000 +0100
+++ flatpak-0.8.7/debian/gbp.conf	2017-06-21 12:36:34.000000000 +0100
@@ -1,7 +1,7 @@
 [DEFAULT]
 pristine-tar = True
 compression = xz
-debian-branch = debian/master
+debian-branch = debian/stretch
 upstream-branch = upstream/0.8.x
 patch-numbers = False
 upstream-vcs-tag = %(version)s
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/document-portal/xdp-dbus.c flatpak-0.8.7/document-portal/xdp-dbus.c
--- flatpak-0.8.5/document-portal/xdp-dbus.c	2016-10-28 10:02:39.000000000 +0100
+++ flatpak-0.8.7/document-portal/xdp-dbus.c	2017-06-20 14:24:38.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- * Generated by gdbus-codegen 2.51.0. DO NOT EDIT.
+ * Generated by gdbus-codegen 2.53.2. DO NOT EDIT.
  *
  * The license of this code is the same as for the source it was derived from.
  */
@@ -720,7 +720,7 @@
  */
 
 typedef XdpDbusDocumentsIface XdpDbusDocumentsInterface;
-G_DEFINE_INTERFACE (XdpDbusDocuments, xdp_dbus_documents, G_TYPE_OBJECT);
+G_DEFINE_INTERFACE (XdpDbusDocuments, xdp_dbus_documents, G_TYPE_OBJECT)
 
 static void
 xdp_dbus_documents_default_init (XdpDbusDocumentsIface *iface)
@@ -2123,11 +2123,11 @@
 #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
 G_DEFINE_TYPE_WITH_CODE (XdpDbusDocumentsProxy, xdp_dbus_documents_proxy, G_TYPE_DBUS_PROXY,
                          G_ADD_PRIVATE (XdpDbusDocumentsProxy)
-                         G_IMPLEMENT_INTERFACE (XDP_DBUS_TYPE_DOCUMENTS, xdp_dbus_documents_proxy_iface_init));
+                         G_IMPLEMENT_INTERFACE (XDP_DBUS_TYPE_DOCUMENTS, xdp_dbus_documents_proxy_iface_init))
 
 #else
 G_DEFINE_TYPE_WITH_CODE (XdpDbusDocumentsProxy, xdp_dbus_documents_proxy, G_TYPE_DBUS_PROXY,
-                         G_IMPLEMENT_INTERFACE (XDP_DBUS_TYPE_DOCUMENTS, xdp_dbus_documents_proxy_iface_init));
+                         G_IMPLEMENT_INTERFACE (XDP_DBUS_TYPE_DOCUMENTS, xdp_dbus_documents_proxy_iface_init))
 
 #endif
 static void
@@ -2164,8 +2164,8 @@
   GVariantIter iter;
   GVariant *child;
   GValue *paramv;
-  guint num_params;
-  guint n;
+  gsize num_params;
+  gsize n;
   guint signal_id;
   info = (_ExtendedGDBusSignalInfo *) g_dbus_interface_info_lookup_signal ((GDBusInterfaceInfo *) &_xdp_dbus_documents_interface_info.parent_struct, signal_name);
   if (info == NULL)
@@ -2481,9 +2481,9 @@
   GVariantIter iter;
   GVariant *child;
   GValue *paramv;
-  guint num_params;
+  gsize num_params;
   guint num_extra;
-  guint n;
+  gsize n;
   guint signal_id;
   GValue return_value = G_VALUE_INIT;
   info = (_ExtendedGDBusMethodInfo *) g_dbus_method_invocation_get_method_info (invocation);
@@ -2657,11 +2657,11 @@
 #if GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_38
 G_DEFINE_TYPE_WITH_CODE (XdpDbusDocumentsSkeleton, xdp_dbus_documents_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
                          G_ADD_PRIVATE (XdpDbusDocumentsSkeleton)
-                         G_IMPLEMENT_INTERFACE (XDP_DBUS_TYPE_DOCUMENTS, xdp_dbus_documents_skeleton_iface_init));
+                         G_IMPLEMENT_INTERFACE (XDP_DBUS_TYPE_DOCUMENTS, xdp_dbus_documents_skeleton_iface_init))
 
 #else
 G_DEFINE_TYPE_WITH_CODE (XdpDbusDocumentsSkeleton, xdp_dbus_documents_skeleton, G_TYPE_DBUS_INTERFACE_SKELETON,
-                         G_IMPLEMENT_INTERFACE (XDP_DBUS_TYPE_DOCUMENTS, xdp_dbus_documents_skeleton_iface_init));
+                         G_IMPLEMENT_INTERFACE (XDP_DBUS_TYPE_DOCUMENTS, xdp_dbus_documents_skeleton_iface_init))
 
 #endif
 static void
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/document-portal/xdp-dbus.h flatpak-0.8.7/document-portal/xdp-dbus.h
--- flatpak-0.8.5/document-portal/xdp-dbus.h	2016-10-28 10:02:39.000000000 +0100
+++ flatpak-0.8.7/document-portal/xdp-dbus.h	2017-06-20 14:24:38.000000000 +0100
@@ -1,5 +1,5 @@
 /*
- * Generated by gdbus-codegen 2.51.0. DO NOT EDIT.
+ * Generated by gdbus-codegen 2.53.2. DO NOT EDIT.
  *
  * The license of this code is the same as for the source it was derived from.
  */
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/gtk-doc.make flatpak-0.8.7/gtk-doc.make
--- flatpak-0.8.5/gtk-doc.make	2016-10-18 12:23:30.000000000 +0100
+++ flatpak-0.8.7/gtk-doc.make	2017-06-15 09:54:46.000000000 +0100
@@ -87,19 +87,18 @@
 
 setup-build.stamp:
 	-$(GTK_DOC_V_SETUP)if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \
-	    files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \
-	    if test "x$$files" != "x" ; then \
-	        for file in $$files ; do \
-	            destdir=`dirname $(abs_builddir)/$$file`; \
-	            test -d "$$destdir" || mkdir -p "$$destdir"; \
-	            test -f $(abs_srcdir)/$$file && \
-	                cp -pf $(abs_srcdir)/$$file $(abs_builddir)/$$file || true; \
-	        done; \
-	    fi; \
+	  files=`echo $(SETUP_FILES) $(DOC_MODULE).types`; \
+	  if test "x$$files" != "x" ; then \
+	    for file in $$files ; do \
+	      destdir=`dirname $(abs_builddir)/$$file`; \
+	      test -d "$$destdir" || mkdir -p "$$destdir"; \
+	      test -f $(abs_srcdir)/$$file && \
+	        cp -pf $(abs_srcdir)/$$file $(abs_builddir)/$$file || true; \
+	    done; \
+	  fi; \
 	fi
 	$(AM_V_at)touch setup-build.stamp
 
-
 #### scan ####
 
 GTK_DOC_V_SCAN=$(GTK_DOC_V_SCAN_$(V))
@@ -113,23 +112,23 @@
 scan-build.stamp: setup-build.stamp $(HFILE_GLOB) $(CFILE_GLOB)
 	$(GTK_DOC_V_SCAN)_source_dir='' ; \
 	for i in $(DOC_SOURCE_DIR) ; do \
-	    _source_dir="$${_source_dir} --source-dir=$$i" ; \
+	  _source_dir="$${_source_dir} --source-dir=$$i" ; \
 	done ; \
 	gtkdoc-scan --module=$(DOC_MODULE) --ignore-headers="$(IGNORE_HFILES)" $${_source_dir} $(SCAN_OPTIONS) $(EXTRA_HFILES)
 	$(GTK_DOC_V_INTROSPECT)if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \
-	    scanobj_options=""; \
-	    gtkdoc-scangobj 2>&1 --help | grep  >/dev/null "\-\-verbose"; \
-	    if test "$$?" = "0"; then \
-	        if test "x$(V)" = "x1"; then \
-	            scanobj_options="--verbose"; \
-	        fi; \
+	  scanobj_options=""; \
+	  gtkdoc-scangobj 2>&1 --help | grep  >/dev/null "\-\-verbose"; \
+	  if test "$$?" = "0"; then \
+	    if test "x$(V)" = "x1"; then \
+	      scanobj_options="--verbose"; \
 	    fi; \
-	    CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" \
-	    gtkdoc-scangobj $(SCANGOBJ_OPTIONS) $$scanobj_options --module=$(DOC_MODULE); \
+	  fi; \
+	  CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" \
+	  gtkdoc-scangobj $(SCANGOBJ_OPTIONS) $$scanobj_options --module=$(DOC_MODULE); \
 	else \
-	    for i in $(SCANOBJ_FILES) ; do \
-	        test -f $$i || touch $$i ; \
-	    done \
+	  for i in $(SCANOBJ_FILES) ; do \
+	    test -f $$i || touch $$i ; \
+	  done \
 	fi
 	$(AM_V_at)touch scan-build.stamp
 
@@ -145,7 +144,7 @@
 sgml-build.stamp: setup-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(HFILE_GLOB) $(CFILE_GLOB) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt $(expand_content_files) xml/gtkdocentities.ent
 	$(GTK_DOC_V_XML)_source_dir='' ; \
 	for i in $(DOC_SOURCE_DIR) ; do \
-	    _source_dir="$${_source_dir} --source-dir=$$i" ; \
+	  _source_dir="$${_source_dir} --source-dir=$$i" ; \
 	done ; \
 	gtkdoc-mkdb --module=$(DOC_MODULE) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $${_source_dir} $(MKDB_OPTIONS)
 	$(AM_V_at)touch sgml-build.stamp
@@ -190,12 +189,8 @@
 	cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
 	-@test "x$(HTML_IMAGES)" = "x" || \
 	for file in $(HTML_IMAGES) ; do \
-	  if test -f $(abs_srcdir)/$$file ; then \
-	    cp $(abs_srcdir)/$$file $(abs_builddir)/html; \
-	  fi; \
-	  if test -f $(abs_builddir)/$$file ; then \
-	    cp $(abs_builddir)/$$file $(abs_builddir)/html; \
-	  fi; \
+	  test -f $(abs_srcdir)/$$file && cp $(abs_srcdir)/$$file $(abs_builddir)/html; \
+	  test -f $(abs_builddir)/$$file && cp $(abs_builddir)/$$file $(abs_builddir)/html; \
 	done;
 	$(GTK_DOC_V_XREF)gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
 	$(AM_V_at)touch html-build.stamp
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/lib/flatpak-version-macros.h flatpak-0.8.7/lib/flatpak-version-macros.h
--- flatpak-0.8.5/lib/flatpak-version-macros.h	2017-04-03 13:07:52.000000000 +0100
+++ flatpak-0.8.7/lib/flatpak-version-macros.h	2017-06-20 14:24:38.000000000 +0100
@@ -27,7 +27,7 @@
 
 #define FLATPAK_MAJOR_VERSION (0)
 #define FLATPAK_MINOR_VERSION (8)
-#define FLATPAK_MICRO_VERSION (5)
+#define FLATPAK_MICRO_VERSION (7)
 
 #define FLATPAK_CHECK_VERSION(major,minor,micro)        \
     (FLATPAK_MAJOR_VERSION > (major) || \
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/NEWS flatpak-0.8.7/NEWS
--- flatpak-0.8.5/NEWS	2017-04-03 13:06:41.000000000 +0100
+++ flatpak-0.8.7/NEWS	2017-06-20 14:23:42.000000000 +0100
@@ -1,3 +1,46 @@
+Major changes in 0.8.7
+======================
+
+This is a minor security update, matching the behaviour on master
+where we avoid ever creating setuid files or world-writable
+directories. However, the fix is more localized and does not
+require a new ostree.
+
+Changes:
+ * After pulling from a remote, always verify that the staged
+   new files and directories have safe permissions.
+ * Ensure ~/.local/share/flatpak is not readable to other users, to
+   avoid anyone ever seeing possibly world-writeable directories
+   therein.
+ * Fix double-setting a error in case of errors when pulling
+ * Fix timeout in testcase
+
+Major changes in 0.8.6
+======================
+
+ * TMPDIR is now unset in the sandbox, if set on the
+   host. Each sandbox has a personal /tmp that is used.
+ * Flatpak run now works if /tmp is a symlink on the
+   host.
+ * /etc/hosts and /etc/hosts.conf from the host are now exposed
+   in the sandbox in addition to /etc/resolv.conf.
+ * flatpak now stores the app id in the X-Flatpak key when exporting a
+   desktop file.
+ * Exports are now whitelisted, and the only thing you can
+   export are:
+     desktop files, icons, dbus services
+   This is somewhat different from the 0.9.x series, where als
+   mime definitions, and gnome-shell search providers are allowed.
+ * Fixed minor race condition in portal application identification.
+ * Support WAYLAND_DISPLAY environment var.
+ * dbus-portal: Fix handling of NameHasOwner
+ * run: Allow regular files for --filesystem=xdg-config/path
+ * run: Allow --filesystem=xdg-config/subdir:ro (previously
+   it needed to be writable).
+ * Support for updating to new gpg keys and url when using
+   flatpak remote-modify --update-metadata. This is a manual
+   operation in 0.8.x but is automatic in the 0.9.x series.
+
 Major changes in 0.8.5
 ======================
 
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/session-helper/flatpak-session-helper.c flatpak-0.8.7/session-helper/flatpak-session-helper.c
--- flatpak-0.8.5/session-helper/flatpak-session-helper.c	2017-03-30 08:17:39.000000000 +0100
+++ flatpak-0.8.7/session-helper/flatpak-session-helper.c	2017-06-20 14:17:13.000000000 +0100
@@ -529,6 +529,8 @@
     }
 
   setup_file_monitor ("/etc/resolv.conf");
+  setup_file_monitor ("/etc/host.conf");
+  setup_file_monitor ("/etc/hosts");
   setup_file_monitor ("/etc/localtime");
 
   flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/tests/package_version.txt flatpak-0.8.7/tests/package_version.txt
--- flatpak-0.8.5/tests/package_version.txt	2017-04-03 13:08:08.000000000 +0100
+++ flatpak-0.8.7/tests/package_version.txt	2017-06-20 14:25:26.000000000 +0100
@@ -1 +1 @@
-0.8.5
+0.8.7
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/tests/testlibrary.c flatpak-0.8.7/tests/testlibrary.c
--- flatpak-0.8.5/tests/testlibrary.c	2017-04-03 12:31:25.000000000 +0100
+++ flatpak-0.8.7/tests/testlibrary.c	2017-06-20 14:17:13.000000000 +0100
@@ -397,7 +397,7 @@
   g_assert (FLATPAK_IS_INSTALLED_REF (ref));
   g_assert_cmpint (progress_count, >, 0);
 
-  quit_id = g_timeout_add (500, quit, NULL);
+  quit_id = g_timeout_add (1000, quit, loop);
   g_main_loop_run (loop);
   g_source_remove (quit_id);
 
@@ -442,7 +442,7 @@
   g_assert (FLATPAK_IS_INSTALLED_REF (ref));
   g_assert_cmpint (progress_count, >, 0);
 
-  quit_id = g_timeout_add (500, quit, loop);
+  quit_id = g_timeout_add (1000, quit, loop);
   g_main_loop_run (loop);
   g_source_remove (quit_id);
 
diff -Nru --exclude aclocal.m4 --exclude configure --exclude config.guess --exclude config.sub --exclude po --exclude html --exclude Makefile.in flatpak-0.8.5/tests/test-run.sh flatpak-0.8.7/tests/test-run.sh
--- flatpak-0.8.5/tests/test-run.sh	2017-04-03 12:44:28.000000000 +0100
+++ flatpak-0.8.7/tests/test-run.sh	2017-06-20 14:17:13.000000000 +0100
@@ -24,7 +24,7 @@
 skip_without_bwrap
 skip_without_user_xattrs
 
-echo "1..10"
+echo "1..12"
 
 setup_repo
 install_repo
@@ -338,3 +338,34 @@
 ${FLATPAK} ${U} update org.test.OldVersion
 
 echo "ok version checks"
+
+rm -rf app
+flatpak build-init app org.test.Writable org.test.Platform org.test.Platform
+mkdir -p app/files/a-dir
+chmod a+rwx app/files/a-dir
+flatpak build-finish --command=hello.sh app
+ostree --repo=repos/test commit  ${FL_GPGARGS} --branch=app/org.test.Writable/$ARCH/master app
+update_repo
+
+if ${FLATPAK} ${U} install test-repo org.test.Writable &> err.txt; then
+    assert_not_reached "Should not be able to install with world-writable directory"
+fi
+assert_file_has_content err.txt [Ii]nvalid
+
+echo "ok no world writable dir"
+
+rm -rf app
+flatpak build-init app org.test.Setuid org.test.Platform org.test.Platform
+mkdir -p app/files/
+touch app/files/exe
+chmod u+s app/files/exe
+flatpak build-finish --command=hello.sh app
+ostree --repo=repos/test commit  ${FL_GPGARGS} --branch=app/org.test.Setuid/$ARCH/master app
+update_repo
+
+if ${FLATPAK} ${U} install test-repo org.test.Setuid &> err2.txt; then
+    assert_not_reached "Should not be able to install with setuid file"
+fi
+assert_file_has_content err2.txt [Ii]nvalid
+
+echo "ok no setuid"

Reply to: