Compare commits
10 Commits
b438c20951
...
1dd69bf453
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1dd69bf453 | ||
|
|
3ebf716878 | ||
|
|
51db3c693d | ||
|
|
4fc0a614c1 | ||
|
|
b76cb2636d | ||
|
|
c06772b78d | ||
|
|
748a464156 | ||
|
|
b078926f3a | ||
|
|
ee03d27738 | ||
|
|
a4560027db |
394
CVE-2023-28100-pre1.patch
Normal file
394
CVE-2023-28100-pre1.patch
Normal 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
231
CVE-2023-28100-pre2.patch
Normal 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
142
CVE-2023-28100-pre3.patch
Normal 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
85
CVE-2023-28100.patch
Normal 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
320
CVE-2023-28101-1.patch
Normal 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
408
CVE-2023-28101-2.patch
Normal 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);
|
||||
70
CVE-2024-32462.patch
Normal file
70
CVE-2024-32462.patch
Normal file
@ -0,0 +1,70 @@
|
||||
From 72016e3fce8fcbeab707daf4f1a02b931fcc004d Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Larsson <alexl@redhat.com>
|
||||
Date: Mon, 15 Apr 2024 16:10:36 +0200
|
||||
Subject: [PATCH] When starting non-static command using bwrap use "--"
|
||||
|
||||
Origin: https://github.com/flatpak/flatpak/commit/72016e3fce8fcbeab707daf4f1a02b931fcc004d
|
||||
|
||||
This ensures that the command is not taken to be a bwrap option.
|
||||
|
||||
Resolves: CVE-2024-32462
|
||||
Resolves: GHSA-phv6-cpc2-2fgj
|
||||
Signed-off-by: Alexander Larsson <alexl@redhat.com>
|
||||
[smcv: Fix DISABLE_SANDBOXED_TRIGGERS code path]
|
||||
[smcv: Make flatpak_run_maybe_start_dbus_proxy() more obviously correct]
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
---
|
||||
app/flatpak-builtins-build.c | 3 ++-
|
||||
common/flatpak-dir.c | 1 +
|
||||
common/flatpak-run.c | 5 ++++-
|
||||
3 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/app/flatpak-builtins-build.c b/app/flatpak-builtins-build.c
|
||||
index c0b12dbca1..761af9a1b0 100644
|
||||
--- a/app/flatpak-builtins-build.c
|
||||
+++ b/app/flatpak-builtins-build.c
|
||||
@@ -576,7 +576,8 @@ flatpak_builtin_build (int argc, char **argv, GCancellable *cancellable, GError
|
||||
if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
|
||||
return FALSE;
|
||||
|
||||
- flatpak_bwrap_add_args (bwrap, command, NULL);
|
||||
+ flatpak_bwrap_add_args (bwrap, "--", command, NULL);
|
||||
+
|
||||
flatpak_bwrap_append_argsv (bwrap,
|
||||
&argv[rest_argv_start + 2],
|
||||
rest_argc - 2);
|
||||
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
|
||||
index 6e07d08e3d..296a7dfd78 100644
|
||||
--- a/common/flatpak-dir.c
|
||||
+++ b/common/flatpak-dir.c
|
||||
@@ -6653,6 +6653,7 @@ flatpak_dir_run_triggers (FlatpakDir *self,
|
||||
"--proc", "/proc",
|
||||
"--dev", "/dev",
|
||||
"--bind", basedir, basedir,
|
||||
+ "--",
|
||||
NULL);
|
||||
#endif
|
||||
flatpak_bwrap_add_args (bwrap,
|
||||
diff --git a/common/flatpak-run.c b/common/flatpak-run.c
|
||||
index c4dcaca9e6..7a3900c651 100644
|
||||
--- a/common/flatpak-run.c
|
||||
+++ b/common/flatpak-run.c
|
||||
@@ -1082,6 +1082,9 @@ add_bwrap_wrapper (FlatpakBwrap *bwrap,
|
||||
if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
|
||||
return FALSE;
|
||||
|
||||
+ /* End of options: the next argument will be the executable name */
|
||||
+ flatpak_bwrap_add_arg (bwrap, "--");
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -4175,7 +4178,7 @@ flatpak_run_app (FlatpakDecomposed *app_ref,
|
||||
if (!flatpak_bwrap_bundle_args (bwrap, 1, -1, FALSE, error))
|
||||
return FALSE;
|
||||
|
||||
- flatpak_bwrap_add_arg (bwrap, command);
|
||||
+ flatpak_bwrap_add_args (bwrap, "--", command, NULL);
|
||||
|
||||
if (!add_rest_args (bwrap, app_id,
|
||||
exports, (flags & FLATPAK_RUN_FLAG_FILE_FORWARDING) != 0,
|
||||
225
CVE-2024-42472.patch
Normal file
225
CVE-2024-42472.patch
Normal file
@ -0,0 +1,225 @@
|
||||
Origin:
|
||||
https://github.com/flatpak/flatpak/commit/8a18137d7e80f0575e8defabf677d81e5cc3a788
|
||||
https://github.com/flatpak/flatpak/commit/db3a785241fda63bf53f0ec12bb519aa5210de19
|
||||
https://github.com/flatpak/flatpak/commit/847dfb88cebbdf8825332730b837489684dfb91e
|
||||
https://github.com/flatpak/flatpak/commit/7c63e53bb2af0aae9097fd2edfd6a9ba9d453e97
|
||||
|
||||
From 7c63e53bb2af0aae9097fd2edfd6a9ba9d453e97 Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Wed, 14 Aug 2024 13:44:30 +0100
|
||||
Subject: [PATCH] persist directories: Pass using new bwrap --bind-fd option
|
||||
|
||||
Instead of passing a /proc/self/fd bind mount we use --bind-fd, which
|
||||
has two advantages:
|
||||
* bwrap closes the fd when used, so it doesn't leak into the started app
|
||||
* bwrap ensures that what was mounted was the passed in fd (same dev/ino),
|
||||
as there is a small (required) gap between symlink resolve and mount
|
||||
where the target path could be replaced.
|
||||
|
||||
Please note that this change requires an updated version of bubblewrap.
|
||||
|
||||
Resolves: CVE-2024-42472, GHSA-7hgv-f2j8-xw87
|
||||
[smcv: Make whitespace consistent]
|
||||
Co-authored-by: Simon McVittie <smcv@collabora.com>
|
||||
Signed-off-by: Simon McVittie <smcv@collabora.com>
|
||||
|
||||
---
|
||||
common/flatpak-context.c | 109 +++++++++++++++++++++++++++++++++++++--
|
||||
configure.ac | 3 ++
|
||||
tests/test-run.sh | 39 ++++++++++++++
|
||||
3 files changed, 148 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/common/flatpak-context.c b/common/flatpak-context.c
|
||||
index 6303c71..09dd440 100644
|
||||
--- a/common/flatpak-context.c
|
||||
+++ b/common/flatpak-context.c
|
||||
@@ -2616,6 +2616,90 @@ flatpak_context_get_run_flags (FlatpakContext *context)
|
||||
return flags;
|
||||
}
|
||||
|
||||
+/* This creates zero or more directories unders base_fd+basedir, each
|
||||
+ * being guaranteed to either exist and be a directory (no symlinks)
|
||||
+ * or be created as a directory. The last directory is opened
|
||||
+ * and the fd is returned.
|
||||
+ */
|
||||
+static gboolean
|
||||
+mkdir_p_open_nofollow_at (int base_fd,
|
||||
+ const char *basedir,
|
||||
+ int mode,
|
||||
+ const char *subdir,
|
||||
+ int *out_fd,
|
||||
+ GError **error)
|
||||
+{
|
||||
+ glnx_autofd int parent_fd = -1;
|
||||
+
|
||||
+ if (g_path_is_absolute (subdir))
|
||||
+ {
|
||||
+ const char *skipped_prefix = subdir;
|
||||
+
|
||||
+ while (*skipped_prefix == '/')
|
||||
+ skipped_prefix++;
|
||||
+
|
||||
+ g_warning ("--persist=\"%s\" is deprecated, treating it as --persist=\"%s\"", subdir, skipped_prefix);
|
||||
+ subdir = skipped_prefix;
|
||||
+ }
|
||||
+
|
||||
+ g_autofree char *subdir_dirname = g_path_get_dirname (subdir);
|
||||
+
|
||||
+ if (strcmp (subdir_dirname, ".") == 0)
|
||||
+ {
|
||||
+ /* It is ok to open basedir with follow=true */
|
||||
+ if (!glnx_opendirat (base_fd, basedir, TRUE, &parent_fd, error))
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ else if (strcmp (subdir_dirname, "..") == 0)
|
||||
+ {
|
||||
+ return glnx_throw (error, "'..' not supported in --persist paths");
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (!mkdir_p_open_nofollow_at (base_fd, basedir, mode,
|
||||
+ subdir_dirname, &parent_fd, error))
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ g_autofree char *subdir_basename = g_path_get_basename (subdir);
|
||||
+
|
||||
+ if (strcmp (subdir_basename, ".") == 0)
|
||||
+ {
|
||||
+ *out_fd = glnx_steal_fd (&parent_fd);
|
||||
+ return TRUE;
|
||||
+ }
|
||||
+ else if (strcmp (subdir_basename, "..") == 0)
|
||||
+ {
|
||||
+ return glnx_throw (error, "'..' not supported in --persist paths");
|
||||
+ }
|
||||
+
|
||||
+ if (!glnx_shutil_mkdir_p_at (parent_fd, subdir_basename, mode, NULL, error))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ int fd = openat (parent_fd, subdir_basename, O_PATH | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC | O_NOCTTY | O_NOFOLLOW);
|
||||
+ if (fd == -1)
|
||||
+ {
|
||||
+ int saved_errno = errno;
|
||||
+ struct stat stat_buf;
|
||||
+
|
||||
+ /* If it's a symbolic link, that could be a user trying to offload
|
||||
+ * large data to another filesystem, but it could equally well be
|
||||
+ * a malicious or compromised app trying to exploit GHSA-7hgv-f2j8-xw87.
|
||||
+ * Produce a clearer error message in this case.
|
||||
+ * Unfortunately the errno we get in this case is ENOTDIR, so we have
|
||||
+ * to ask again to find out whether it's really a symlink. */
|
||||
+ if (saved_errno == ENOTDIR &&
|
||||
+ fstatat (parent_fd, subdir_basename, &stat_buf, AT_SYMLINK_NOFOLLOW) == 0 &&
|
||||
+ S_ISLNK (stat_buf.st_mode))
|
||||
+ return glnx_throw (error, "Symbolic link \"%s\" not allowed to avoid sandbox escape", subdir_basename);
|
||||
+
|
||||
+ return glnx_throw_errno_prefix (error, "openat(%s)", subdir_basename);
|
||||
+ }
|
||||
+
|
||||
+ *out_fd = fd;
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
void
|
||||
flatpak_context_append_bwrap_filesystem (FlatpakContext *context,
|
||||
FlatpakBwrap *bwrap,
|
||||
@@ -2643,12 +2727,31 @@ flatpak_context_append_bwrap_filesystem (FlatpakContext *context,
|
||||
while (g_hash_table_iter_next (&iter, &key, NULL))
|
||||
{
|
||||
const char *persist = key;
|
||||
- g_autofree char *src = g_build_filename (g_get_home_dir (), ".var/app", app_id, persist, NULL);
|
||||
+ g_autofree char *appdir = g_build_filename (g_get_home_dir (), ".var/app", app_id, NULL);
|
||||
g_autofree char *dest = g_build_filename (g_get_home_dir (), persist, NULL);
|
||||
|
||||
- g_mkdir_with_parents (src, 0755);
|
||||
+ g_autoptr(GError) local_error = NULL;
|
||||
+
|
||||
+ if (g_mkdir_with_parents (appdir, 0755) != 0)
|
||||
+ {
|
||||
+ g_warning ("Unable to create directory %s", appdir);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* Don't follow symlinks from the persist directory, as it is under user control */
|
||||
+ glnx_autofd int src_fd = -1;
|
||||
+ if (!mkdir_p_open_nofollow_at (AT_FDCWD, appdir, 0755,
|
||||
+ persist, &src_fd,
|
||||
+ &local_error))
|
||||
+ {
|
||||
+ g_warning ("Failed to create persist path %s: %s", persist, local_error->message);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ g_autofree char *src_via_proc = g_strdup_printf ("%d", src_fd);
|
||||
|
||||
- flatpak_bwrap_add_bind_arg (bwrap, "--bind", src, dest);
|
||||
+ flatpak_bwrap_add_fd (bwrap, glnx_steal_fd (&src_fd));
|
||||
+ flatpak_bwrap_add_bind_arg (bwrap, "--bind-fd", src_via_proc, dest);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 8bf37b0..0862ae5 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -175,6 +175,9 @@ if test "x$BWRAP" != xfalse; then
|
||||
BWRAP_VERSION=`$BWRAP --version | sed 's,.*\ \([0-9]*\.[0-9]*\.[0-9]*\)$,\1,'`
|
||||
AX_COMPARE_VERSION([$SYSTEM_BWRAP_REQS],[gt],[$BWRAP_VERSION],
|
||||
[AC_MSG_ERROR([You need at least version $SYSTEM_BWRAP_REQS of bubblewrap to use the system installed version])])
|
||||
+ AS_IF([$BWRAP --help | grep '@<:@-@:>@-bind-fd' >/dev/null],
|
||||
+ [:],
|
||||
+ [AC_MSG_ERROR([$BWRAP does not list required option --bind-fd in its --help])])
|
||||
AM_CONDITIONAL([WITH_SYSTEM_BWRAP], [true])
|
||||
else
|
||||
AC_CHECK_LIB(cap, cap_from_text, CAP_LIB=-lcap)
|
||||
diff --git a/tests/test-run.sh b/tests/test-run.sh
|
||||
index 3c344df..f087ff2 100644
|
||||
--- a/tests/test-run.sh
|
||||
+++ b/tests/test-run.sh
|
||||
@@ -494,3 +494,42 @@ ${FLATPAK} ${U} info -m org.test.App > out
|
||||
assert_file_has_content out "^sdk=org\.test\.Sdk/$(flatpak --default-arch)/stable$"
|
||||
|
||||
ok "--sdk option"
|
||||
+
|
||||
+rm -fr "$HOME/.var/app/org.test.Hello"
|
||||
+mkdir -p "$HOME/.var/app/org.test.Hello"
|
||||
+run --command=sh --persist=.persist org.test.Hello -c 'echo can-persist > .persist/rc'
|
||||
+sed -e 's,^,#--persist=.persist# ,g' < "$HOME/.var/app/org.test.Hello/.persist/rc" >&2
|
||||
+assert_file_has_content "$HOME/.var/app/org.test.Hello/.persist/rc" "can-persist"
|
||||
+
|
||||
+ok "--persist=.persist persists a directory"
|
||||
+
|
||||
+rm -fr "$HOME/.var/app/org.test.Hello"
|
||||
+mkdir -p "$HOME/.var/app/org.test.Hello"
|
||||
+# G_DEBUG= to avoid the deprecation warning being fatal
|
||||
+G_DEBUG= run --command=sh --persist=/.persist org.test.Hello -c 'echo can-persist > .persist/rc'
|
||||
+sed -e 's,^,#--persist=/.persist# ,g' < "$HOME/.var/app/org.test.Hello/.persist/rc" >&2
|
||||
+assert_file_has_content "$HOME/.var/app/org.test.Hello/.persist/rc" "can-persist"
|
||||
+
|
||||
+ok "--persist=/.persist is a deprecated form of --persist=.persist"
|
||||
+
|
||||
+rm -fr "$HOME/.var/app/org.test.Hello"
|
||||
+mkdir -p "$HOME/.var/app/org.test.Hello"
|
||||
+run --command=sh --persist=. org.test.Hello -c 'echo can-persist > .persistrc'
|
||||
+sed -e 's,^,#--persist=.# ,g' < "$HOME/.var/app/org.test.Hello/.persistrc" >&2
|
||||
+assert_file_has_content "$HOME/.var/app/org.test.Hello/.persistrc" "can-persist"
|
||||
+
|
||||
+ok "--persist=. persists all files"
|
||||
+
|
||||
+mkdir "${TEST_DATA_DIR}/inaccessible"
|
||||
+echo FOO > ${TEST_DATA_DIR}/inaccessible/secret-file
|
||||
+rm -fr "$HOME/.var/app/org.test.Hello"
|
||||
+mkdir -p "$HOME/.var/app/org.test.Hello"
|
||||
+ln -fns "${TEST_DATA_DIR}/inaccessible" "$HOME/.var/app/org.test.Hello/persist"
|
||||
+# G_DEBUG= to avoid the warnings being fatal when we reject a --persist option.
|
||||
+# LC_ALL=C so we get the expected non-localized string.
|
||||
+LC_ALL=C G_DEBUG= run --command=ls --persist=persist --persist=relative/../escape org.test.Hello -la ~/persist &> hello_out || true
|
||||
+sed -e 's,^,#--persist=symlink# ,g' < hello_out >&2
|
||||
+assert_file_has_content hello_out "not allowed to avoid sandbox escape"
|
||||
+assert_not_file_has_content hello_out "secret-file"
|
||||
+
|
||||
+ok "--persist doesn't allow sandbox escape via a symlink (CVE-2024-42472)"
|
||||
--
|
||||
2.33.0
|
||||
|
||||
210
backport-0001-CVE-2021-43860.patch
Normal file
210
backport-0001-CVE-2021-43860.patch
Normal file
@ -0,0 +1,210 @@
|
||||
From 54ec1a482dfc668127eaae57f135e6a8e0bc52da Mon Sep 17 00:00:00 2001
|
||||
From: Phaedrus Leeds <mwleeds@protonmail.com>
|
||||
Date: Tue, 28 Dec 2021 11:48:16 -0800
|
||||
Subject: [PATCH] Add test for metadata validation
|
||||
|
||||
This tests for invalid metadata, missing xa.metadata and mismatched
|
||||
values in xa.metadata and the real metadata, including the embedded
|
||||
null leading to the hidden permissions of CVE-2021-43860.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/flatpak/flatpak/commit/54ec1a482dfc668127eaae57f135e6a8e0bc52da
|
||||
|
||||
---
|
||||
tests/Makefile-test-matrix.am.inc | 1 +
|
||||
tests/Makefile.am.inc | 1 +
|
||||
tests/test-metadata-validation.sh | 158 ++++++++++++++++++++++++++++++
|
||||
3 files changed, 160 insertions(+)
|
||||
create mode 100644 tests/test-metadata-validation.sh
|
||||
|
||||
diff --git a/tests/Makefile-test-matrix.am.inc b/tests/Makefile-test-matrix.am.inc
|
||||
index 30b402d..eef5a7e 100644
|
||||
--- a/tests/Makefile-test-matrix.am.inc
|
||||
+++ b/tests/Makefile-test-matrix.am.inc
|
||||
@@ -36,6 +36,7 @@ TEST_MATRIX_DIST= \
|
||||
tests/test-build-update-repo.sh \
|
||||
tests/test-http-utils.sh \
|
||||
tests/test-default-remotes.sh \
|
||||
+ tests/test-metadata-validation.sh \
|
||||
tests/test-extensions.sh \
|
||||
tests/test-oci.sh \
|
||||
tests/test-override.sh \
|
||||
diff --git a/tests/Makefile.am.inc b/tests/Makefile.am.inc
|
||||
index 2458445..53d6403 100644
|
||||
--- a/tests/Makefile.am.inc
|
||||
+++ b/tests/Makefile.am.inc
|
||||
@@ -216,6 +216,7 @@ TEST_MATRIX_SOURCE = \
|
||||
tests/test-repo.sh{{user+system+system-norevokefs}+{{user+system},oldsummary}} \
|
||||
tests/test-sideload.sh{user+system} \
|
||||
tests/test-default-remotes.sh \
|
||||
+ tests/test-metadata-validation.sh \
|
||||
tests/test-extensions.sh \
|
||||
tests/test-bundle.sh{user+system+system-norevokefs} \
|
||||
tests/test-oci.sh \
|
||||
diff --git a/tests/test-metadata-validation.sh b/tests/test-metadata-validation.sh
|
||||
new file mode 100644
|
||||
index 0000000..7e3efcc
|
||||
--- /dev/null
|
||||
+++ b/tests/test-metadata-validation.sh
|
||||
@@ -0,0 +1,158 @@
|
||||
+#!/bin/bash
|
||||
+#
|
||||
+# Copyright (C) 2021 Matthew Leeds <mwleeds@protonmail.com>
|
||||
+#
|
||||
+# SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
+
|
||||
+set -euo pipefail
|
||||
+
|
||||
+. $(dirname $0)/libtest.sh
|
||||
+
|
||||
+echo "1..7"
|
||||
+
|
||||
+setup_repo
|
||||
+
|
||||
+COUNTER=1
|
||||
+
|
||||
+create_app () {
|
||||
+ local OPTIONS="$1"
|
||||
+ local DIR=`mktemp -d`
|
||||
+
|
||||
+ mkdir ${DIR}/files
|
||||
+ echo $COUNTER > ${DIR}/files/counter
|
||||
+ let COUNTER=COUNTER+1
|
||||
+
|
||||
+ local INVALID=""
|
||||
+ if [[ $OPTIONS =~ "invalid" ]]; then
|
||||
+ INVALID=invalidkeyfileline
|
||||
+ fi
|
||||
+ cat > ${DIR}/metadata <<EOF
|
||||
+[Application]
|
||||
+name=org.test.Malicious
|
||||
+runtime=org.test.Platform/${ARCH}/master
|
||||
+$INVALID
|
||||
+
|
||||
+[Context]
|
||||
+EOF
|
||||
+ if [[ $OPTIONS =~ "mismatch" ]]; then
|
||||
+ echo -e "filesystems=host;" >> ${DIR}/metadata
|
||||
+ fi
|
||||
+ if [[ $OPTIONS =~ "hidden" ]]; then
|
||||
+ echo -ne "\0" >> ${DIR}/metadata
|
||||
+ echo -e "\nfilesystems=home;" >> ${DIR}/metadata
|
||||
+ fi
|
||||
+ local XA_METADATA=--add-metadata-string=xa.metadata="$(head -n6 ${DIR}/metadata)"$'\n'
|
||||
+ if [[ $OPTIONS =~ "no-xametadata" ]]; then
|
||||
+ XA_METADATA="--add-metadata-string=xa.nometadata=1"
|
||||
+ fi
|
||||
+ ostree commit --repo=repos/test --branch=app/org.test.Malicious/${ARCH}/master ${FL_GPGARGS} "$XA_METADATA" ${DIR}/
|
||||
+ if [[ $OPTIONS =~ "no-cache-in-summary" ]]; then
|
||||
+ ostree --repo=repos/test ${FL_GPGARGS} summary -u
|
||||
+ # force use of legacy summary format
|
||||
+ rm -rf repos/test/summary.idx repos/test/summaries
|
||||
+ else
|
||||
+ update_repo
|
||||
+ fi
|
||||
+ rm -rf ${DIR}
|
||||
+}
|
||||
+
|
||||
+cleanup_repo () {
|
||||
+ ostree refs --repo=repos/test --delete app/org.test.Malicious/${ARCH}/master
|
||||
+ update_repo
|
||||
+}
|
||||
+
|
||||
+create_app "hidden"
|
||||
+
|
||||
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
|
||||
+ assert_not_reached "Should not be able to install app with hidden permissions"
|
||||
+fi
|
||||
+
|
||||
+assert_file_has_content install-error-log "not matching expected metadata"
|
||||
+
|
||||
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
|
||||
+
|
||||
+cleanup_repo
|
||||
+
|
||||
+ok "app with hidden permissions can't be installed (CVE-2021-43860)"
|
||||
+
|
||||
+create_app no-xametadata
|
||||
+
|
||||
+# The install will fail because the metadata in the summary doesn't match the metadata on the commit
|
||||
+# The missing xa.metadata in the commit got turned into "" in the xa.cache
|
||||
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
|
||||
+ assert_not_reached "Should not be able to install app with missing xa.metadata"
|
||||
+fi
|
||||
+
|
||||
+assert_file_has_content install-error-log "not matching expected metadata"
|
||||
+
|
||||
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
|
||||
+
|
||||
+cleanup_repo
|
||||
+
|
||||
+ok "app with no xa.metadata can't be installed"
|
||||
+
|
||||
+create_app "no-xametadata no-cache-in-summary"
|
||||
+
|
||||
+# The install will fail because there's no metadata in the summary or on the commit
|
||||
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
|
||||
+ assert_not_reached "Should not be able to install app with missing metadata"
|
||||
+fi
|
||||
+assert_file_has_content install-error-log "No xa.metadata in local commit"
|
||||
+
|
||||
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
|
||||
+
|
||||
+cleanup_repo
|
||||
+
|
||||
+ok "app with no xa.metadata and no metadata in summary can't be installed"
|
||||
+
|
||||
+create_app "invalid"
|
||||
+
|
||||
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
|
||||
+ assert_not_reached "Should not be able to install app with invalid metadata"
|
||||
+fi
|
||||
+assert_file_has_content install-error-log "Metadata for .* is invalid"
|
||||
+
|
||||
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
|
||||
+
|
||||
+cleanup_repo
|
||||
+
|
||||
+ok "app with invalid metadata (in summary) can't be installed"
|
||||
+
|
||||
+create_app "invalid no-cache-in-summary"
|
||||
+
|
||||
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
|
||||
+ assert_not_reached "Should not be able to install app with invalid metadata"
|
||||
+fi
|
||||
+assert_file_has_content install-error-log "Metadata for .* is invalid"
|
||||
+
|
||||
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
|
||||
+
|
||||
+cleanup_repo
|
||||
+
|
||||
+ok "app with invalid metadata (in commit) can't be installed"
|
||||
+
|
||||
+create_app "mismatch no-cache-in-summary"
|
||||
+
|
||||
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
|
||||
+ assert_not_reached "Should not be able to install app with non-matching metadata"
|
||||
+fi
|
||||
+assert_file_has_content install-error-log "Commit metadata for .* not matching expected metadata"
|
||||
+
|
||||
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
|
||||
+
|
||||
+cleanup_repo
|
||||
+
|
||||
+ok "app with mismatched metadata (in commit) can't be installed"
|
||||
+
|
||||
+create_app "mismatch"
|
||||
+
|
||||
+if ${FLATPAK} ${U} install -y test-repo org.test.Malicious 2>install-error-log; then
|
||||
+ assert_not_reached "Should not be able to install app with non-matching metadata"
|
||||
+fi
|
||||
+assert_file_has_content install-error-log "Commit metadata for .* not matching expected metadata"
|
||||
+
|
||||
+assert_not_has_dir $FL_DIR/app/org.test.Malicious/current/active
|
||||
+
|
||||
+cleanup_repo
|
||||
+
|
||||
+ok "app with mismatched metadata (in summary) can't be installed"
|
||||
--
|
||||
2.27.0
|
||||
|
||||
36
backport-0002-CVE-2021-43860.patch
Normal file
36
backport-0002-CVE-2021-43860.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From 65cbfac982cb1c83993a9e19aa424daee8e9f042 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Larsson <alexl@redhat.com>
|
||||
Date: Wed, 12 Jan 2022 11:00:56 +0100
|
||||
Subject: [PATCH] Ensure that bundles have metadata on install
|
||||
|
||||
If we have a bundle without metadata we wouldn't properly present
|
||||
the permissions in the transaction.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/flatpak/flatpak/commit/65cbfac982cb1c83993a9e19aa424daee8e9f042
|
||||
|
||||
---
|
||||
common/flatpak-dir.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
|
||||
index 94a86f4..ddc5ee9 100644
|
||||
--- a/common/flatpak-dir.c
|
||||
+++ b/common/flatpak-dir.c
|
||||
@@ -9295,6 +9295,13 @@ flatpak_dir_ensure_bundle_remote (FlatpakDir *self,
|
||||
if (metadata == NULL)
|
||||
return NULL;
|
||||
|
||||
+ /* If we rely on metadata (to e.g. print permissions), check it exists before creating the remote */
|
||||
+ if (out_metadata && fp_metadata == NULL)
|
||||
+ {
|
||||
+ flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA, "No metadata in bundler header");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
gpg_data = extra_gpg_data ? extra_gpg_data : included_gpg_data;
|
||||
|
||||
deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY, cancellable, NULL);
|
||||
--
|
||||
2.27.0
|
||||
|
||||
210
backport-0003-CVE-2021-43860.patch
Normal file
210
backport-0003-CVE-2021-43860.patch
Normal file
@ -0,0 +1,210 @@
|
||||
From ba818f504c926baaf6e362be8159cfacf994310e Mon Sep 17 00:00:00 2001
|
||||
From: Ryan Gonzalez <ryan.gonzalez@collabora.com>
|
||||
Date: Thu, 23 Dec 2021 18:30:17 -0600
|
||||
Subject: [PATCH] Fix metadata file contents after null terminators being
|
||||
ignored
|
||||
|
||||
In particular, if a null terminator is placed inside the metadata file,
|
||||
Flatpak will only compare the text *before* it to the value of
|
||||
xa.metadata, but the full file will be parsed when permissions are set
|
||||
at runtime. This means that any app can include a null terminator in its
|
||||
permissions metadata, and Flatpak will only show the user the
|
||||
permissions *preceding* the terminator during install, but the
|
||||
permissions *after* the terminator are applied at runtime.
|
||||
|
||||
Fixes GHSA-qpjc-vq3c-572j / CVE-2021-43860
|
||||
|
||||
Signed-off-by: Ryan Gonzalez <ryan.gonzalez@collabora.com>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/flatpak/flatpak/commit/ba818f504c926baaf6e362be8159cfacf994310e
|
||||
|
||||
---
|
||||
common/flatpak-dir.c | 36 +++++++++++++++++++++++++++---------
|
||||
common/flatpak-transaction.c | 8 ++++----
|
||||
common/flatpak-utils.c | 9 +++++----
|
||||
3 files changed, 36 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
|
||||
index ddc5ee9..e6c8046 100644
|
||||
--- a/common/flatpak-dir.c
|
||||
+++ b/common/flatpak-dir.c
|
||||
@@ -1762,19 +1762,29 @@ static gboolean
|
||||
validate_commit_metadata (GVariant *commit_data,
|
||||
const char *ref,
|
||||
const char *required_metadata,
|
||||
+ gsize required_metadata_size,
|
||||
gboolean require_xa_metadata,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GVariant) commit_metadata = NULL;
|
||||
+ g_autoptr(GVariant) xa_metadata_v = NULL;
|
||||
const char *xa_metadata = NULL;
|
||||
+ gsize xa_metadata_size = 0;
|
||||
|
||||
commit_metadata = g_variant_get_child_value (commit_data, 0);
|
||||
|
||||
if (commit_metadata != NULL)
|
||||
- g_variant_lookup (commit_metadata, "xa.metadata", "&s", &xa_metadata);
|
||||
+ {
|
||||
+ xa_metadata_v = g_variant_lookup_value (commit_metadata,
|
||||
+ "xa.metadata",
|
||||
+ G_VARIANT_TYPE_STRING);
|
||||
+ if (xa_metadata_v)
|
||||
+ xa_metadata = g_variant_get_string (xa_metadata_v, &xa_metadata_size);
|
||||
+ }
|
||||
|
||||
if ((xa_metadata == NULL && require_xa_metadata) ||
|
||||
- (xa_metadata != NULL && g_strcmp0 (required_metadata, xa_metadata) != 0))
|
||||
+ (xa_metadata != NULL && (xa_metadata_size != required_metadata_size ||
|
||||
+ memcmp (xa_metadata, required_metadata, xa_metadata_size) != 0)))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
|
||||
_("Commit metadata for %s not matching expected metadata"), ref);
|
||||
@@ -3478,6 +3488,7 @@ upgrade_deploy_data (GBytes *deploy_data,
|
||||
g_autoptr(GKeyFile) keyfile = NULL;
|
||||
g_autoptr(GFile) metadata_file = NULL;
|
||||
g_autofree char *metadata_contents = NULL;
|
||||
+ gsize metadata_size = 0;
|
||||
g_autofree char *id = flatpak_decomposed_dup_id (ref);
|
||||
|
||||
/* Add fields from commit metadata to deploy */
|
||||
@@ -3491,9 +3502,9 @@ upgrade_deploy_data (GBytes *deploy_data,
|
||||
keyfile = g_key_file_new ();
|
||||
metadata_file = g_file_resolve_relative_path (deploy_dir, "metadata");
|
||||
if (!g_file_load_contents (metadata_file, cancellable,
|
||||
- &metadata_contents, NULL, NULL, error))
|
||||
+ &metadata_contents, &metadata_size, NULL, error))
|
||||
return NULL;
|
||||
- if (!g_key_file_load_from_data (keyfile, metadata_contents, -1, 0, error))
|
||||
+ if (!g_key_file_load_from_data (keyfile, metadata_contents, metadata_size, 0, error))
|
||||
return NULL;
|
||||
add_metadata_to_deploy_data (&metadata_dict, keyfile);
|
||||
|
||||
@@ -5799,8 +5810,13 @@ flatpak_dir_pull (FlatpakDir *self,
|
||||
{
|
||||
g_autoptr(GVariant) commit_data = NULL;
|
||||
if (!ostree_repo_load_commit (repo, rev, &commit_data, NULL, error) ||
|
||||
- !validate_commit_metadata (commit_data, ref, (const char *)g_bytes_get_data (require_metadata, NULL), TRUE, error))
|
||||
- return FALSE;
|
||||
+ !validate_commit_metadata (commit_data,
|
||||
+ ref,
|
||||
+ (const char *)g_bytes_get_data (require_metadata, NULL),
|
||||
+ g_bytes_get_size (require_metadata),
|
||||
+ TRUE,
|
||||
+ error))
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (!flatpak_dir_pull_extra_data (self, repo,
|
||||
@@ -8111,6 +8127,7 @@ flatpak_dir_deploy (FlatpakDir *self,
|
||||
g_auto(GLnxLockFile) lock = { 0, };
|
||||
g_autoptr(GFile) metadata_file = NULL;
|
||||
g_autofree char *metadata_contents = NULL;
|
||||
+ gsize metadata_size = 0;
|
||||
gboolean is_oci;
|
||||
|
||||
if (!flatpak_dir_ensure_repo (self, cancellable, error))
|
||||
@@ -8320,11 +8337,12 @@ flatpak_dir_deploy (FlatpakDir *self,
|
||||
keyfile = g_key_file_new ();
|
||||
metadata_file = g_file_resolve_relative_path (checkoutdir, "metadata");
|
||||
if (g_file_load_contents (metadata_file, NULL,
|
||||
- &metadata_contents, NULL, NULL, NULL))
|
||||
+ &metadata_contents,
|
||||
+ &metadata_size, NULL, NULL))
|
||||
{
|
||||
if (!g_key_file_load_from_data (keyfile,
|
||||
metadata_contents,
|
||||
- -1,
|
||||
+ metadata_size,
|
||||
0, error))
|
||||
return FALSE;
|
||||
|
||||
@@ -8340,7 +8358,7 @@ flatpak_dir_deploy (FlatpakDir *self,
|
||||
*/
|
||||
is_oci = flatpak_dir_get_remote_oci (self, origin);
|
||||
if (!validate_commit_metadata (commit_data, flatpak_decomposed_get_ref (ref),
|
||||
- metadata_contents, !is_oci, error))
|
||||
+ metadata_contents, metadata_size, !is_oci, error))
|
||||
return FALSE;
|
||||
|
||||
dotref = g_file_resolve_relative_path (checkoutdir, "files/.ref");
|
||||
diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c
|
||||
index 1927498..721da14 100644
|
||||
--- a/common/flatpak-transaction.c
|
||||
+++ b/common/flatpak-transaction.c
|
||||
@@ -2520,7 +2520,7 @@ flatpak_transaction_add_ref (FlatpakTransaction *self,
|
||||
return FALSE;
|
||||
|
||||
if (external_metadata)
|
||||
- op->external_metadata = g_bytes_new (external_metadata, strlen (external_metadata) + 1);
|
||||
+ op->external_metadata = g_bytes_new (external_metadata, strlen (external_metadata));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -2937,7 +2937,7 @@ load_deployed_metadata (FlatpakTransaction *self, FlatpakDecomposed *ref, char *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- return g_bytes_new_take (g_steal_pointer (&metadata_contents), metadata_contents_length + 1);
|
||||
+ return g_bytes_new_take (g_steal_pointer (&metadata_contents), metadata_contents_length);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -3034,7 +3034,7 @@ resolve_op_from_commit (FlatpakTransaction *self,
|
||||
if (xa_metadata == NULL)
|
||||
g_message ("Warning: No xa.metadata in local commit %s ref %s", checksum, flatpak_decomposed_get_ref (op->ref));
|
||||
else
|
||||
- metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata) + 1);
|
||||
+ metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata));
|
||||
|
||||
if (g_variant_lookup (commit_metadata, "xa.download-size", "t", &download_size))
|
||||
op->download_size = GUINT64_FROM_BE (download_size);
|
||||
@@ -3074,7 +3074,7 @@ try_resolve_op_from_metadata (FlatpakTransaction *self,
|
||||
&download_size, &installed_size, &metadata, NULL))
|
||||
return FALSE;
|
||||
|
||||
- metadata_bytes = g_bytes_new (metadata, strlen (metadata) + 1);
|
||||
+ metadata_bytes = g_bytes_new (metadata, strlen (metadata));
|
||||
|
||||
if (flatpak_remote_state_lookup_ref (state, flatpak_decomposed_get_ref (op->ref),
|
||||
NULL, NULL, &info, NULL, NULL))
|
||||
diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c
|
||||
index 6901a62..9eedbfa 100644
|
||||
--- a/common/flatpak-utils.c
|
||||
+++ b/common/flatpak-utils.c
|
||||
@@ -6604,6 +6604,7 @@ flatpak_pull_from_bundle (OstreeRepo *repo,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
+ gsize metadata_size = 0;
|
||||
g_autofree char *metadata_contents = NULL;
|
||||
g_autofree char *to_checksum = NULL;
|
||||
g_autoptr(GFile) root = NULL;
|
||||
@@ -6620,6 +6621,8 @@ flatpak_pull_from_bundle (OstreeRepo *repo,
|
||||
if (metadata == NULL)
|
||||
return FALSE;
|
||||
|
||||
+ metadata_size = strlen (metadata_contents);
|
||||
+
|
||||
if (!ostree_repo_get_remote_option (repo, remote, "collection-id", NULL,
|
||||
&remote_collection_id, NULL))
|
||||
remote_collection_id = NULL;
|
||||
@@ -6689,12 +6692,10 @@ flatpak_pull_from_bundle (OstreeRepo *repo,
|
||||
cancellable, error) < 0)
|
||||
return FALSE;
|
||||
|
||||
- /* Null terminate */
|
||||
- g_output_stream_write (G_OUTPUT_STREAM (data_stream), "\0", 1, NULL, NULL);
|
||||
-
|
||||
metadata_valid =
|
||||
metadata_contents != NULL &&
|
||||
- strcmp (metadata_contents, g_memory_output_stream_get_data (data_stream)) == 0;
|
||||
+ metadata_size == g_memory_output_stream_get_data_size (data_stream) &&
|
||||
+ memcmp (metadata_contents, g_memory_output_stream_get_data (data_stream), metadata_size) == 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
--
|
||||
2.27.0
|
||||
|
||||
76
backport-0004-CVE-2021-43860.patch
Normal file
76
backport-0004-CVE-2021-43860.patch
Normal file
@ -0,0 +1,76 @@
|
||||
From 93357d357119093804df05acc32ff335839c6451 Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Larsson <alexl@redhat.com>
|
||||
Date: Tue, 11 Jan 2022 10:27:46 +0100
|
||||
Subject: [PATCH] Require metadata in commit also for OCI remotes
|
||||
|
||||
This was disables a long time ago because the fedora remotes didn't
|
||||
contain metadata, but that has been added since then. Requiring fixes
|
||||
a security concern where an app claims to require no permissions (by
|
||||
having no metadata in commit) but then actually requires permissions
|
||||
in the installed app.
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/flatpak/flatpak/commit/93357d357119093804df05acc32ff335839c6451
|
||||
|
||||
---
|
||||
common/flatpak-dir.c | 14 ++++----------
|
||||
1 file changed, 4 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c
|
||||
index e6c8046..e6a83cf 100644
|
||||
--- a/common/flatpak-dir.c
|
||||
+++ b/common/flatpak-dir.c
|
||||
@@ -1763,7 +1763,6 @@ validate_commit_metadata (GVariant *commit_data,
|
||||
const char *ref,
|
||||
const char *required_metadata,
|
||||
gsize required_metadata_size,
|
||||
- gboolean require_xa_metadata,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GVariant) commit_metadata = NULL;
|
||||
@@ -1782,9 +1781,9 @@ validate_commit_metadata (GVariant *commit_data,
|
||||
xa_metadata = g_variant_get_string (xa_metadata_v, &xa_metadata_size);
|
||||
}
|
||||
|
||||
- if ((xa_metadata == NULL && require_xa_metadata) ||
|
||||
- (xa_metadata != NULL && (xa_metadata_size != required_metadata_size ||
|
||||
- memcmp (xa_metadata, required_metadata, xa_metadata_size) != 0)))
|
||||
+ if (xa_metadata == NULL ||
|
||||
+ xa_metadata_size != required_metadata_size ||
|
||||
+ memcmp (xa_metadata, required_metadata, xa_metadata_size) != 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
|
||||
_("Commit metadata for %s not matching expected metadata"), ref);
|
||||
@@ -5814,7 +5813,6 @@ flatpak_dir_pull (FlatpakDir *self,
|
||||
ref,
|
||||
(const char *)g_bytes_get_data (require_metadata, NULL),
|
||||
g_bytes_get_size (require_metadata),
|
||||
- TRUE,
|
||||
error))
|
||||
goto out;
|
||||
}
|
||||
@@ -8128,7 +8126,6 @@ flatpak_dir_deploy (FlatpakDir *self,
|
||||
g_autoptr(GFile) metadata_file = NULL;
|
||||
g_autofree char *metadata_contents = NULL;
|
||||
gsize metadata_size = 0;
|
||||
- gboolean is_oci;
|
||||
|
||||
if (!flatpak_dir_ensure_repo (self, cancellable, error))
|
||||
return FALSE;
|
||||
@@ -8353,12 +8350,9 @@ flatpak_dir_deploy (FlatpakDir *self,
|
||||
/* Check the metadata in the commit to make sure it matches the actual
|
||||
* deployed metadata, in case we relied on the one in the commit for
|
||||
* a decision
|
||||
- * Note: For historical reason we don't enforce commits to contain xa.metadata
|
||||
- * since this was lacking in fedora builds.
|
||||
*/
|
||||
- is_oci = flatpak_dir_get_remote_oci (self, origin);
|
||||
if (!validate_commit_metadata (commit_data, flatpak_decomposed_get_ref (ref),
|
||||
- metadata_contents, metadata_size, !is_oci, error))
|
||||
+ metadata_contents, metadata_size, error))
|
||||
return FALSE;
|
||||
|
||||
dotref = g_file_resolve_relative_path (checkoutdir, "files/.ref");
|
||||
--
|
||||
2.27.0
|
||||
|
||||
239
backport-0005-CVE-2021-43860.patch
Normal file
239
backport-0005-CVE-2021-43860.patch
Normal file
@ -0,0 +1,239 @@
|
||||
From d9a8f9d8ccc0b7c1135d0ecde006a75d25f66aee Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Larsson <alexl@redhat.com>
|
||||
Date: Mon, 10 Jan 2022 16:43:08 +0100
|
||||
Subject: [PATCH] Transaction: Fail the resolve if xa.metadata invalid or
|
||||
missing
|
||||
|
||||
If we fail to parse xa.metadata from the summary cache or the commit
|
||||
xa.metadata we fail the resolve.
|
||||
|
||||
If xa.metadata is missing in the commit we fail the resolve (it is
|
||||
always set in the summary cache, because summary update converts
|
||||
missing xa.metadata to "", so we either get that, or cache miss which
|
||||
leads to resolving from the commit.
|
||||
|
||||
This means that op->resolved_metadata is always set during install and
|
||||
updates, which means we will show the app permissions. The transaction
|
||||
will also always make sure that this data actually matches what gets
|
||||
deployed.
|
||||
|
||||
Before this change an invalid metadata in the summary cache could lead
|
||||
to a NULL resolved_metadata, which means we wouldn't print the app
|
||||
permissions, yet we would still deploy some metadata file that could
|
||||
have permissions. (NOTE: It would fail to deploy unless the
|
||||
xa.metadata in the commit matched the metadata file, but in this
|
||||
corner case we would't compare the summary and commit metadata, so
|
||||
they may differ.)
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/flatpak/flatpak/commit/d9a8f9d8ccc0b7c1135d0ecde006a75d25f66aee
|
||||
|
||||
---
|
||||
common/flatpak-transaction.c | 84 +++++++++++++++++++++++-------------
|
||||
1 file changed, 55 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/common/flatpak-transaction.c b/common/flatpak-transaction.c
|
||||
index 721da14..b0908c3 100644
|
||||
--- a/common/flatpak-transaction.c
|
||||
+++ b/common/flatpak-transaction.c
|
||||
@@ -2957,12 +2957,13 @@ emit_eol_and_maybe_skip (FlatpakTransaction *self,
|
||||
g_signal_emit (self, signals[END_OF_LIFED_WITH_REBASE], 0, op->remote, flatpak_decomposed_get_ref (op->ref), op->eol, op->eol_rebase, previous_ids, &op->skip);
|
||||
}
|
||||
|
||||
-static void
|
||||
+static gboolean
|
||||
mark_op_resolved (FlatpakTransactionOperation *op,
|
||||
const char *commit,
|
||||
GFile *sideload_path,
|
||||
GBytes *metadata,
|
||||
- GBytes *old_metadata)
|
||||
+ GBytes *old_metadata,
|
||||
+ GError **error)
|
||||
{
|
||||
g_debug ("marking op %s:%s resolved to %s", kind_to_str (op->kind), flatpak_decomposed_get_ref (op->ref), commit ? commit : "-");
|
||||
|
||||
@@ -2980,13 +2981,12 @@ mark_op_resolved (FlatpakTransactionOperation *op,
|
||||
if (metadata)
|
||||
{
|
||||
g_autoptr(GKeyFile) metakey = g_key_file_new ();
|
||||
- if (g_key_file_load_from_bytes (metakey, metadata, G_KEY_FILE_NONE, NULL))
|
||||
- {
|
||||
- op->resolved_metadata = g_bytes_ref (metadata);
|
||||
- op->resolved_metakey = g_steal_pointer (&metakey);
|
||||
- }
|
||||
- else
|
||||
- g_message ("Warning: Failed to parse metadata for %s\n", flatpak_decomposed_get_ref (op->ref));
|
||||
+ if (!g_key_file_load_from_bytes (metakey, metadata, G_KEY_FILE_NONE, NULL))
|
||||
+ return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
|
||||
+ "Metadata for %s is invalid", flatpak_decomposed_get_ref (op->ref));
|
||||
+
|
||||
+ op->resolved_metadata = g_bytes_ref (metadata);
|
||||
+ op->resolved_metakey = g_steal_pointer (&metakey);
|
||||
}
|
||||
if (old_metadata)
|
||||
{
|
||||
@@ -2997,31 +2997,40 @@ mark_op_resolved (FlatpakTransactionOperation *op,
|
||||
op->resolved_old_metakey = g_steal_pointer (&metakey);
|
||||
}
|
||||
else
|
||||
- g_message ("Warning: Failed to parse old metadata for %s\n", flatpak_decomposed_get_ref (op->ref));
|
||||
+ {
|
||||
+ /* This shouldn't happen, but a NULL old metadata is safe (all permisssions are considered new) */
|
||||
+ g_message ("Warning: Failed to parse old metadata for %s\n", flatpak_decomposed_get_ref (op->ref));
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
-static void
|
||||
+static gboolean
|
||||
resolve_op_end (FlatpakTransaction *self,
|
||||
FlatpakTransactionOperation *op,
|
||||
const char *checksum,
|
||||
GFile *sideload_path,
|
||||
- GBytes *metadata_bytes)
|
||||
+ GBytes *metadata_bytes,
|
||||
+ GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) old_metadata_bytes = NULL;
|
||||
|
||||
old_metadata_bytes = load_deployed_metadata (self, op->ref, NULL, NULL);
|
||||
- mark_op_resolved (op, checksum, sideload_path, metadata_bytes, old_metadata_bytes);
|
||||
+ if (!mark_op_resolved (op, checksum, sideload_path, metadata_bytes, old_metadata_bytes, error))
|
||||
+ return FALSE;
|
||||
emit_eol_and_maybe_skip (self, op);
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
|
||||
-static void
|
||||
+static gboolean
|
||||
resolve_op_from_commit (FlatpakTransaction *self,
|
||||
FlatpakTransactionOperation *op,
|
||||
const char *checksum,
|
||||
GFile *sideload_path,
|
||||
- GVariant *commit_data)
|
||||
+ GVariant *commit_data,
|
||||
+ GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) metadata_bytes = NULL;
|
||||
g_autoptr(GVariant) commit_metadata = NULL;
|
||||
@@ -3032,9 +3041,11 @@ resolve_op_from_commit (FlatpakTransaction *self,
|
||||
commit_metadata = g_variant_get_child_value (commit_data, 0);
|
||||
g_variant_lookup (commit_metadata, "xa.metadata", "&s", &xa_metadata);
|
||||
if (xa_metadata == NULL)
|
||||
- g_message ("Warning: No xa.metadata in local commit %s ref %s", checksum, flatpak_decomposed_get_ref (op->ref));
|
||||
- else
|
||||
- metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata));
|
||||
+ return flatpak_fail_error (error, FLATPAK_ERROR_INVALID_DATA,
|
||||
+ "No xa.metadata in local commit %s ref %s",
|
||||
+ checksum, flatpak_decomposed_get_ref (op->ref));
|
||||
+
|
||||
+ metadata_bytes = g_bytes_new (xa_metadata, strlen (xa_metadata));
|
||||
|
||||
if (g_variant_lookup (commit_metadata, "xa.download-size", "t", &download_size))
|
||||
op->download_size = GUINT64_FROM_BE (download_size);
|
||||
@@ -3044,15 +3055,19 @@ resolve_op_from_commit (FlatpakTransaction *self,
|
||||
g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE, "s", &op->eol);
|
||||
g_variant_lookup (commit_metadata, OSTREE_COMMIT_META_KEY_ENDOFLIFE_REBASE, "s", &op->eol_rebase);
|
||||
|
||||
- resolve_op_end (self, op, checksum, sideload_path, metadata_bytes);
|
||||
+ return resolve_op_end (self, op, checksum, sideload_path, metadata_bytes, error);
|
||||
}
|
||||
|
||||
+/* NOTE: In case of non-available summary this returns FALSE with a
|
||||
+ * NULL error, but for other error cases it will be set.
|
||||
+ */
|
||||
static gboolean
|
||||
try_resolve_op_from_metadata (FlatpakTransaction *self,
|
||||
FlatpakTransactionOperation *op,
|
||||
const char *checksum,
|
||||
GFile *sideload_path,
|
||||
- FlatpakRemoteState *state)
|
||||
+ FlatpakRemoteState *state,
|
||||
+ GError **error)
|
||||
{
|
||||
g_autoptr(GBytes) metadata_bytes = NULL;
|
||||
guint64 download_size = 0;
|
||||
@@ -3092,8 +3107,7 @@ try_resolve_op_from_metadata (FlatpakTransaction *self,
|
||||
op->token_type = GINT32_FROM_LE (var_metadata_lookup_int32 (sparse_cache, FLATPAK_SPARSE_CACHE_KEY_TOKEN_TYPE, op->token_type));
|
||||
}
|
||||
|
||||
- resolve_op_end (self, op, checksum, sideload_path, metadata_bytes);
|
||||
- return TRUE;
|
||||
+ return resolve_op_end (self, op, checksum, sideload_path, metadata_bytes, error);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3136,7 +3150,8 @@ resolve_ops (FlatpakTransaction *self,
|
||||
* checksum we got was the version already installed.
|
||||
*/
|
||||
g_assert (op->resolved_commit != NULL);
|
||||
- mark_op_resolved (op, op->resolved_commit, NULL, NULL, NULL);
|
||||
+ if (!mark_op_resolved (op, op->resolved_commit, NULL, NULL, NULL, error))
|
||||
+ return FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3145,14 +3160,16 @@ resolve_ops (FlatpakTransaction *self,
|
||||
/* We resolve to the deployed metadata, because we need it to uninstall related ops */
|
||||
|
||||
metadata_bytes = load_deployed_metadata (self, op->ref, &checksum, NULL);
|
||||
- mark_op_resolved (op, checksum, NULL, metadata_bytes, NULL);
|
||||
+ if (!mark_op_resolved (op, checksum, NULL, metadata_bytes, NULL, error))
|
||||
+ return FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (op->kind == FLATPAK_TRANSACTION_OPERATION_INSTALL_BUNDLE)
|
||||
{
|
||||
g_assert (op->commit != NULL);
|
||||
- mark_op_resolved (op, op->commit, NULL, op->external_metadata, NULL);
|
||||
+ if (!mark_op_resolved (op, op->commit, NULL, op->external_metadata, NULL, error))
|
||||
+ return FALSE;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3183,7 +3200,8 @@ resolve_ops (FlatpakTransaction *self,
|
||||
if (commit_data == NULL)
|
||||
return FALSE;
|
||||
|
||||
- resolve_op_from_commit (self, op, checksum, NULL, commit_data);
|
||||
+ if (!resolve_op_from_commit (self, op, checksum, NULL, commit_data, error))
|
||||
+ return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3242,9 +3260,16 @@ resolve_ops (FlatpakTransaction *self,
|
||||
}
|
||||
|
||||
/* First try to resolve via metadata (if remote is available and its metadata matches the commit version) */
|
||||
- if (!try_resolve_op_from_metadata (self, op, checksum, sideload_path, state))
|
||||
+ if (!try_resolve_op_from_metadata (self, op, checksum, sideload_path, state, &local_error))
|
||||
{
|
||||
- /* Else try to load the commit object.
|
||||
+ if (local_error)
|
||||
+ {
|
||||
+ /* Actual error, not just missing from summary */
|
||||
+ g_propagate_error (error, g_steal_pointer (&local_error));
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* Missing from summary, try to load the commit object.
|
||||
* Note, we don't have a token here, so this will not work for authenticated apps.
|
||||
* We handle this by catching the 401 http status and retrying. */
|
||||
g_autoptr(GVariant) commit_data = NULL;
|
||||
@@ -3280,7 +3305,8 @@ resolve_ops (FlatpakTransaction *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- resolve_op_from_commit (self, op, checksum, sideload_path, commit_data);
|
||||
+ if (!resolve_op_from_commit (self, op, checksum, sideload_path, commit_data, error))
|
||||
+ return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.27.0
|
||||
|
||||
340
backport-CVE-2022-21682.patch
Normal file
340
backport-CVE-2022-21682.patch
Normal file
@ -0,0 +1,340 @@
|
||||
From 5709f1aaed6579f0136976e14e7f3cae399134ca Mon Sep 17 00:00:00 2001
|
||||
From: Simon McVittie <smcv@collabora.com>
|
||||
Date: Sun, 16 Jan 2022 12:42:30 +0000
|
||||
Subject: [PATCH] context: Introduce new --nofilesystem=host:reset
|
||||
|
||||
This reintroduces the special case that existed in Flatpak 1.12.3, but
|
||||
under a different name, so that it will be backwards-compatible. With
|
||||
this change, flatpak-builder will be able to resolve CVE-2022-21682 by
|
||||
using --filesystem=host:reset.
|
||||
|
||||
We want to implement this as a suffix rather than as a new keyword,
|
||||
because unknown suffixes are ignored with a warning, rather than causing
|
||||
a fatal error. This means that the new version of flatpak-builder will
|
||||
be able to run against older versions of flatpak: it will still be
|
||||
vulnerable to CVE-2022-21682 in that situation, but at least it will run.
|
||||
|
||||
Co-authored-by: Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
Conflict:NA
|
||||
Reference:https://github.com/flatpak/flatpak/commit/5709f1aaed6579f0136976e14e7f3cae399134ca
|
||||
---
|
||||
common/flatpak-context-private.h | 1 +
|
||||
common/flatpak-context.c | 166 ++++++++++++++++++++++++++++---
|
||||
2 files changed, 153 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/common/flatpak-context-private.h b/common/flatpak-context-private.h
|
||||
index 45879ac..b6b9e56 100644
|
||||
--- a/common/flatpak-context-private.h
|
||||
+++ b/common/flatpak-context-private.h
|
||||
@@ -83,6 +83,7 @@ extern const char *flatpak_context_features[];
|
||||
extern const char *flatpak_context_shares[];
|
||||
|
||||
gboolean flatpak_context_parse_filesystem (const char *filesystem_and_mode,
|
||||
+ gboolean negated,
|
||||
char **filesystem_out,
|
||||
FlatpakFilesystemMode *mode_out,
|
||||
GError **error);
|
||||
diff --git a/common/flatpak-context.c b/common/flatpak-context.c
|
||||
index abeda35..a7cd891 100644
|
||||
--- a/common/flatpak-context.c
|
||||
+++ b/common/flatpak-context.c
|
||||
@@ -86,6 +86,7 @@ const char *flatpak_context_special_filesystems[] = {
|
||||
"host",
|
||||
"host-etc",
|
||||
"host-os",
|
||||
+ "host-reset",
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -703,6 +704,12 @@ unparse_filesystem_flags (const char *path,
|
||||
|
||||
case FLATPAK_FILESYSTEM_MODE_NONE:
|
||||
g_string_insert_c (s, 0, '!');
|
||||
+
|
||||
+ if (g_str_has_suffix (s->str, "-reset"))
|
||||
+ {
|
||||
+ g_string_truncate (s, s->len - 6);
|
||||
+ g_string_append (s, ":reset");
|
||||
+ }
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -715,11 +722,14 @@ unparse_filesystem_flags (const char *path,
|
||||
|
||||
static char *
|
||||
parse_filesystem_flags (const char *filesystem,
|
||||
- FlatpakFilesystemMode *mode_out)
|
||||
+ gboolean negated,
|
||||
+ FlatpakFilesystemMode *mode_out,
|
||||
+ GError **error)
|
||||
{
|
||||
g_autoptr(GString) s = g_string_new ("");
|
||||
const char *p, *suffix;
|
||||
FlatpakFilesystemMode mode;
|
||||
+ gboolean reset = FALSE;
|
||||
|
||||
p = filesystem;
|
||||
while (*p != 0 && *p != ':')
|
||||
@@ -734,7 +744,31 @@ parse_filesystem_flags (const char *filesystem,
|
||||
g_string_append_c (s, *p++);
|
||||
}
|
||||
|
||||
- mode = FLATPAK_FILESYSTEM_MODE_READ_WRITE;
|
||||
+ if (negated)
|
||||
+ mode = FLATPAK_FILESYSTEM_MODE_NONE;
|
||||
+ else
|
||||
+ mode = FLATPAK_FILESYSTEM_MODE_READ_WRITE;
|
||||
+
|
||||
+ if (g_str_equal (s->str, "host-reset"))
|
||||
+ {
|
||||
+ reset = TRUE;
|
||||
+
|
||||
+ if (!negated)
|
||||
+ {
|
||||
+ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
|
||||
+ "Filesystem token \"%s\" is only applicable for --nofilesystem",
|
||||
+ s->str);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (*p != '\0')
|
||||
+ {
|
||||
+ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
|
||||
+ "Filesystem token \"%s\" cannot be used with a suffix",
|
||||
+ s->str);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (*p == ':')
|
||||
{
|
||||
@@ -746,10 +780,63 @@ parse_filesystem_flags (const char *filesystem,
|
||||
mode = FLATPAK_FILESYSTEM_MODE_READ_WRITE;
|
||||
else if (strcmp (suffix, "create") == 0)
|
||||
mode = FLATPAK_FILESYSTEM_MODE_CREATE;
|
||||
+ else if (strcmp (suffix, "reset") == 0)
|
||||
+ reset = TRUE;
|
||||
else if (*suffix != 0)
|
||||
g_warning ("Unexpected filesystem suffix %s, ignoring", suffix);
|
||||
+
|
||||
+ if (negated && mode != FLATPAK_FILESYSTEM_MODE_NONE)
|
||||
+ {
|
||||
+ g_warning ("Filesystem suffix \"%s\" is not applicable for --nofilesystem",
|
||||
+ suffix);
|
||||
+ mode = FLATPAK_FILESYSTEM_MODE_NONE;
|
||||
+ }
|
||||
+
|
||||
+ if (reset)
|
||||
+ {
|
||||
+ if (!negated)
|
||||
+ {
|
||||
+ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
|
||||
+ "Filesystem suffix \"%s\" only applies to --nofilesystem",
|
||||
+ suffix);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (!g_str_equal (s->str, "host"))
|
||||
+ {
|
||||
+ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
|
||||
+ "Filesystem suffix \"%s\" can only be applied to "
|
||||
+ "--nofilesystem=host",
|
||||
+ suffix);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* We internally handle host:reset (etc) as host-reset, only exposing it as a flag in the public
|
||||
+ part to allow it to be ignored (with a warning) for old flatpak versions */
|
||||
+ g_string_append (s, "-reset");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* Postcondition check: the code above should make some results
|
||||
+ * impossible */
|
||||
+ if (negated)
|
||||
+ {
|
||||
+ g_assert (mode == FLATPAK_FILESYSTEM_MODE_NONE);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ g_assert (mode > FLATPAK_FILESYSTEM_MODE_NONE);
|
||||
+ /* This flag is only applicable to --nofilesystem */
|
||||
+ g_assert (!reset);
|
||||
}
|
||||
|
||||
+ /* Postcondition check: filesystem token is host-reset iff reset flag
|
||||
+ * was found */
|
||||
+ if (reset)
|
||||
+ g_assert (g_str_equal (s->str, "host-reset"));
|
||||
+ else
|
||||
+ g_assert (!g_str_equal (s->str, "host-reset"));
|
||||
+
|
||||
if (mode_out)
|
||||
*mode_out = mode;
|
||||
|
||||
@@ -758,13 +845,18 @@ parse_filesystem_flags (const char *filesystem,
|
||||
|
||||
gboolean
|
||||
flatpak_context_parse_filesystem (const char *filesystem_and_mode,
|
||||
+ gboolean negated,
|
||||
char **filesystem_out,
|
||||
FlatpakFilesystemMode *mode_out,
|
||||
GError **error)
|
||||
{
|
||||
- g_autofree char *filesystem = parse_filesystem_flags (filesystem_and_mode, mode_out);
|
||||
+ g_autofree char *filesystem = NULL;
|
||||
char *slash;
|
||||
|
||||
+ filesystem = parse_filesystem_flags (filesystem_and_mode, negated, mode_out, error);
|
||||
+ if (filesystem == NULL)
|
||||
+ return FALSE;
|
||||
+
|
||||
slash = strchr (filesystem, '/');
|
||||
|
||||
/* Forbid /../ in paths */
|
||||
@@ -856,6 +948,14 @@ flatpak_context_take_filesystem (FlatpakContext *context,
|
||||
char *fs,
|
||||
FlatpakFilesystemMode mode)
|
||||
{
|
||||
+ /* Special case: --nofilesystem=host-reset implies --nofilesystem=host.
|
||||
+ * --filesystem=host-reset (or host:reset) is not allowed. */
|
||||
+ if (g_str_equal (fs, "host-reset"))
|
||||
+ {
|
||||
+ g_return_if_fail (mode == FLATPAK_FILESYSTEM_MODE_NONE);
|
||||
+ g_hash_table_insert (context->filesystems, g_strdup ("host"), GINT_TO_POINTER (mode));
|
||||
+ }
|
||||
+
|
||||
g_hash_table_insert (context->filesystems, fs, GINT_TO_POINTER (mode));
|
||||
}
|
||||
|
||||
@@ -887,6 +987,14 @@ flatpak_context_merge (FlatpakContext *context,
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
g_hash_table_insert (context->persistent, g_strdup (key), value);
|
||||
|
||||
+ /* We first handle host:reset, as it overrides all other keys from the parent */
|
||||
+ if (g_hash_table_lookup_extended (other->filesystems, "host-reset", NULL, &value))
|
||||
+ {
|
||||
+ g_warn_if_fail (GPOINTER_TO_INT (value) == FLATPAK_FILESYSTEM_MODE_NONE);
|
||||
+ g_hash_table_remove_all (context->filesystems);
|
||||
+ }
|
||||
+
|
||||
+ /* Then set the new ones, which includes propagating host:reset. */
|
||||
g_hash_table_iter_init (&iter, other->filesystems);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
g_hash_table_insert (context->filesystems, g_strdup (key), value);
|
||||
@@ -1074,7 +1182,7 @@ option_filesystem_cb (const gchar *option_name,
|
||||
g_autofree char *fs = NULL;
|
||||
FlatpakFilesystemMode mode;
|
||||
|
||||
- if (!flatpak_context_parse_filesystem (value, &fs, &mode, error))
|
||||
+ if (!flatpak_context_parse_filesystem (value, FALSE, &fs, &mode, error))
|
||||
return FALSE;
|
||||
|
||||
flatpak_context_take_filesystem (context, g_steal_pointer (&fs), mode);
|
||||
@@ -1091,7 +1199,7 @@ option_nofilesystem_cb (const gchar *option_name,
|
||||
g_autofree char *fs = NULL;
|
||||
FlatpakFilesystemMode mode;
|
||||
|
||||
- if (!flatpak_context_parse_filesystem (value, &fs, &mode, error))
|
||||
+ if (!flatpak_context_parse_filesystem (value, TRUE, &fs, &mode, error))
|
||||
return FALSE;
|
||||
|
||||
flatpak_context_take_filesystem (context, g_steal_pointer (&fs),
|
||||
@@ -1571,15 +1679,13 @@ flatpak_context_load_metadata (FlatpakContext *context,
|
||||
g_autofree char *filesystem = NULL;
|
||||
FlatpakFilesystemMode mode;
|
||||
|
||||
- if (!flatpak_context_parse_filesystem (fs, &filesystem, &mode, NULL))
|
||||
+ if (!flatpak_context_parse_filesystem (fs, remove,
|
||||
+ &filesystem, &mode, NULL))
|
||||
g_debug ("Unknown filesystem type %s", filesystems[i]);
|
||||
else
|
||||
{
|
||||
- if (remove)
|
||||
- flatpak_context_take_filesystem (context, g_steal_pointer (&filesystem),
|
||||
- FLATPAK_FILESYSTEM_MODE_NONE);
|
||||
- else
|
||||
- flatpak_context_take_filesystem (context, g_steal_pointer (&filesystem), mode);
|
||||
+ g_assert (mode == FLATPAK_FILESYSTEM_MODE_NONE || !remove);
|
||||
+ flatpak_context_take_filesystem (context, g_steal_pointer (&filesystem), mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1825,11 +1931,24 @@ flatpak_context_save_metadata (FlatpakContext *context,
|
||||
{
|
||||
g_autoptr(GPtrArray) array = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
+ /* Serialize host-reset first, because order can matter in
|
||||
+ * corner cases. */
|
||||
+ if (g_hash_table_lookup_extended (context->filesystems, "host-reset",
|
||||
+ NULL, &value))
|
||||
+ {
|
||||
+ g_warn_if_fail (GPOINTER_TO_INT (value) == FLATPAK_FILESYSTEM_MODE_NONE);
|
||||
+ g_ptr_array_add (array, g_strdup ("!host:reset"));
|
||||
+ }
|
||||
+
|
||||
g_hash_table_iter_init (&iter, context->filesystems);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
FlatpakFilesystemMode mode = GPOINTER_TO_INT (value);
|
||||
|
||||
+ /* We already did this */
|
||||
+ if (g_str_equal (key, "host-reset"))
|
||||
+ continue;
|
||||
+
|
||||
g_ptr_array_add (array, unparse_filesystem_flags (key, mode));
|
||||
}
|
||||
|
||||
@@ -1968,7 +2087,8 @@ flatpak_context_save_metadata (FlatpakContext *context,
|
||||
void
|
||||
flatpak_context_allow_host_fs (FlatpakContext *context)
|
||||
{
|
||||
- flatpak_context_take_filesystem (context, g_strdup ("host"), FLATPAK_FILESYSTEM_MODE_READ_WRITE);
|
||||
+ flatpak_context_take_filesystem (context, g_strdup ("host"),
|
||||
+ FLATPAK_FILESYSTEM_MODE_READ_WRITE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -2155,18 +2275,36 @@ flatpak_context_to_args (FlatpakContext *context,
|
||||
g_ptr_array_add (args, g_strdup_printf ("--system-%s-name=%s", flatpak_policy_to_string (policy), name));
|
||||
}
|
||||
|
||||
+ /* Serialize host-reset first, because order can matter in
|
||||
+ * corner cases. */
|
||||
+ if (g_hash_table_lookup_extended (context->filesystems, "host-reset",
|
||||
+ NULL, &value))
|
||||
+ {
|
||||
+ g_warn_if_fail (GPOINTER_TO_INT (value) == FLATPAK_FILESYSTEM_MODE_NONE);
|
||||
+ g_ptr_array_add (args, g_strdup ("--nofilesystem=host:reset"));
|
||||
+ }
|
||||
+
|
||||
g_hash_table_iter_init (&iter, context->filesystems);
|
||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
||||
{
|
||||
+ g_autofree char *fs = NULL;
|
||||
FlatpakFilesystemMode mode = GPOINTER_TO_INT (value);
|
||||
|
||||
+ /* We already did this */
|
||||
+ if (g_str_equal (key, "host-reset"))
|
||||
+ continue;
|
||||
+
|
||||
+ fs = unparse_filesystem_flags (key, mode);
|
||||
+
|
||||
if (mode != FLATPAK_FILESYSTEM_MODE_NONE)
|
||||
{
|
||||
- g_autofree char *fs = unparse_filesystem_flags (key, mode);
|
||||
g_ptr_array_add (args, g_strdup_printf ("--filesystem=%s", fs));
|
||||
}
|
||||
else
|
||||
- g_ptr_array_add (args, g_strdup_printf ("--nofilesystem=%s", (char *) key));
|
||||
+ {
|
||||
+ g_assert (fs[0] == '!');
|
||||
+ g_ptr_array_add (args, g_strdup_printf ("--nofilesystem=%s", &fs[1]));
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.27.0
|
||||
|
||||
85
backport-Fix-several-memory-leaks.patch
Normal file
85
backport-Fix-several-memory-leaks.patch
Normal 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);
|
||||
41
flatpak.spec
41
flatpak.spec
@ -1,6 +1,6 @@
|
||||
Name: flatpak
|
||||
Version: 1.10.2
|
||||
Release: 3
|
||||
Release: 9
|
||||
Summary: Application deployment framework for desktop apps
|
||||
License: LGPLv2+
|
||||
URL: http://flatpak.org/
|
||||
@ -20,6 +20,27 @@ Patch6007: backport-0008-CVE-2021-41133.patch
|
||||
Patch6008: backport-run-Handle-unknown-syscalls-as-intended.patch
|
||||
Patch6009: backport-Fix-handling-of-syscalls-only-allowed-by-de.patch
|
||||
Patch6010: backport-support-new-pyparsing.patch
|
||||
Patch6011: backport-CVE-2022-21682.patch
|
||||
Patch6012: backport-0001-CVE-2021-43860.patch
|
||||
Patch6013: backport-0002-CVE-2021-43860.patch
|
||||
Patch6014: backport-0003-CVE-2021-43860.patch
|
||||
Patch6015: backport-0004-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
|
||||
Patch6024: CVE-2024-32462.patch
|
||||
Patch6025: CVE-2024-42472.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(libsoup-2.4) pkgconfig(libxml-2.0) >= 2.4 pkgconfig(ostree-1) >= 2020.8 pkgconfig(polkit-gobject-1) pkgconfig(libseccomp) pkgconfig(xau)
|
||||
@ -125,6 +146,24 @@ flatpak remote-list --system &> /dev/null || :
|
||||
%{_mandir}/man5/flatpak-remote.5*
|
||||
|
||||
%changelog
|
||||
* Thu Aug 15 2024 wangkai <13474090681@163.com> - 1.10.2-9
|
||||
- Fix CVE-2024-42472
|
||||
|
||||
* Fri Apr 19 2024 wangkai <13474090681@163.com> - 1.10.2-8
|
||||
- Fix CVE-2024-32462
|
||||
|
||||
* 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
|
||||
- Fix CVE-2021-43860
|
||||
|
||||
* Tue Jan 25 2022 hanhui <hanhui15@huawei.com> - 1.10.2-4
|
||||
- Fix CVE-2022-21682
|
||||
|
||||
* Tue Jan 25 2022 hanhui <hanhui15@huawei.com> - 1.10.2-3
|
||||
- Fix compiler error when using pyparsing >= 3.0.2
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user