On Wed, 21 Jun 2017 at 09:46:21 +0100, Simon McVittie wrote:
> Security team: do you want a backport/DSA for stretch-security, or do
> you consider the mitigations to be sufficient to fix this through
> a stable update instead? I am hoping to get 0.8.7 into stretch r1 as a
> stable update, but 0.8.6 contains unrelated bug fixes that I realise
> you won't necessarily want in stretch-security (proposed-update tracked
> at <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=864028>).

Here is a proposed minimal backport for stretch in case you want one.
I have source and binaries for this ready for upload. Does the security
archive still want source packages built with debuild -sa, and do you
accept source-only uploads for stretch-security?

Thanks,
    S
diffstat for flatpak-0.8.5 flatpak-0.8.5

 changelog                                                               |   14 
 patches/Ensure-we-don-t-install-world-writable-dirs-or-setuid-fil.patch |  178 ++++++++++
 patches/dir-Ensure-.local-share-flatpak-is-0700.patch                   |   79 ++++
 patches/series                                                          |    2 
 4 files changed, 273 insertions(+)

diff -Nru flatpak-0.8.5/debian/changelog flatpak-0.8.5/debian/changelog
--- flatpak-0.8.5/debian/changelog	2017-04-24 12:59:09.000000000 +0100
+++ flatpak-0.8.5/debian/changelog	2017-06-21 12:05:49.000000000 +0100
@@ -1,3 +1,17 @@
+flatpak (0.8.5-2+deb9u1) stretch-security; urgency=high
+
+  * d/p/Ensure-we-don-t-install-world-writable-dirs-or-setuid-fil.patch:
+    Patch from upstream stable release 0.8.7.
+    Prevent deploying files with inappropriate permissions
+    (world-writable, setuid, etc.) (Closes: #865413)
+  * d/p/dir-Ensure-.local-share-flatpak-is-0700.patch:
+    Patch from upstream stable release 0.8.7.
+    Make ~/.local/share/flatpak private to user to defend against app
+    vendors that might have released files with inappropriate permissions
+    in the past
+
+ -- Simon McVittie <s...@debian.org>  Wed, 21 Jun 2017 12:05:49 +0100
+
 flatpak (0.8.5-2) unstable; urgency=medium
 
   * flatpak Recommends xdg-desktop-portal-gtk | xdg-desktop-portal-backend,
diff -Nru flatpak-0.8.5/debian/patches/dir-Ensure-.local-share-flatpak-is-0700.patch flatpak-0.8.5/debian/patches/dir-Ensure-.local-share-flatpak-is-0700.patch
--- flatpak-0.8.5/debian/patches/dir-Ensure-.local-share-flatpak-is-0700.patch	1970-01-01 01:00:00.000000000 +0100
+++ flatpak-0.8.5/debian/patches/dir-Ensure-.local-share-flatpak-is-0700.patch	2017-06-21 12:05:49.000000000 +0100
@@ -0,0 +1,79 @@
+From: Colin Walters <walt...@verbum.org>
+Date: Thu, 8 Jun 2017 10:24:48 -0400
+Subject: dir: Ensure ~/.local/share/flatpak is 0700
+
+This goes into a big old topic about Unix homedir permissions; it's not uncommon
+for general purpose OS vendors to have homedirs be 0755. In that case,
+applications need to ensure confidentiality for data requiring it (classically
+e.g. `~/.ssh`) by making the dirs `0700`.
+
+While most of the data in the flatpak per-user dir probably isn't confidential
+(debatably) we have a different issue; if container content includes suid or
+world-writable files/dirs, then having that data accessible to other users
+is obviously problematic.
+
+We're going to fix flatpak/ostree to not create files with those modes
+to begin with, but this simple fix closes off the attack route for
+the per-user directory.
+
+A different fix will be necessary for the system-wide repo.
+
+See: https://github.com/flatpak/flatpak/pull/837
+(cherry picked from commit daf36ba2afab407c488c456952eecba16f79020e)
+
+Origin: upstream, 0.8.7, commit:02a299f5c0321ae807c128812ddaf7d0b71abe1f
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865413
+---
+ common/flatpak-dir.c | 39 ++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 38 insertions(+), 1 deletion(-)
+
+diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
+index 4ae1ab1..8c057eb 100644
+--- a/common/flatpak-dir.c
++++ b/common/flatpak-dir.c
+@@ -1306,7 +1306,44 @@ flatpak_dir_ensure_path (FlatpakDir   *self,
+                          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 */
diff -Nru flatpak-0.8.5/debian/patches/Ensure-we-don-t-install-world-writable-dirs-or-setuid-fil.patch flatpak-0.8.5/debian/patches/Ensure-we-don-t-install-world-writable-dirs-or-setuid-fil.patch
--- flatpak-0.8.5/debian/patches/Ensure-we-don-t-install-world-writable-dirs-or-setuid-fil.patch	1970-01-01 01:00:00.000000000 +0100
+++ flatpak-0.8.5/debian/patches/Ensure-we-don-t-install-world-writable-dirs-or-setuid-fil.patch	2017-06-21 12:05:49.000000000 +0100
@@ -0,0 +1,178 @@
+From: Alexander Larsson <al...@redhat.com>
+Date: Mon, 19 Jun 2017 19:01:08 +0200
+Subject: Ensure we don't install world-writable dirs or setuid files
+
+This is solved in a much nicer way on master, using new ostree
+APIs. However, here we take a brute-force approach of scanning
+all staged files and ensuring we don't have any files or
+directories with invalid modes before committing the transaction.
+
+If any bad permissions were found we delete the entire staging
+directory.
+
+Origin: upstream, 0.8.7, commit:2c8e2417deb6a0d293b15367fcd69080e285da31
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865413
+---
+ common/flatpak-dir.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ tests/test-run.sh    | 33 ++++++++++++++++++-
+ 2 files changed, 125 insertions(+), 1 deletion(-)
+
+diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
+index 8c057eb..4dd45c6 100644
+--- a/common/flatpak-dir.c
++++ b/common/flatpak-dir.c
+@@ -2110,6 +2110,96 @@ flatpak_dir_pull_oci (FlatpakDir          *self,
+   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,
+@@ -2238,6 +2328,9 @@ flatpak_dir_pull (FlatpakDir          *self,
+     goto out;
+ 
+ 
++  if (!ensure_safe_staging_permissions (repo, error))
++    goto out;
++
+   if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
+     goto out;
+ 
+diff --git a/tests/test-run.sh b/tests/test-run.sh
+index 0f0d3aa..2b70ff2 100755
+--- a/tests/test-run.sh
++++ b/tests/test-run.sh
+@@ -24,7 +24,7 @@ set -euo pipefail
+ skip_without_bwrap
+ skip_without_user_xattrs
+ 
+-echo "1..10"
++echo "1..12"
+ 
+ setup_repo
+ install_repo
+@@ -338,3 +338,34 @@ ${FLATPAK} build-export ${FL_GPGARGS} repos/test ${DIR}
+ ${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"
diff -Nru flatpak-0.8.5/debian/patches/series flatpak-0.8.5/debian/patches/series
--- flatpak-0.8.5/debian/patches/series	2017-04-24 12:59:09.000000000 +0100
+++ flatpak-0.8.5/debian/patches/series	2017-06-21 12:05:49.000000000 +0100
@@ -1 +1,3 @@
+dir-Ensure-.local-share-flatpak-is-0700.patch
+Ensure-we-don-t-install-world-writable-dirs-or-setuid-fil.patch
 Improve-and-simplify-profile-snippet.patch

Reply via email to