From 778fd167a33f840a5313e9c649536c89bae18ae0 Mon Sep 17 00:00:00 2001 From: wangkerong Date: Mon, 24 Jan 2022 14:33:22 +0800 Subject: [PATCH] fix CVE-2022-21682 --- backport-CVE-2022-21682.patch | 340 ++++++++++++++++++++++++++++++++++ flatpak.spec | 6 +- 2 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2022-21682.patch diff --git a/backport-CVE-2022-21682.patch b/backport-CVE-2022-21682.patch new file mode 100644 index 0000000..0b3adb5 --- /dev/null +++ b/backport-CVE-2022-21682.patch @@ -0,0 +1,340 @@ +From 5709f1aaed6579f0136976e14e7f3cae399134ca Mon Sep 17 00:00:00 2001 +From: Simon McVittie +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 + +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 + diff --git a/flatpak.spec b/flatpak.spec index 5d6065f..d1a2086 100644 --- a/flatpak.spec +++ b/flatpak.spec @@ -1,6 +1,6 @@ Name: flatpak Version: 1.10.2 -Release: 3 +Release: 4 Summary: Application deployment framework for desktop apps License: LGPLv2+ URL: http://flatpak.org/ @@ -20,6 +20,7 @@ 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: support-new-pyparsing.patch +Patch6011: backport-CVE-2022-21682.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 +126,9 @@ flatpak remote-list --system &> /dev/null || : %{_mandir}/man5/flatpak-remote.5* %changelog +* Mon Jan 24 2022 wangkerong - 1.10.2-4 +- Fix CVE-2022-21682 + * Tue Jan 11 2022 yaoxin - 1.10.2-3 - Fix compilation failure of flatpak -- Gitee