Fix CVE-2023-28100 and CVE-2023-28101 and Fix several memory leaks

(cherry picked from commit 6fe17b7f232e7c9530c41cff1c634d3cbad5ef28)
This commit is contained in:
starlet-dx 2024-03-28 15:25:16 +08:00 committed by openeuler-sync-bot
parent 748a464156
commit c06772b78d
8 changed files with 1685 additions and 1 deletions

394
CVE-2023-28100-pre1.patch Normal file
View File

@ -0,0 +1,394 @@
From 4206d681c5c52691dec0074e3f8c32dab1953a94 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Fri, 21 May 2021 17:41:31 +0100
Subject: [PATCH] test-context: Exercise some corner cases for merging
filesystems
Signed-off-by: Simon McVittie <smcv@collabora.com>
Co-authored-by: Alexander Larsson <alexl@redhat.com>
(cherry picked from commit fab0f8ed7c52fc58e6c550d123ede9621c760ca7)
[smcv: Also backport the scaffolding to create this test-case]
---
tests/Makefile.am.inc | 11 +-
tests/test-context.c | 343 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 353 insertions(+), 1 deletion(-)
create mode 100644 tests/test-context.c
diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc
index 53d6403e4c..0fb650cb38 100644
--- a/tests/Makefile.am.inc
+++ b/tests/Makefile.am.inc
@@ -66,6 +66,10 @@ testcommon_LDADD = \
$(NULL)
testcommon_SOURCES = tests/testcommon.c
+test_context_CFLAGS = $(testcommon_CFLAGS)
+test_context_LDADD = $(testcommon_LDADD)
+test_context_SOURCES = tests/test-context.c
+
test_exports_CFLAGS = $(testcommon_CFLAGS)
test_exports_LDADD = $(testcommon_LDADD)
test_exports_SOURCES = tests/test-exports.c
@@ -252,7 +256,12 @@ test_scripts = ${TEST_MATRIX}
dist_test_scripts = ${TEST_MATRIX_DIST}
dist_installed_test_extra_scripts += ${TEST_MATRIX_EXTRA_DIST}
-test_programs = testlibrary testcommon test-exports
+test_programs = \
+ test-context \
+ test-exports \
+ testcommon \
+ testlibrary \
+ $(NULL)
test_extra_programs = tests/httpcache tests/test-update-portal tests/test-portal-impl tests/test-authenticator tests/list-unused
@VALGRIND_CHECK_RULES@
diff --git a/tests/test-context.c b/tests/test-context.c
new file mode 100644
index 0000000000..c128a83fae
--- /dev/null
+++ b/tests/test-context.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright © 2021 Collabora Ltd.
+ *
+ * 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/>.
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+
+#include <glib.h>
+#include "flatpak.h"
+#include "flatpak-context-private.h"
+#include "flatpak-run-private.h"
+#include "flatpak-utils-private.h"
+
+/* g_str_has_prefix as a GEqualFunc */
+static gboolean
+str_has_prefix (gconstpointer candidate,
+ gconstpointer pattern)
+{
+ return g_str_has_prefix (candidate, pattern);
+}
+
+static void context_parse_args (FlatpakContext *context,
+ ...) G_GNUC_NULL_TERMINATED;
+
+static void
+context_parse_args (FlatpakContext *context,
+ ...)
+{
+ g_autoptr(GError) local_error = NULL;
+ g_autoptr(GOptionContext) oc = NULL;
+ g_autoptr(GOptionGroup) group = NULL;
+ g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free);
+ g_auto(GStrv) argv = NULL;
+ const char *arg;
+ va_list ap;
+
+ g_ptr_array_add (args, g_strdup ("argv[0]"));
+
+ va_start (ap, context);
+
+ while ((arg = va_arg (ap, const char *)) != NULL)
+ g_ptr_array_add (args, g_strdup (arg));
+
+ va_end (ap);
+
+ g_ptr_array_add (args, NULL);
+ argv = (GStrv) g_ptr_array_free (g_steal_pointer (&args), FALSE);
+
+ oc = g_option_context_new ("");
+ group = flatpak_context_get_options (context);
+ g_option_context_add_group (oc, group);
+ g_option_context_parse_strv (oc, &argv, &local_error);
+ g_assert_no_error (local_error);
+}
+
+static void
+test_context_merge_fs (void)
+{
+ /*
+ * We want to arrive at the same result regardless of whether we:
+ * - start from lowest precedence, and successively merge higher
+ * precedences into it, discarding them when done;
+ * - successively merge highest precedence into second-highest, and
+ * then discard highest
+ */
+ enum { LOWEST_FIRST, HIGHEST_FIRST, INVALID } merge_order;
+
+ for (merge_order = LOWEST_FIRST; merge_order < INVALID; merge_order++)
+ {
+ g_autoptr(FlatpakContext) lowest = flatpak_context_new ();
+ g_autoptr(FlatpakContext) middle = flatpak_context_new ();
+ g_autoptr(FlatpakContext) highest = flatpak_context_new ();
+ gpointer value;
+
+ context_parse_args (lowest,
+ "--filesystem=/one",
+ NULL);
+ context_parse_args (middle,
+ "--nofilesystem=host:reset",
+ "--filesystem=/two",
+ NULL);
+ context_parse_args (highest,
+ "--nofilesystem=host",
+ "--filesystem=/three",
+ NULL);
+
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (middle->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (middle->filesystems, "/three", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "host-reset", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/one", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/two", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ if (merge_order == LOWEST_FIRST)
+ {
+ flatpak_context_merge (lowest, middle);
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
+
+ flatpak_context_merge (lowest, highest);
+ }
+ else
+ {
+ flatpak_context_merge (middle, highest);
+
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (middle->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (middle->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ flatpak_context_merge (lowest, middle);
+ }
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ }
+
+ for (merge_order = LOWEST_FIRST; merge_order < INVALID; merge_order++)
+ {
+ g_autoptr(FlatpakContext) lowest = flatpak_context_new ();
+ g_autoptr(FlatpakContext) mid_low = flatpak_context_new ();
+ g_autoptr(FlatpakContext) mid_high = flatpak_context_new ();
+ g_autoptr(FlatpakContext) highest = flatpak_context_new ();
+ g_autoptr(GError) local_error = NULL;
+ g_autoptr(GKeyFile) metakey = g_key_file_new ();
+ g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free);
+ g_autofree char *filesystems = NULL;
+ gpointer value;
+
+ context_parse_args (lowest,
+ "--filesystem=/one",
+ NULL);
+ context_parse_args (mid_low,
+ "--nofilesystem=host:reset",
+ "--filesystem=/two",
+ NULL);
+ context_parse_args (mid_high,
+ "--filesystem=host",
+ "--filesystem=/three",
+ NULL);
+ context_parse_args (highest,
+ "--nofilesystem=host",
+ "--filesystem=/four",
+ NULL);
+
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/three", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/four", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "host-reset", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/one", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/two", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/four", NULL, NULL));
+
+ g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "host-reset", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/one", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/two", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (highest->filesystems, "/three", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (highest->filesystems, "/four", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ if (merge_order == LOWEST_FIRST)
+ {
+ flatpak_context_merge (lowest, mid_low);
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, NULL));
+
+ flatpak_context_merge (lowest, mid_high);
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, NULL));
+
+ flatpak_context_merge (lowest, highest);
+ }
+ else
+ {
+ flatpak_context_merge (mid_high, highest);
+
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "host-reset", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/one", NULL, NULL));
+ g_assert_false (g_hash_table_lookup_extended (mid_high->filesystems, "/two", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (mid_high->filesystems, "/four", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ flatpak_context_merge (mid_low, mid_high);
+
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (mid_low->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (mid_low->filesystems, "/four", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ flatpak_context_merge (lowest, mid_low);
+ }
+
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_NONE);
+ g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "/one", NULL, NULL));
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/two", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/three", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+ g_assert_true (g_hash_table_lookup_extended (lowest->filesystems, "/four", NULL, &value));
+ g_assert_cmpint (GPOINTER_TO_INT (value), ==, FLATPAK_FILESYSTEM_MODE_READ_WRITE);
+
+ flatpak_context_save_metadata (lowest, FALSE, metakey);
+ filesystems = g_key_file_get_value (metakey,
+ FLATPAK_METADATA_GROUP_CONTEXT,
+ FLATPAK_METADATA_KEY_FILESYSTEMS,
+ &local_error);
+ g_assert_no_error (local_error);
+ g_test_message ("%s=%s", FLATPAK_METADATA_KEY_FILESYSTEMS, filesystems);
+ /* !host:reset is serialized first */
+ g_assert_true (g_str_has_prefix (filesystems, "!host:reset;"));
+ /* The rest are serialized in arbitrary order */
+ g_assert_nonnull (strstr (filesystems, ";!host;"));
+ g_assert_null (strstr (filesystems, "/one"));
+ g_assert_nonnull (strstr (filesystems, ";/two;"));
+ g_assert_nonnull (strstr (filesystems, ";/three;"));
+ g_assert_nonnull (strstr (filesystems, ";/four;"));
+
+ flatpak_context_to_args (lowest, args);
+ /* !host:reset is serialized first */
+ g_assert_cmpuint (args->len, >, 0);
+ g_assert_cmpstr (g_ptr_array_index (args, 0), ==,
+ "--nofilesystem=host:reset");
+ /* The rest are serialized in arbitrary order */
+ g_assert_true (g_ptr_array_find_with_equal_func (args, "--nofilesystem=host", g_str_equal, NULL));
+ g_assert_false (g_ptr_array_find_with_equal_func (args, "--filesystem=/one", str_has_prefix, NULL));
+ g_assert_false (g_ptr_array_find_with_equal_func (args, "--nofilesystem=/one", str_has_prefix, NULL));
+ g_assert_true (g_ptr_array_find_with_equal_func (args, "--filesystem=/two", g_str_equal, NULL));
+ g_assert_true (g_ptr_array_find_with_equal_func (args, "--filesystem=/three", g_str_equal, NULL));
+ g_assert_true (g_ptr_array_find_with_equal_func (args, "--filesystem=/four", g_str_equal, NULL));
+ }
+}
+
+int
+main (int argc, char *argv[])
+{
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add_func ("/context/merge-fs", test_context_merge_fs);
+
+ return g_test_run ();
+}

231
CVE-2023-28100-pre2.patch Normal file
View File

@ -0,0 +1,231 @@
From b83fb81d1a66fe4ea31fd9c36ca425705eaaca99 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Thu, 21 Oct 2021 17:39:08 +0100
Subject: [PATCH] tests: Add try-syscall helper
This exercises various syscalls. It's heavily based on the one from
<https://github.com/containers/bubblewrap/pull/459>, but with the
addition of a mode to output the numeric values of various expected
errno codes, which are not otherwise available to shell scripts.
Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 4ce251882c488953ca6e3734f00c5dbe2e1e3e7a)
(cherry picked from commit f82e2a45777e6f370b9d3be787a84cddc3ed0575)
---
.gitignore | 1 +
tests/Makefile.am.inc | 14 +++-
tests/try-syscall.c | 173 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 187 insertions(+), 1 deletion(-)
create mode 100644 tests/try-syscall.c
diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc
index 3632591a04..2548080254 100644
--- a/tests/Makefile.am.inc
+++ b/tests/Makefile.am.inc
@@ -99,6 +99,10 @@ tests_test_authenticator_CFLAGS = $(AM_CFLAGS) $(BASE_CFLAGS) \
tests_test_authenticator_LDADD = $(AM_LDADD) $(BASE_LIBS) libflatpak-common.la libflatpak-common-base.la libglnx.la
tests_test_authenticator_SOURCES = tests/test-authenticator.c
+tests_try_syscall_CFLAGS = $(AM_CFLAGS)
+tests_try_syscall_LDADD = $(AM_LDADD)
+tests_try_syscall_SOURCES = tests/try-syscall.c
+
tests_list_unused_CFLAGS = $(AM_CFLAGS) $(BASE_CFLAGS) $(OSTREE_CFLAGS) $(SOUP_CFLAGS) $(JSON_CFLAGS) $(APPSTREAM_GLIB_CFLAGS) \
-DFLATPAK_COMPILATION \
-DLOCALEDIR=\"$(localedir)\"
@@ -263,7 +267,15 @@ test_programs = \
testcommon \
testlibrary \
$(NULL)
-test_extra_programs = tests/httpcache tests/test-update-portal tests/test-portal-impl tests/test-authenticator tests/list-unused
+
+test_extra_programs = \
+ tests/httpcache \
+ tests/list-unused \
+ tests/test-authenticator \
+ tests/test-portal-impl \
+ tests/test-update-portal \
+ tests/try-syscall \
+ $(NULL)
@VALGRIND_CHECK_RULES@
VALGRIND_SUPPRESSIONS_FILES=tests/flatpak.supp tests/glib.supp
diff --git a/tests/try-syscall.c b/tests/try-syscall.c
new file mode 100644
index 0000000000..84a0ca6673
--- /dev/null
+++ b/tests/try-syscall.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2021 Simon McVittie
+ * SPDX-License-Identifier: LGPL-2.0-or-later
+ *
+ * Try one or more system calls that might have been blocked by a
+ * seccomp filter. Return the last value of errno seen.
+ *
+ * In general, we pass a bad fd or pointer to each syscall that will
+ * accept one, so that it will fail with EBADF or EFAULT without side-effects.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/prctl.h>
+#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#if defined(_MIPS_SIM)
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+# define MISSING_SYSCALL_BASE 4000
+# elif _MIPS_SIM == _MIPS_SIM_ABI64
+# define MISSING_SYSCALL_BASE 5000
+# elif _MIPS_SIM == _MIPS_SIM_NABI32
+# define MISSING_SYSCALL_BASE 6000
+# else
+# error "Unknown MIPS ABI"
+# endif
+#endif
+
+#if defined(__ia64__)
+# define MISSING_SYSCALL_BASE 1024
+#endif
+
+#if defined(__alpha__)
+# define MISSING_SYSCALL_BASE 110
+#endif
+
+#if defined(__x86_64__) && defined(__ILP32__)
+# define MISSING_SYSCALL_BASE 0x40000000
+#endif
+
+/*
+ * MISSING_SYSCALL_BASE:
+ *
+ * Number to add to the syscall numbers of recently-added syscalls
+ * to get the appropriate syscall for the current ABI.
+ */
+#ifndef MISSING_SYSCALL_BASE
+# define MISSING_SYSCALL_BASE 0
+#endif
+
+#ifndef __NR_clone3
+# define __NR_clone3 (MISSING_SYSCALL_BASE + 435)
+#endif
+
+/*
+ * The size of clone3's parameter (as of 2021)
+ */
+#define SIZEOF_STRUCT_CLONE_ARGS ((size_t) 88)
+
+/*
+ * An invalid pointer that will cause syscalls to fail with EFAULT
+ */
+#define WRONG_POINTER ((char *) 1)
+
+int
+main (int argc, char **argv)
+{
+ int errsv = 0;
+ int i;
+
+ for (i = 1; i < argc; i++)
+ {
+ const char *arg = argv[i];
+
+ if (strcmp (arg, "print-errno-values") == 0)
+ {
+ printf ("EBADF=%d\n", EBADF);
+ printf ("EFAULT=%d\n", EFAULT);
+ printf ("ENOENT=%d\n", ENOENT);
+ printf ("ENOSYS=%d\n", ENOSYS);
+ printf ("EPERM=%d\n", EPERM);
+ }
+ else if (strcmp (arg, "chmod") == 0)
+ {
+ /* If not blocked by seccomp, this will fail with EFAULT */
+ if (chmod (WRONG_POINTER, 0700) != 0)
+ {
+ errsv = errno;
+ perror (arg);
+ }
+ }
+ else if (strcmp (arg, "chroot") == 0)
+ {
+ /* If not blocked by seccomp, this will fail with EFAULT */
+ if (chroot (WRONG_POINTER) != 0)
+ {
+ errsv = errno;
+ perror (arg);
+ }
+ }
+ else if (strcmp (arg, "clone3") == 0)
+ {
+ /* If not blocked by seccomp, this will fail with EFAULT */
+ if (syscall (__NR_clone3, WRONG_POINTER, SIZEOF_STRUCT_CLONE_ARGS) != 0)
+ {
+ errsv = errno;
+ perror (arg);
+ }
+ }
+ else if (strcmp (arg, "ioctl TIOCNOTTY") == 0)
+ {
+ /* If not blocked by seccomp, this will fail with EBADF */
+ if (ioctl (-1, TIOCNOTTY) != 0)
+ {
+ errsv = errno;
+ perror (arg);
+ }
+ }
+ else if (strcmp (arg, "ioctl TIOCSTI") == 0)
+ {
+ /* If not blocked by seccomp, this will fail with EBADF */
+ if (ioctl (-1, TIOCSTI, WRONG_POINTER) != 0)
+ {
+ errsv = errno;
+ perror (arg);
+ }
+ }
+#ifdef __LP64__
+ else if (strcmp (arg, "ioctl TIOCSTI CVE-2019-10063") == 0)
+ {
+ unsigned long not_TIOCSTI = (0x123UL << 32) | (unsigned long) TIOCSTI;
+
+ /* If not blocked by seccomp, this will fail with EBADF */
+ if (syscall (__NR_ioctl, -1, not_TIOCSTI, WRONG_POINTER) != 0)
+ {
+ errsv = errno;
+ perror (arg);
+ }
+ }
+#endif
+ else if (strcmp (arg, "listen") == 0)
+ {
+ /* If not blocked by seccomp, this will fail with EBADF */
+ if (listen (-1, 42) != 0)
+ {
+ errsv = errno;
+ perror (arg);
+ }
+ }
+ else if (strcmp (arg, "prctl") == 0)
+ {
+ /* If not blocked by seccomp, this will fail with EFAULT */
+ if (prctl (PR_GET_CHILD_SUBREAPER, WRONG_POINTER, 0, 0, 0) != 0)
+ {
+ errsv = errno;
+ perror (arg);
+ }
+ }
+ else
+ {
+ fprintf (stderr, "Unsupported syscall \"%s\"\n", arg);
+ errsv = ENOENT;
+ }
+ }
+
+ return errsv;
+}

142
CVE-2023-28100-pre3.patch Normal file
View File

@ -0,0 +1,142 @@
From e7880e25b9d400feeaacb82f115fae676ce6c65d Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Thu, 21 Oct 2021 17:41:08 +0100
Subject: [PATCH] tests: Add basic test coverage for our seccomp filters
In particular, this checks that CVE-2017-5226, CVE-2019-10063 and
CVE-2021-41133 are still prevented.
Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 7c5aec474caef7aa004286cc9359611ad21d227b)
(cherry picked from commit ff0f5a15b26dac28c8efd88c8d47e51751df8043)
---
tests/Makefile-test-matrix.am.inc | 1 +
tests/Makefile.am.inc | 1 +
tests/test-seccomp.sh | 94 +++++++++++++++++++++++++++++++
3 files changed, 96 insertions(+)
create mode 100755 tests/test-seccomp.sh
diff --git a/tests/Makefile-test-matrix.am.inc b/tests/Makefile-test-matrix.am.inc
index f56c169e60..e1ec09ffb0 100644
--- a/tests/Makefile-test-matrix.am.inc
+++ b/tests/Makefile-test-matrix.am.inc
@@ -43,6 +43,7 @@ TEST_MATRIX_DIST= \
tests/test-override.sh \
tests/test-auth.sh \
tests/test-unused.sh \
+ tests/test-seccomp.sh \
$(NULL)
TEST_MATRIX_EXTRA_DIST= \
tests/test-run.sh \
diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc
index 2548080254..fd13c0cd3d 100644
--- a/tests/Makefile.am.inc
+++ b/tests/Makefile.am.inc
@@ -237,6 +237,7 @@ TEST_MATRIX_SOURCE = \
tests/test-unused.sh \
tests/test-summaries.sh{user+system} \
tests/test-subset.sh{user+system} \
+ tests/test-seccomp.sh \
$(NULL)
update-test-matrix:
diff --git a/tests/test-seccomp.sh b/tests/test-seccomp.sh
new file mode 100755
index 0000000000..72b0dad231
--- /dev/null
+++ b/tests/test-seccomp.sh
@@ -0,0 +1,94 @@
+#!/bin/bash
+# Copyright 2021 Collabora Ltd.
+# SPDX-License-Identifier: LGPL-2.0-or-later
+
+set -euo pipefail
+
+. $(dirname $0)/libtest.sh
+
+skip_without_bwrap
+
+echo "1..16"
+
+setup_repo
+install_repo
+
+cp -a "$G_TEST_BUILDDIR/try-syscall" "$test_tmpdir/try-syscall"
+
+# How this works:
+# try-syscall tries to make various syscalls, some benign, some not.
+#
+# The parameters are chosen to make them fail with EBADF or EFAULT if
+# not blocked. If they are blocked, we get ENOSYS or EPERM. If the syscall
+# is impossible for a particular architecture, we get ENOENT.
+#
+# The exit status is an errno value, which we can compare with the expected
+# errno value.
+
+eval "$("$test_tmpdir/try-syscall" print-errno-values)"
+
+try_syscall () {
+ ${FLATPAK} run \
+ --filesystem="$test_tmpdir" \
+ --command="$test_tmpdir/try-syscall" \
+ $extra_argv \
+ org.test.Hello "$@"
+}
+
+for extra_argv in "" "--allow=multiarch"; do
+ echo "# testing with extra argv: '$extra_argv'"
+
+ echo "# chmod (benign)"
+ e=0
+ try_syscall chmod || e="$?"
+ assert_streq "$e" "$EFAULT"
+ ok "chmod not blocked"
+
+ echo "# chroot (harmful)"
+ e=0
+ try_syscall chroot || e="$?"
+ assert_streq "$e" "$EPERM"
+ ok "chroot blocked with EPERM"
+
+ echo "# clone3 (harmful)"
+ e=0
+ try_syscall clone3 || e="$?"
+ # This is either ENOSYS because the kernel genuinely doesn't implement it,
+ # or because we successfully blocked it. We can't tell which.
+ assert_streq "$e" "$ENOSYS"
+ ok "clone3 blocked with ENOSYS (CVE-2021-41133)"
+
+ echo "# ioctl TIOCNOTTY (benign)"
+ e=0
+ try_syscall "ioctl TIOCNOTTY" || e="$?"
+ assert_streq "$e" "$EBADF"
+ ok "ioctl TIOCNOTTY not blocked"
+
+ echo "# ioctl TIOCSTI (CVE-2017-5226)"
+ e=0
+ try_syscall "ioctl TIOCSTI" || e="$?"
+ assert_streq "$e" "$EPERM"
+ ok "ioctl TIOCSTI blocked (CVE-2017-5226)"
+
+ echo "# ioctl TIOCSTI (trying to repeat CVE-2019-10063)"
+ e=0
+ try_syscall "ioctl TIOCSTI CVE-2019-10063" || e="$?"
+ if test "$e" = "$ENOENT"; then
+ echo "ok # SKIP Cannot replicate CVE-2019-10063 on 32-bit architecture"
+ else
+ assert_streq "$e" "$EPERM"
+ ok "ioctl TIOCSTI with high bits blocked (CVE-2019-10063)"
+ fi
+
+ echo "# listen (benign)"
+ e=0
+ try_syscall "listen" || e="$?"
+ assert_streq "$e" "$EBADF"
+ ok "listen not blocked"
+
+ echo "# prctl (benign)"
+ e=0
+ try_syscall "prctl" || e="$?"
+ assert_streq "$e" "$EFAULT"
+ ok "prctl not blocked"
+done

85
CVE-2023-28100.patch Normal file
View File

@ -0,0 +1,85 @@
From a9bf18040cc075a70657c6090a59d7f6fe78f893 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@debian.org>
Date: Wed, 15 Mar 2023 09:58:56 +0000
Subject: [PATCH] run: Prevent TIOCLINUX ioctl, the same as TIOCSTI
The TIOCLINUX ioctl is only available on Linux virtual consoles such as
/dev/tty1. It has several Linux-specific functions, one of which is a
copy/paste operation which can be used for attacks similar to TIOCSTI.
This vulnerability does not affect typical graphical terminal emulators
such as xterm, gnome-terminal and Konsole, and Flatpak is primarily
designed to be run from a Wayland or X11 graphical environment, so this
is relatively unlikely to be a practical problem.
CVE-2023-28100, GHSA-7qpw-3vjv-xrqp
Resolves: https://github.com/flatpak/flatpak/security/advisories/GHSA-7qpw-3vjv-xrqp
Signed-off-by: Simon McVittie <smcv@debian.org>
---
common/flatpak-run.c | 4 ++++
tests/test-seccomp.sh | 8 +++++++-
tests/try-syscall.c | 9 +++++++++
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/common/flatpak-run.c b/common/flatpak-run.c
index 1c43ca7205..c4dcaca9e6 100644
--- a/common/flatpak-run.c
+++ b/common/flatpak-run.c
@@ -2872,6 +2872,10 @@ setup_seccomp (FlatpakBwrap *bwrap,
/* Don't allow faking input to the controlling tty (CVE-2017-5226) */
{SCMP_SYS (ioctl), EPERM, &SCMP_A1 (SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int) TIOCSTI)},
+ /* In the unlikely event that the controlling tty is a Linux virtual
+ * console (/dev/tty2 or similar), copy/paste operations have an effect
+ * similar to TIOCSTI (CVE-2023-28100) */
+ {SCMP_SYS (ioctl), EPERM, &SCMP_A1 (SCMP_CMP_MASKED_EQ, 0xFFFFFFFFu, (int) TIOCLINUX)},
/* seccomp can't look into clone3()'s struct clone_args to check whether
* the flags are OK, so we have no choice but to block clone3().
diff --git a/tests/test-seccomp.sh b/tests/test-seccomp.sh
index 72b0dad231..be6fb085d0 100755
--- a/tests/test-seccomp.sh
+++ b/tests/test-seccomp.sh
@@ -8,7 +8,7 @@ set -euo pipefail
skip_without_bwrap
-echo "1..16"
+echo "1..18"
setup_repo
install_repo
@@ -80,6 +80,12 @@ for extra_argv in "" "--allow=multiarch"; do
ok "ioctl TIOCSTI with high bits blocked (CVE-2019-10063)"
fi
+ echo "# ioctl TIOCLINUX (CVE-2023-28100)"
+ e=0
+ try_syscall "ioctl TIOCLINUX" || e="$?"
+ assert_streq "$e" "$EPERM"
+ ok "ioctl TIOCLINUX blocked"
+
echo "# listen (benign)"
e=0
try_syscall "listen" || e="$?"
diff --git a/tests/try-syscall.c b/tests/try-syscall.c
index 84a0ca6673..9dab899ba3 100644
--- a/tests/try-syscall.c
+++ b/tests/try-syscall.c
@@ -144,6 +144,15 @@ main (int argc, char **argv)
}
}
#endif
+ else if (strcmp (arg, "ioctl TIOCLINUX") == 0)
+ {
+ /* If not blocked by seccomp, this will fail with EBADF */
+ if (ioctl (-1, TIOCLINUX, WRONG_POINTER) != 0)
+ {
+ errsv = errno;
+ perror (arg);
+ }
+ }
else if (strcmp (arg, "listen") == 0)
{
/* If not blocked by seccomp, this will fail with EBADF */

320
CVE-2023-28101-1.patch Normal file
View File

@ -0,0 +1,320 @@
From acd627a2fabe9856947399044dbf7aa79247c75b Mon Sep 17 00:00:00 2001
From: Ryan Gonzalez <ryan.gonzalez@collabora.com>
Date: Sat, 4 Mar 2023 16:23:37 -0600
Subject: [PATCH] Ensure special characters in permissions and metadata are
escaped
This prevents someone from placing special characters in order to
manipulate the appearance of the permissions list.
CVE-2023-28101, GHSA-h43h-fwqx-mpp8
Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
---
app/flatpak-builtins-info.c | 8 +++-
app/flatpak-builtins-remote-info.c | 5 +-
app/flatpak-cli-transaction.c | 12 +++--
common/flatpak-utils-private.h | 11 +++++
common/flatpak-utils.c | 77 ++++++++++++++++++++++++++++++
tests/make-test-app.sh | 8 ++++
tests/test-info.sh | 14 ++++--
tests/testcommon.c | 39 +++++++++++++++
8 files changed, 164 insertions(+), 10 deletions(-)
diff --git a/app/flatpak-builtins-info.c b/app/flatpak-builtins-info.c
index c13d2d89eb..35d49c446a 100644
--- a/app/flatpak-builtins-info.c
+++ b/app/flatpak-builtins-info.c
@@ -400,7 +400,9 @@ flatpak_builtin_info (int argc, char **argv, GCancellable *cancellable, GError *
if (!g_file_load_contents (file, cancellable, &data, &data_size, NULL, error))
return FALSE;
- g_print ("%s", data);
+ flatpak_print_escaped_string (data,
+ FLATPAK_ESCAPE_ALLOW_NEWLINES
+ | FLATPAK_ESCAPE_DO_NOT_QUOTE);
}
if (opt_show_permissions || opt_file_access)
@@ -421,7 +423,9 @@ flatpak_builtin_info (int argc, char **argv, GCancellable *cancellable, GError *
if (contents == NULL)
return FALSE;
- g_print ("%s", contents);
+ flatpak_print_escaped_string (contents,
+ FLATPAK_ESCAPE_ALLOW_NEWLINES
+ | FLATPAK_ESCAPE_DO_NOT_QUOTE);
}
if (opt_file_access)
diff --git a/app/flatpak-builtins-remote-info.c b/app/flatpak-builtins-remote-info.c
index 20705a97ca..0ab05b7ca4 100644
--- a/app/flatpak-builtins-remote-info.c
+++ b/app/flatpak-builtins-remote-info.c
@@ -441,7 +441,10 @@ flatpak_builtin_remote_info (int argc, char **argv, GCancellable *cancellable, G
if (opt_show_metadata)
{
- g_print ("%s", xa_metadata ? xa_metadata : "");
+ if (xa_metadata != NULL)
+ flatpak_print_escaped_string (xa_metadata,
+ FLATPAK_ESCAPE_ALLOW_NEWLINES
+ | FLATPAK_ESCAPE_DO_NOT_QUOTE);
if (xa_metadata == NULL || !g_str_has_suffix (xa_metadata, "\n"))
g_print ("\n");
}
diff --git a/app/flatpak-cli-transaction.c b/app/flatpak-cli-transaction.c
index a258f905c4..b915bedd04 100644
--- a/app/flatpak-cli-transaction.c
+++ b/app/flatpak-cli-transaction.c
@@ -894,12 +894,16 @@ print_perm_line (int idx,
int cols)
{
g_autoptr(GString) res = g_string_new (NULL);
+ g_autofree char *escaped_first_perm = NULL;
int i;
- g_string_append_printf (res, " [%d] %s", idx, (char *) items->pdata[0]);
+ escaped_first_perm = flatpak_escape_string (items->pdata[0], FLATPAK_ESCAPE_DEFAULT);
+ g_string_append_printf (res, " [%d] %s", idx, escaped_first_perm);
for (i = 1; i < items->len; i++)
{
+ g_autofree char *escaped = flatpak_escape_string (items->pdata[i],
+ FLATPAK_ESCAPE_DEFAULT);
char *p;
int len;
@@ -908,10 +912,10 @@ print_perm_line (int idx,
p = res->str;
len = (res->str + strlen (res->str)) - p;
- if (len + strlen ((char *) items->pdata[i]) + 2 >= cols)
- g_string_append_printf (res, ",\n %s", (char *) items->pdata[i]);
+ if (len + strlen (escaped) + 2 >= cols)
+ g_string_append_printf (res, ",\n %s", escaped);
else
- g_string_append_printf (res, ", %s", (char *) items->pdata[i]);
+ g_string_append_printf (res, ", %s", escaped);
}
g_print ("%s\n", res->str);
diff --git a/common/flatpak-utils-private.h b/common/flatpak-utils-private.h
index 1a92154706..c1282641f9 100644
--- a/common/flatpak-utils-private.h
+++ b/common/flatpak-utils-private.h
@@ -902,6 +902,17 @@ null_safe_g_ptr_array_unref (gpointer data)
g_clear_pointer (&data, g_ptr_array_unref);
}
+typedef enum {
+ FLATPAK_ESCAPE_DEFAULT = 0,
+ FLATPAK_ESCAPE_ALLOW_NEWLINES = 1 << 0,
+ FLATPAK_ESCAPE_DO_NOT_QUOTE = 1 << 1,
+} FlatpakEscapeFlags;
+
+char * flatpak_escape_string (const char *s,
+ FlatpakEscapeFlags flags);
+void flatpak_print_escaped_string (const char *s,
+ FlatpakEscapeFlags flags);
+
#define FLATPAK_MESSAGE_ID "c7b39b1e006b464599465e105b361485"
#endif /* __FLATPAK_UTILS_H__ */
diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c
index 3a5adb82ee..0b91ae3f91 100644
--- a/common/flatpak-utils.c
+++ b/common/flatpak-utils.c
@@ -8613,4 +8613,81 @@ flatpak_dconf_path_is_similar (const char *path1,
return (path1[i1] == '\0');
}
+static gboolean
+is_char_safe (gunichar c)
+{
+ return g_unichar_isgraph (c) || c == ' ';
+}
+
+static gboolean
+should_hex_escape (gunichar c,
+ FlatpakEscapeFlags flags)
+{
+ if ((flags & FLATPAK_ESCAPE_ALLOW_NEWLINES) && c == '\n')
+ return FALSE;
+ return !is_char_safe (c);
+}
+
+static void
+append_hex_escaped_character (GString *result,
+ gunichar c)
+{
+ if (c <= 0xFF)
+ g_string_append_printf (result, "\\x%02X", c);
+ else if (c <= 0xFFFF)
+ g_string_append_printf (result, "\\u%04X", c);
+ else
+ g_string_append_printf (result, "\\U%08X", c);
+}
+
+char *
+flatpak_escape_string (const char *s,
+ FlatpakEscapeFlags flags)
+{
+ g_autoptr(GString) res = g_string_new ("");
+ gboolean did_escape = FALSE;
+
+ while (*s)
+ {
+ gunichar c = g_utf8_get_char_validated (s, -1);
+ if (c == (gunichar)-2 || c == (gunichar)-1)
+ {
+ /* Need to convert to unsigned first, to avoid negative chars becoming
+ huge gunichars. */
+ append_hex_escaped_character (res, (unsigned char)*s++);
+ did_escape = TRUE;
+ continue;
+ }
+ else if (should_hex_escape (c, flags))
+ {
+ append_hex_escaped_character (res, c);
+ did_escape = TRUE;
+ }
+ else if (c == '\\' || (!(flags & FLATPAK_ESCAPE_DO_NOT_QUOTE) && c == '\''))
+ {
+ g_string_append_printf (res, "\\%c", (char) c);
+ did_escape = TRUE;
+ }
+ else
+ g_string_append_unichar (res, c);
+
+ s = g_utf8_find_next_char (s, NULL);
+ }
+
+ if (did_escape && !(flags & FLATPAK_ESCAPE_DO_NOT_QUOTE))
+ {
+ g_string_prepend_c (res, '\'');
+ g_string_append_c (res, '\'');
+ }
+
+ return g_string_free (g_steal_pointer (&res), FALSE);
+}
+
+void
+flatpak_print_escaped_string (const char *s,
+ FlatpakEscapeFlags flags)
+{
+ g_autofree char *escaped = flatpak_escape_string (s, flags);
+ g_print ("%s", escaped);
+}
diff --git a/tests/make-test-app.sh b/tests/make-test-app.sh
index 731160535c..125e97f6b5 100755
--- a/tests/make-test-app.sh
+++ b/tests/make-test-app.sh
@@ -40,6 +40,14 @@ required-flatpak=$REQUIRED_VERSION
EOF
fi
+if [ x${INCLUDE_SPECIAL_CHARACTER-} != x ]; then
+TAB=$'\t'
+cat >> ${DIR}/metadata <<EOF
+[Environment]
+A=x${TAB}y
+EOF
+fi
+
cat >> ${DIR}/metadata <<EOF
[Extension $APP_ID.Locale]
directory=share/runtime/locale
diff --git a/tests/test-info.sh b/tests/test-info.sh
index 4a247bdb48..2158c11b10 100644
--- a/tests/test-info.sh
+++ b/tests/test-info.sh
@@ -6,9 +6,9 @@ set -euo pipefail
skip_revokefs_without_fuse
-echo "1..7"
+echo "1..8"
-setup_repo
+INCLUDE_SPECIAL_CHARACTER=1 setup_repo
install_repo
COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`
@@ -19,9 +19,17 @@ assert_file_has_content info "^app/org\.test\.Hello/$(flatpak --default-arch)/ma
ok "info -rcos"
+${FLATPAK} info --show-metadata org.test.Hello > info
+
+# CVE-2023-28101
+assert_file_has_content info "name=org\.test\.Hello"
+assert_file_has_content info "^A=x\\\\x09y"
+
+ok "info --show-metadata"
+
${FLATPAK} info --show-permissions org.test.Hello > info
-assert_file_empty info
+assert_file_has_content info "^A=x\\\\x09y"
ok "info --show-permissions"
diff --git a/tests/testcommon.c b/tests/testcommon.c
index 1d217c072a..daae5e4aac 100644
--- a/tests/testcommon.c
+++ b/tests/testcommon.c
@@ -1557,6 +1557,44 @@ test_dconf_paths (void)
}
}
+typedef struct {
+ const char *in;
+ FlatpakEscapeFlags flags;
+ const char *out;
+} EscapeData;
+
+static EscapeData escapes[] = {
+ {"abc def", FLATPAK_ESCAPE_DEFAULT, "abc def"},
+ {"やあ", FLATPAK_ESCAPE_DEFAULT, "やあ"},
+ {"\033[;1m", FLATPAK_ESCAPE_DEFAULT, "'\\x1B[;1m'"},
+ // non-printable U+061C
+ {"\u061C", FLATPAK_ESCAPE_DEFAULT, "'\\u061C'"},
+ // non-printable U+1343F
+ {"\xF0\x93\x90\xBF", FLATPAK_ESCAPE_DEFAULT, "'\\U0001343F'"},
+ // invalid utf-8
+ {"\xD8\1", FLATPAK_ESCAPE_DEFAULT, "'\\xD8\\x01'"},
+ {"\b \n abc ' \\", FLATPAK_ESCAPE_DEFAULT, "'\\x08 \\x0A abc \\' \\\\'"},
+ {"\b \n abc ' \\", FLATPAK_ESCAPE_DO_NOT_QUOTE, "\\x08 \\x0A abc ' \\\\"},
+ {"abc\tdef\n\033[;1m ghi\b", FLATPAK_ESCAPE_ALLOW_NEWLINES | FLATPAK_ESCAPE_DO_NOT_QUOTE,
+ "abc\\x09def\n\\x1B[;1m ghi\\x08"},
+};
+
+/* CVE-2023-28101 */
+static void
+test_string_escape (void)
+{
+ gsize idx;
+
+ for (idx = 0; idx < G_N_ELEMENTS (escapes); idx++)
+ {
+ EscapeData *data = &escapes[idx];
+ g_autofree char *ret = NULL;
+
+ ret = flatpak_escape_string (data->in, data->flags);
+ g_assert_cmpstr (ret, ==, data->out);
+ }
+}
+
int
main (int argc, char *argv[])
{
@@ -1585,6 +1623,7 @@ main (int argc, char *argv[])
g_test_add_func ("/common/dconf-app-id", test_dconf_app_id);
g_test_add_func ("/common/dconf-paths", test_dconf_paths);
g_test_add_func ("/common/decompose-ref", test_decompose);
+ g_test_add_func ("/common/string-escape", test_string_escape);
g_test_add_func ("/app/looks-like-branch", test_looks_like_branch);
g_test_add_func ("/app/columns", test_columns);

408
CVE-2023-28101-2.patch Normal file
View File

@ -0,0 +1,408 @@
From e88eedce76f79a5573df4fc38b344bbeaf7af024 Mon Sep 17 00:00:00 2001
From: Ryan Gonzalez <ryan.gonzalez@collabora.com>
Date: Sat, 4 Mar 2023 21:07:03 -0600
Subject: [PATCH] Reject paths given to --filesystem/--persist with special
characters
There isn't much in the way of legit reasons for this, but it's a
potential security footgun when displaying the text.
CVE-2023-28101, GHSA-h43h-fwqx-mpp8
Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
Co-authored-by: Simon McVittie <smcv@collabora.com>
---
common/flatpak-context.c | 36 ++++++++++++---
common/flatpak-utils-private.h | 3 ++
common/flatpak-utils.c | 40 ++++++++++++++++
tests/test-context.c | 84 ++++++++++++++++++++++++++++++++--
tests/testcommon.c | 41 +++++++++++++++--
5 files changed, 190 insertions(+), 14 deletions(-)
diff --git a/common/flatpak-context.c b/common/flatpak-context.c
index 9c506499a4..512a577f81 100644
--- a/common/flatpak-context.c
+++ b/common/flatpak-context.c
@@ -487,11 +487,17 @@ flatpak_context_apply_generic_policy (FlatpakContext *context,
g_ptr_array_free (new, FALSE));
}
-static void
+
+static gboolean
flatpak_context_set_persistent (FlatpakContext *context,
- const char *path)
+ const char *path,
+ GError **error)
{
+ if (!flatpak_validate_path_characters (path, error))
+ return FALSE;
+
g_hash_table_insert (context->persistent, g_strdup (path), GINT_TO_POINTER (1));
+ return TRUE;
}
static gboolean
@@ -853,6 +859,9 @@ flatpak_context_parse_filesystem (const char *filesystem_and_mode,
g_autofree char *filesystem = NULL;
char *slash;
+ if (!flatpak_validate_path_characters (filesystem_and_mode, error))
+ return FALSE;
+
filesystem = parse_filesystem_flags (filesystem_and_mode, negated, mode_out, error);
if (filesystem == NULL)
return FALSE;
@@ -1484,8 +1493,7 @@ option_persist_cb (const gchar *option_name,
{
FlatpakContext *context = data;
- flatpak_context_set_persistent (context, value);
- return TRUE;
+ return flatpak_context_set_persistent (context, value, error);
}
static gboolean option_no_desktop_deprecated;
@@ -1677,11 +1685,24 @@ flatpak_context_load_metadata (FlatpakContext *context,
{
const char *fs = parse_negated (filesystems[i], &remove);
g_autofree char *filesystem = NULL;
+ g_autoptr(GError) local_error = NULL;
FlatpakFilesystemMode mode;
if (!flatpak_context_parse_filesystem (fs, remove,
- &filesystem, &mode, NULL))
- g_debug ("Unknown filesystem type %s", filesystems[i]);
+ &filesystem, &mode, &local_error))
+ {
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA))
+ {
+ /* Invalid characters, so just hard-fail. */
+ g_propagate_error (error, g_steal_pointer (&local_error));
+ return FALSE;
+ }
+ else
+ {
+ g_debug ("Unknown filesystem type %s", filesystems[i]);
+ g_clear_error (&local_error);
+ }
+ }
else
{
g_assert (mode == FLATPAK_FILESYSTEM_MODE_NONE || !remove);
@@ -1698,7 +1719,8 @@ flatpak_context_load_metadata (FlatpakContext *context,
return FALSE;
for (i = 0; persistent[i] != NULL; i++)
- flatpak_context_set_persistent (context, persistent[i]);
+ if (!flatpak_context_set_persistent (context, persistent[i], error))
+ return FALSE;
}
if (g_key_file_has_group (metakey, FLATPAK_METADATA_GROUP_SESSION_BUS_POLICY))
diff --git a/common/flatpak-utils-private.h b/common/flatpak-utils-private.h
index c1282641f9..195023c20f 100644
--- a/common/flatpak-utils-private.h
+++ b/common/flatpak-utils-private.h
@@ -913,6 +913,9 @@ char * flatpak_escape_string (const char *s,
void flatpak_print_escaped_string (const char *s,
FlatpakEscapeFlags flags);
+gboolean flatpak_validate_path_characters (const char *path,
+ GError **error);
+
#define FLATPAK_MESSAGE_ID "c7b39b1e006b464599465e105b361485"
#endif /* __FLATPAK_UTILS_H__ */
diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c
index 0b91ae3f91..b562522e58 100644
--- a/common/flatpak-utils.c
+++ b/common/flatpak-utils.c
@@ -8641,6 +8641,14 @@ append_hex_escaped_character (GString *result,
g_string_append_printf (result, "\\U%08X", c);
}
+static char *
+escape_character (gunichar c)
+{
+ g_autoptr(GString) res = g_string_new ("");
+ append_hex_escaped_character (res, c);
+ return g_string_free (g_steal_pointer (&res), FALSE);
+}
+
char *
flatpak_escape_string (const char *s,
FlatpakEscapeFlags flags)
@@ -8691,3 +8699,35 @@ flatpak_print_escaped_string (const char *s,
g_autofree char *escaped = flatpak_escape_string (s, flags);
g_print ("%s", escaped);
}
+
+gboolean
+flatpak_validate_path_characters (const char *path,
+ GError **error)
+{
+ while (*path)
+ {
+ gunichar c = g_utf8_get_char_validated (path, -1);
+ if (c == (gunichar)-1 || c == (gunichar)-2)
+ {
+ /* Need to convert to unsigned first, to avoid negative chars becoming
+ huge gunichars. */
+ g_autofree char *escaped_char = escape_character ((unsigned char)*path);
+ g_autofree char *escaped = flatpak_escape_string (path, FLATPAK_ESCAPE_DEFAULT);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
+ "Non-UTF8 byte %s in path %s", escaped_char, escaped);
+ return FALSE;
+ }
+ else if (!is_char_safe (c))
+ {
+ g_autofree char *escaped_char = escape_character (c);
+ g_autofree char *escaped = flatpak_escape_string (path, FLATPAK_ESCAPE_DEFAULT);
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA,
+ "Non-graphical character %s in path %s", escaped_char, escaped);
+ return FALSE;
+ }
+
+ path = g_utf8_find_next_char (path, NULL);
+ }
+
+ return TRUE;
+}
diff --git a/tests/test-context.c b/tests/test-context.c
index c128a83fae..6c15feb013 100644
--- a/tests/test-context.c
+++ b/tests/test-context.c
@@ -34,13 +34,14 @@ str_has_prefix (gconstpointer candidate,
}
static void context_parse_args (FlatpakContext *context,
+ GError **error,
...) G_GNUC_NULL_TERMINATED;
static void
context_parse_args (FlatpakContext *context,
+ GError **error,
...)
{
- g_autoptr(GError) local_error = NULL;
g_autoptr(GOptionContext) oc = NULL;
g_autoptr(GOptionGroup) group = NULL;
g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free);
@@ -50,7 +51,7 @@ context_parse_args (FlatpakContext *context,
g_ptr_array_add (args, g_strdup ("argv[0]"));
- va_start (ap, context);
+ va_start (ap, error);
while ((arg = va_arg (ap, const char *)) != NULL)
g_ptr_array_add (args, g_strdup (arg));
@@ -63,8 +64,7 @@ context_parse_args (FlatpakContext *context,
oc = g_option_context_new ("");
group = flatpak_context_get_options (context);
g_option_context_add_group (oc, group);
- g_option_context_parse_strv (oc, &argv, &local_error);
- g_assert_no_error (local_error);
+ g_option_context_parse_strv (oc, &argv, error);
}
static void
@@ -84,19 +84,26 @@ test_context_merge_fs (void)
g_autoptr(FlatpakContext) lowest = flatpak_context_new ();
g_autoptr(FlatpakContext) middle = flatpak_context_new ();
g_autoptr(FlatpakContext) highest = flatpak_context_new ();
+ g_autoptr(GError) local_error = NULL;
gpointer value;
context_parse_args (lowest,
+ &local_error,
"--filesystem=/one",
NULL);
+ g_assert_no_error (local_error);
context_parse_args (middle,
+ &local_error,
"--nofilesystem=host:reset",
"--filesystem=/two",
NULL);
+ g_assert_no_error (local_error);
context_parse_args (highest,
+ &local_error,
"--nofilesystem=host",
"--filesystem=/three",
NULL);
+ g_assert_no_error (local_error);
g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, NULL));
g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, NULL));
@@ -178,20 +185,28 @@ test_context_merge_fs (void)
gpointer value;
context_parse_args (lowest,
+ &local_error,
"--filesystem=/one",
NULL);
+ g_assert_no_error (local_error);
context_parse_args (mid_low,
+ &local_error,
"--nofilesystem=host:reset",
"--filesystem=/two",
NULL);
+ g_assert_no_error (local_error);
context_parse_args (mid_high,
+ &local_error,
"--filesystem=host",
"--filesystem=/three",
NULL);
+ g_assert_no_error (local_error);
context_parse_args (highest,
+ &local_error,
"--nofilesystem=host",
"--filesystem=/four",
NULL);
+ g_assert_no_error (local_error);
g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host", NULL, NULL));
g_assert_false (g_hash_table_lookup_extended (lowest->filesystems, "host-reset", NULL, NULL));
@@ -332,12 +347,73 @@ test_context_merge_fs (void)
}
}
+const char *invalid_path_args[] = {
+ "--filesystem=/\033[J:ro",
+ "--filesystem=/\033[J",
+ "--persist=\033[J",
+};
+
+/* CVE-2023-28101 */
+static void
+test_validate_path_args (void)
+{
+ gsize idx;
+
+ for (idx = 0; idx < G_N_ELEMENTS (invalid_path_args); idx++)
+ {
+ g_autoptr(FlatpakContext) context = flatpak_context_new ();
+ g_autoptr(GError) local_error = NULL;
+ const char *path = invalid_path_args[idx];
+
+ context_parse_args (context, &local_error, path, NULL);
+ g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
+ g_assert (strstr (local_error->message, "Non-graphical character"));
+ }
+}
+
+typedef struct {
+ const char *key;
+ const char *value;
+} PathValidityData;
+
+PathValidityData invalid_path_meta[] = {
+ {FLATPAK_METADATA_KEY_FILESYSTEMS, "\033[J"},
+ {FLATPAK_METADATA_KEY_PERSISTENT, "\033[J"},
+};
+
+/* CVE-2023-28101 */
+static void
+test_validate_path_meta (void)
+{
+ gsize idx;
+
+ for (idx = 0; idx < G_N_ELEMENTS (invalid_path_meta); idx++)
+ {
+ g_autoptr(FlatpakContext) context = flatpak_context_new ();
+ g_autoptr(GKeyFile) metakey = g_key_file_new ();
+ g_autoptr(GError) local_error = NULL;
+ PathValidityData *data = &invalid_path_meta[idx];
+ gboolean ret = FALSE;
+
+ g_key_file_set_string_list (metakey, FLATPAK_METADATA_GROUP_CONTEXT,
+ data->key, &data->value, 1);
+
+ ret = flatpak_context_load_metadata (context, metakey, &local_error);
+ g_assert_false (ret);
+ g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
+ g_assert (strstr (local_error->message, "Non-graphical character"));
+ }
+
+}
+
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/context/merge-fs", test_context_merge_fs);
+ g_test_add_func ("/context/validate-path-args", test_validate_path_args);
+ g_test_add_func ("/context/validate-path-meta", test_validate_path_meta);
return g_test_run ();
}
diff --git a/tests/testcommon.c b/tests/testcommon.c
index daae5e4aac..0840632575 100644
--- a/tests/testcommon.c
+++ b/tests/testcommon.c
@@ -1567,11 +1567,12 @@ static EscapeData escapes[] = {
{"abc def", FLATPAK_ESCAPE_DEFAULT, "abc def"},
{"やあ", FLATPAK_ESCAPE_DEFAULT, "やあ"},
{"\033[;1m", FLATPAK_ESCAPE_DEFAULT, "'\\x1B[;1m'"},
- // non-printable U+061C
+ /* U+061C ARABIC LETTER MARK, non-printable */
{"\u061C", FLATPAK_ESCAPE_DEFAULT, "'\\u061C'"},
- // non-printable U+1343F
+ /* U+1343F EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE, non-printable and
+ * outside BMP */
{"\xF0\x93\x90\xBF", FLATPAK_ESCAPE_DEFAULT, "'\\U0001343F'"},
- // invalid utf-8
+ /* invalid utf-8 */
{"\xD8\1", FLATPAK_ESCAPE_DEFAULT, "'\\xD8\\x01'"},
{"\b \n abc ' \\", FLATPAK_ESCAPE_DEFAULT, "'\\x08 \\x0A abc \\' \\\\'"},
{"\b \n abc ' \\", FLATPAK_ESCAPE_DO_NOT_QUOTE, "\\x08 \\x0A abc ' \\\\"},
@@ -1595,6 +1596,39 @@ test_string_escape (void)
}
}
+typedef struct {
+ const char *path;
+ gboolean ret;
+} PathValidityData;
+
+static PathValidityData paths[] = {
+ {"/a/b/../c.def", TRUE},
+ {"やあ", TRUE},
+ /* U+061C ARABIC LETTER MARK, non-printable */
+ {"\u061C", FALSE},
+ /* U+1343F EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE, non-printable and
+ * outside BMP */
+ {"\xF0\x93\x90\xBF", FALSE},
+ /* invalid utf-8 */
+ {"\xD8\1", FALSE},
+};
+
+/* CVE-2023-28101 */
+static void
+test_validate_path_characters (void)
+{
+ gsize idx;
+
+ for (idx = 0; idx < G_N_ELEMENTS (paths); idx++)
+ {
+ PathValidityData *data = &paths[idx];
+ gboolean ret = FALSE;
+
+ ret = flatpak_validate_path_characters (data->path, NULL);
+ g_assert_cmpint (ret, ==, data->ret);
+ }
+}
+
int
main (int argc, char *argv[])
{
@@ -1624,6 +1658,7 @@ main (int argc, char *argv[])
g_test_add_func ("/common/dconf-paths", test_dconf_paths);
g_test_add_func ("/common/decompose-ref", test_decompose);
g_test_add_func ("/common/string-escape", test_string_escape);
+ g_test_add_func ("/common/validate-path-characters", test_validate_path_characters);
g_test_add_func ("/app/looks-like-branch", test_looks_like_branch);
g_test_add_func ("/app/columns", test_columns);

View File

@ -0,0 +1,85 @@
From b912053c6cc556f131465c1fd877d7bd0b433539 Mon Sep 17 00:00:00 2001
From: Phaedrus Leeds <mwleeds@protonmail.com>
Date: Sun, 2 May 2021 21:53:02 -0500
Subject: [PATCH] Fix several memory leaks
(cherry picked from commit 404d7c6941baf63d1b3ccbe9ee9d34f3ff12f35f)
---
app/flatpak-builtins-document-export.c | 6 +++---
common/flatpak-dir.c | 7 ++++---
common/flatpak-utils.c | 1 +
portal/flatpak-portal.c | 2 +-
4 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/app/flatpak-builtins-document-export.c b/app/flatpak-builtins-document-export.c
index 15f1ad1275..e701a826bb 100644
--- a/app/flatpak-builtins-document-export.c
+++ b/app/flatpak-builtins-document-export.c
@@ -90,8 +90,8 @@ flatpak_builtin_document_export (int argc, char **argv,
g_autofree char *dirname = NULL;
g_autofree char *doc_path = NULL;
XdpDbusDocuments *documents;
- int fd, fd_id;
- int i;
+ glnx_autofd int fd = -1;
+ int i, fd_id;
GUnixFDList *fd_list = NULL;
const char *doc_id;
struct stat stbuf;
@@ -173,7 +173,7 @@ flatpak_builtin_document_export (int argc, char **argv,
fd_list = g_unix_fd_list_new ();
fd_id = g_unix_fd_list_append (fd_list, fd, error);
- close (fd);
+ glnx_close_fd (&fd);
if (opt_noexist)
{
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
index 94a86f4afb..0724677b91 100644
--- a/common/flatpak-dir.c
+++ b/common/flatpak-dir.c
@@ -13690,14 +13690,15 @@ parse_ref_file (GKeyFile *keyfile,
collection_id = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP,
FLATPAK_REF_DEPLOY_COLLECTION_ID_KEY, NULL);
- if (collection_id == NULL || *collection_id == '\0')
+ if (collection_id != NULL && *collection_id == '\0')
+ g_clear_pointer (&collection_id, g_free);
+ if (collection_id == NULL)
{
collection_id = g_key_file_get_string (keyfile, FLATPAK_REF_GROUP,
FLATPAK_REF_COLLECTION_ID_KEY, NULL);
}
-
if (collection_id != NULL && *collection_id == '\0')
- collection_id = NULL;
+ g_clear_pointer (&collection_id, g_free);
if (collection_id != NULL && gpg_data == NULL)
return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Collection ID requires GPG key to be provided"));
diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c
index 56cbb06db3..84bc6a398d 100644
--- a/common/flatpak-utils.c
+++ b/common/flatpak-utils.c
@@ -2235,6 +2235,7 @@ flatpak_parse_repofile (const char *remote_name,
decoded = g_base64_decode (gpg_key, &decoded_len);
if (decoded_len < 10) /* Check some minimal size so we don't get crap */
{
+ g_free (decoded);
flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, _("Invalid gpg key"));
return NULL;
}
diff --git a/portal/flatpak-portal.c b/portal/flatpak-portal.c
index 7887c57a3b..0539ff2d22 100644
--- a/portal/flatpak-portal.c
+++ b/portal/flatpak-portal.c
@@ -767,7 +767,7 @@ handle_spawn (PortalFlatpak *object,
const gint *fds = NULL;
gint fds_len = 0;
g_autofree FdMapEntry *fd_map = NULL;
- gchar **env;
+ g_auto(GStrv) env = NULL;
gint32 max_fd;
GKeyFile *app_info;
g_autoptr(GPtrArray) flatpak_argv = g_ptr_array_new_with_free_func (g_free);

View File

@ -1,6 +1,6 @@
Name: flatpak Name: flatpak
Version: 1.10.2 Version: 1.10.2
Release: 5 Release: 7
Summary: Application deployment framework for desktop apps Summary: Application deployment framework for desktop apps
License: LGPLv2+ License: LGPLv2+
URL: http://flatpak.org/ URL: http://flatpak.org/
@ -26,6 +26,19 @@ Patch6013: backport-0002-CVE-2021-43860.patch
Patch6014: backport-0003-CVE-2021-43860.patch Patch6014: backport-0003-CVE-2021-43860.patch
Patch6015: backport-0004-CVE-2021-43860.patch Patch6015: backport-0004-CVE-2021-43860.patch
Patch6016: backport-0005-CVE-2021-43860.patch Patch6016: backport-0005-CVE-2021-43860.patch
Patch6017: backport-Fix-several-memory-leaks.patch
# https://github.com/flatpak/flatpak/commit/4206d681c5c52691dec0074e3f8c32dab1953a94
Patch6018: CVE-2023-28100-pre1.patch
# https://github.com/flatpak/flatpak/commit/b83fb81d1a66fe4ea31fd9c36ca425705eaaca99
Patch6019: CVE-2023-28100-pre2.patch
# https://github.com/flatpak/flatpak/commit/e7880e25b9d400feeaacb82f115fae676ce6c65d
Patch6020: CVE-2023-28100-pre3.patch
# https://github.com/flatpak/flatpak/commit/a9bf18040cc075a70657c6090a59d7f6fe78f893
Patch6021: CVE-2023-28100.patch
# https://github.com/flatpak/flatpak/commit/acd627a2fabe9856947399044dbf7aa79247c75b
Patch6022: CVE-2023-28101-1.patch
# https://github.com/flatpak/flatpak/commit/e88eedce76f79a5573df4fc38b344bbeaf7af024
Patch6023: CVE-2023-28101-2.patch
BuildRequires: pkgconfig(appstream-glib) pkgconfig(gio-unix-2.0) pkgconfig(gobject-introspection-1.0) >= 1.40.0 pkgconfig(json-glib-1.0) pkgconfig(libarchive) >= 2.8.0 BuildRequires: pkgconfig(appstream-glib) pkgconfig(gio-unix-2.0) pkgconfig(gobject-introspection-1.0) >= 1.40.0 pkgconfig(json-glib-1.0) pkgconfig(libarchive) >= 2.8.0
BuildRequires: pkgconfig(libsoup-2.4) pkgconfig(libxml-2.0) >= 2.4 pkgconfig(ostree-1) >= 2020.8 pkgconfig(polkit-gobject-1) pkgconfig(libseccomp) pkgconfig(xau) BuildRequires: pkgconfig(libsoup-2.4) pkgconfig(libxml-2.0) >= 2.4 pkgconfig(ostree-1) >= 2020.8 pkgconfig(polkit-gobject-1) pkgconfig(libseccomp) pkgconfig(xau)
@ -131,6 +144,12 @@ flatpak remote-list --system &> /dev/null || :
%{_mandir}/man5/flatpak-remote.5* %{_mandir}/man5/flatpak-remote.5*
%changelog %changelog
* Thu Mar 28 2024 yaoxin <yao_xin001@hoperun.com> - 1.10.2-7
- Fix CVE-2023-28100 and CVE-2023-28101
* Tue Dec 26 2023 maokecheng <maokecheng@xfusion.com> - 1.10.2-6
- DESC:Fix several memory leaks
* Sat Jan 29 2022 dongyuzhen <dongyuzhen@h-partners.com> - 1.10.2-5 * Sat Jan 29 2022 dongyuzhen <dongyuzhen@h-partners.com> - 1.10.2-5
- Fix CVE-2021-43860 - Fix CVE-2021-43860