From ca7e6f02a07af911310e373327b588075108e508 Mon Sep 17 00:00:00 2001 From: wangkerong Date: Sat, 22 Jan 2022 16:40:48 +0800 Subject: [PATCH] fix CVE-2022-21682 (cherry picked from commit 5c1ea76f55a3c324dfea823695556165bec182a9) --- backport-0001-CVE-2022-21682.patch | 54 ++++++ backport-0002-CVE-2022-21682.patch | 271 +++++++++++++++++++++++++++++ backport-0003-CVE-2022-21682.patch | 32 ++++ backport-0004-CVE-2022-21682.patch | 114 ++++++++++++ flatpak.spec | 9 +- 5 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 backport-0001-CVE-2022-21682.patch create mode 100644 backport-0002-CVE-2022-21682.patch create mode 100644 backport-0003-CVE-2022-21682.patch create mode 100644 backport-0004-CVE-2022-21682.patch diff --git a/backport-0001-CVE-2022-21682.patch b/backport-0001-CVE-2022-21682.patch new file mode 100644 index 0000000..4fe9a2b --- /dev/null +++ b/backport-0001-CVE-2022-21682.patch @@ -0,0 +1,54 @@ +From 949a3ec479d5ca0c962cf12adec70aea30bf0186 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Mon, 20 Jan 2020 19:20:14 +0000 +Subject: [PATCH] context: Generalize handling of special filesystems a bit + +Currently there are only "home" and "host", but I'm going to add one +that represents /usr and friends (/usr, /lib, ...), and one for /etc. +These differ from ordinary filesystem mounts because they are redirected +into /run/host to avoid conflicting with the runtime. + +Signed-off-by: Simon McVittie +--- + common/flatpak-context.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/common/flatpak-context.c b/common/flatpak-context.c +index 462134aab..4ff235b1d 100644 +--- a/common/flatpak-context.c ++++ b/common/flatpak-context.c +@@ -81,6 +81,12 @@ const char *flatpak_context_features[] = { + NULL + }; + ++const char *flatpak_context_special_filesystems[] = { ++ "home", ++ "host", ++ NULL ++}; ++ + FlatpakContext * + flatpak_context_new (void) + { +@@ -749,9 +755,7 @@ flatpak_context_verify_filesystem (const char *filesystem_and_mode, + { + g_autofree char *filesystem = parse_filesystem_flags (filesystem_and_mode, NULL); + +- if (strcmp (filesystem, "host") == 0) +- return TRUE; +- if (strcmp (filesystem, "home") == 0) ++ if (g_strv_contains (flatpak_context_special_filesystems, filesystem)) + return TRUE; + if (get_xdg_user_dir_from_string (filesystem, NULL, NULL, NULL)) + return TRUE; +@@ -2103,8 +2107,7 @@ flatpak_context_export (FlatpakContext *context, + const char *filesystem = key; + FlatpakFilesystemMode mode = GPOINTER_TO_INT (value); + +- if (strcmp (filesystem, "host") == 0 || +- strcmp (filesystem, "home") == 0) ++ if (g_strv_contains (flatpak_context_special_filesystems, filesystem)) + continue; + + if (g_str_has_prefix (filesystem, "xdg-")) + diff --git a/backport-0002-CVE-2022-21682.patch b/backport-0002-CVE-2022-21682.patch new file mode 100644 index 0000000..24d5830 --- /dev/null +++ b/backport-0002-CVE-2022-21682.patch @@ -0,0 +1,271 @@ +From 517ad25b5fe83376af258acef646551cb97af97c Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Mon, 10 Aug 2020 23:58:11 +0100 +Subject: [PATCH] context: Only parse filesystem/mode strings in one place +This gives us the ability for the parse function (the former verify +function) to carry out a normalization step as well. +Signed-off-by: Simon McVittie +Conflict:NA +Reference:https://github.com/flatpak/flatpak/commit/517ad25b5fe83376af258acef646551cb97af97c +--- + common/flatpak-context.c | 75 +++++++++++++++++--------------- + common/flatpak-exports-private.h | 1 + + common/flatpak-exports.c | 16 +++---- + 3 files changed, 48 insertions(+), 44 deletions(-) +diff --git a/common/flatpak-context.c b/common/flatpak-context.c +index 4892d7b..3f66d65 100644 +--- a/common/flatpak-context.c ++++ b/common/flatpak-context.c +@@ -92,6 +92,7 @@ flatpak_context_new (void) + context = g_slice_new0 (FlatpakContext); + context->env_vars = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + context->persistent = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); ++ /* filename or special filesystem name => FlatpakFilesystemMode */ + context->filesystems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + context->session_bus_policy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + context->system_bus_policy = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); +@@ -748,19 +749,23 @@ parse_filesystem_flags (const char *filesystem, + } + + static gboolean +-flatpak_context_verify_filesystem (const char *filesystem_and_mode, +- GError **error) ++flatpak_context_parse_filesystem (const char *filesystem_and_mode, ++ char **filesystem_out, ++ FlatpakFilesystemMode *mode_out, ++ GError **error) + { +- g_autofree char *filesystem = parse_filesystem_flags (filesystem_and_mode, NULL); ++ g_autofree char *filesystem = parse_filesystem_flags (filesystem_and_mode, mode_out); + +- if (g_strv_contains (flatpak_context_special_filesystems, filesystem)) +- return TRUE; +- if (get_xdg_user_dir_from_string (filesystem, NULL, NULL, NULL)) +- return TRUE; +- if (g_str_has_prefix (filesystem, "~/")) +- return TRUE; +- if (g_str_has_prefix (filesystem, "/")) +- return TRUE; ++ if (g_strv_contains (flatpak_context_special_filesystems, filesystem) || ++ get_xdg_user_dir_from_string (filesystem, NULL, NULL, NULL) || ++ g_str_has_prefix (filesystem, "~/") || ++ g_str_has_prefix (filesystem, "/")) ++ { ++ if (filesystem_out != NULL) ++ *filesystem_out = g_steal_pointer (&filesystem); ++ ++ return TRUE; ++ } + + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED, + _("Unknown filesystem location %s, valid locations are: host, home, xdg-*[/...], ~/dir, /dir"), filesystem); +@@ -768,24 +773,13 @@ flatpak_context_verify_filesystem (const char *filesystem_and_mode, + } + + static void +-flatpak_context_add_filesystem (FlatpakContext *context, +- const char *what) ++flatpak_context_take_filesystem (FlatpakContext *context, ++ char *fs, ++ FlatpakFilesystemMode mode) + { +- FlatpakFilesystemMode mode; +- char *fs = parse_filesystem_flags (what, &mode); +- + g_hash_table_insert (context->filesystems, fs, GINT_TO_POINTER (mode)); + } + +-static void +-flatpak_context_remove_filesystem (FlatpakContext *context, +- const char *what) +-{ +- g_hash_table_insert (context->filesystems, +- parse_filesystem_flags (what, NULL), +- NULL); +-} +- + void + flatpak_context_merge (FlatpakContext *context, + FlatpakContext *other) +@@ -999,11 +993,13 @@ option_filesystem_cb (const gchar *option_name, + GError **error) + { + FlatpakContext *context = data; ++ g_autofree char *fs = NULL; ++ FlatpakFilesystemMode mode; + +- if (!flatpak_context_verify_filesystem (value, error)) ++ if (!flatpak_context_parse_filesystem (value, &fs, &mode, error)) + return FALSE; + +- flatpak_context_add_filesystem (context, value); ++ flatpak_context_take_filesystem (context, g_steal_pointer (&fs), mode); + return TRUE; + } + +@@ -1014,11 +1010,14 @@ option_nofilesystem_cb (const gchar *option_name, + GError **error) + { + FlatpakContext *context = data; ++ g_autofree char *fs = NULL; ++ FlatpakFilesystemMode mode; + +- if (!flatpak_context_verify_filesystem (value, error)) ++ if (!flatpak_context_parse_filesystem (value, &fs, &mode, error)) + return FALSE; + +- flatpak_context_remove_filesystem (context, value); ++ flatpak_context_take_filesystem (context, g_steal_pointer (&fs), ++ FLATPAK_FILESYSTEM_MODE_NONE); + return TRUE; + } + +@@ -1441,14 +1440,18 @@ flatpak_context_load_metadata (FlatpakContext *context, + for (i = 0; filesystems[i] != NULL; i++) + { + const char *fs = parse_negated (filesystems[i], &remove); +- if (!flatpak_context_verify_filesystem (fs, NULL)) ++ g_autofree char *filesystem = NULL; ++ FlatpakFilesystemMode mode; ++ ++ if (!flatpak_context_parse_filesystem (fs, &filesystem, &mode, NULL)) + g_debug ("Unknown filesystem type %s", filesystems[i]); + else + { + if (remove) +- flatpak_context_remove_filesystem (context, fs); ++ flatpak_context_take_filesystem (context, g_steal_pointer (&filesystem), ++ FLATPAK_FILESYSTEM_MODE_NONE); + else +- flatpak_context_add_filesystem (context, fs); ++ flatpak_context_take_filesystem (context, g_steal_pointer (&filesystem), mode); + } + } + } +@@ -1674,7 +1677,7 @@ flatpak_context_save_metadata (FlatpakContext *context, + { + FlatpakFilesystemMode mode = GPOINTER_TO_INT (value); + +- if (mode != 0) ++ if (mode != FLATPAK_FILESYSTEM_MODE_NONE) + g_ptr_array_add (array, unparse_filesystem_flags (key, mode)); + else + g_ptr_array_add (array, g_strconcat ("!", key, NULL)); +@@ -1781,7 +1784,7 @@ flatpak_context_save_metadata (FlatpakContext *context, + void + flatpak_context_allow_host_fs (FlatpakContext *context) + { +- flatpak_context_add_filesystem (context, "host"); ++ flatpak_context_take_filesystem (context, g_strdup ("host"), FLATPAK_FILESYSTEM_MODE_READ_WRITE); + } + + gboolean +@@ -1846,7 +1849,7 @@ flatpak_context_to_args (FlatpakContext *context, + { + FlatpakFilesystemMode mode = GPOINTER_TO_INT (value); + +- if (mode != 0) ++ 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)); +@@ -1949,7 +1952,7 @@ flatpak_context_export (FlatpakContext *context, + gpointer key, value; + + fs_mode = (FlatpakFilesystemMode) g_hash_table_lookup (context->filesystems, "host"); +- if (fs_mode != 0) ++ if (fs_mode != FLATPAK_FILESYSTEM_MODE_NONE) + { + DIR *dir; + struct dirent *dirent; +diff --git a/common/flatpak-exports-private.h b/common/flatpak-exports-private.h +index 64cf59a..e4b2c14 100644 +--- a/common/flatpak-exports-private.h ++++ b/common/flatpak-exports-private.h +@@ -26,6 +26,7 @@ + + /* In numerical order of more privs */ + typedef enum { ++ FLATPAK_FILESYSTEM_MODE_NONE = 0, + FLATPAK_FILESYSTEM_MODE_READ_ONLY = 1, + FLATPAK_FILESYSTEM_MODE_READ_WRITE = 2, + FLATPAK_FILESYSTEM_MODE_CREATE = 3, +diff --git a/common/flatpak-exports.c b/common/flatpak-exports.c +index 21a8b17..87c8172 100644 +--- a/common/flatpak-exports.c ++++ b/common/flatpak-exports.c +@@ -80,7 +80,7 @@ make_relative (const char *base, const char *path) + } + + #define FAKE_MODE_DIR -1 /* Ensure a dir, either on tmpfs or mapped parent */ +-#define FAKE_MODE_TMPFS 0 ++#define FAKE_MODE_TMPFS FLATPAK_FILESYSTEM_MODE_NONE + #define FAKE_MODE_SYMLINK G_MAXINT + + typedef struct +@@ -278,7 +278,7 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports, + } + } + +- if (exports->host_fs != 0) ++ if (exports->host_fs != FLATPAK_FILESYSTEM_MODE_NONE) + { + if (g_file_test ("/usr", G_FILE_TEST_IS_DIR)) + flatpak_bwrap_add_args (bwrap, +@@ -291,7 +291,7 @@ flatpak_exports_append_bwrap_args (FlatpakExports *exports, + } + } + +-/* Returns 0 if not visible */ ++/* Returns FLATPAK_FILESYSTEM_MODE_NONE if not visible */ + FlatpakFilesystemMode + flatpak_exports_path_get_mode (FlatpakExports *exports, + const char *path) +@@ -337,7 +337,7 @@ flatpak_exports_path_get_mode (FlatpakExports *exports, + break; + } + +- return 0; ++ return FLATPAK_FILESYSTEM_MODE_NONE; + } + + if (S_ISLNK (st.st_mode)) +@@ -347,7 +347,7 @@ flatpak_exports_path_get_mode (FlatpakExports *exports, + int j; + + if (resolved == NULL) +- return 0; ++ return FLATPAK_FILESYSTEM_MODE_NONE; + + path2_builder = g_string_new (resolved); + +@@ -361,7 +361,7 @@ flatpak_exports_path_get_mode (FlatpakExports *exports, + } + } + else if (parts[i + 1] == NULL) +- return 0; /* Last part was not mapped */ ++ return FLATPAK_FILESYSTEM_MODE_NONE; /* Last part was not mapped */ + } + + if (is_readonly) +@@ -374,7 +374,7 @@ gboolean + flatpak_exports_path_is_visible (FlatpakExports *exports, + const char *path) + { +- return flatpak_exports_path_get_mode (exports, path) > 0; ++ return flatpak_exports_path_get_mode (exports, path) > FLATPAK_FILESYSTEM_MODE_NONE; + } + + static gboolean +@@ -605,7 +605,7 @@ flatpak_exports_add_path_expose_or_hide (FlatpakExports *exports, + FlatpakFilesystemMode mode, + const char *path) + { +- if (mode == 0) ++ if (mode == FLATPAK_FILESYSTEM_MODE_NONE) + flatpak_exports_add_path_tmpfs (exports, path); + else + flatpak_exports_add_path_expose (exports, mode, path); +-- +2.19.1 + diff --git a/backport-0003-CVE-2022-21682.patch b/backport-0003-CVE-2022-21682.patch new file mode 100644 index 0000000..c428c41 --- /dev/null +++ b/backport-0003-CVE-2022-21682.patch @@ -0,0 +1,32 @@ + +From 5a83c73ed859fe3e4bd93a228a4bc8981d649c5e Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 27 Aug 2020 18:01:12 +0100 +Subject: [PATCH] context: Implement MODE_NONE in unparse_filesystem_flags +flatpak doesn't yet use -Wswitch-enum, but perhaps it should at some +point. Now that FLATPAK_FILESYSTEM_MODE_NONE is a member of the enum, +it should be handled; and if we're doing that, we might as well make +the same function fully responsible for it. +Signed-off-by: Simon McVittie +Conflict:NA +Reference:https://github.com/flatpak/flatpak/commit/5a83c73ed859fe3e4bd93a228a4bc8981d649c5e +--- + common/flatpak-context.c | 4 ++++ + 1 file changed, 4 insertions(+) +diff --git a/common/flatpak-context.c b/common/flatpak-context.c +index 3f66d65..25835b6 100644 +--- a/common/flatpak-context.c ++++ b/common/flatpak-context.c +@@ -697,6 +697,10 @@ unparse_filesystem_flags (const char *path, + case FLATPAK_FILESYSTEM_MODE_READ_WRITE: + break; + ++ case FLATPAK_FILESYSTEM_MODE_NONE: ++ g_string_insert_c (s, 0, '!'); ++ break; ++ + default: + g_warning ("Unexpected filesystem mode %d", mode); + break; +-- +2.19.1 diff --git a/backport-0004-CVE-2022-21682.patch b/backport-0004-CVE-2022-21682.patch new file mode 100644 index 0000000..336ae37 --- /dev/null +++ b/backport-0004-CVE-2022-21682.patch @@ -0,0 +1,114 @@ +From 445bddeee657fdc8d2a0a1f0de12975400d4fc1a Mon Sep 17 00:00:00 2001 +From: Alexander Larsson +Date: Tue, 19 Oct 2021 11:48:00 +0200 +Subject: [PATCH] Make --nofilesystem=host/home remove access to subdirs of + those +Previously --nofilesystem=host only removed specifically access to the +`host` permissions, and not necessarily other filesystems (like `home` +or `/some/path`). This isn't very useful to limit access because you +don't know what other filesystems the app may have access too. +We change this to mean that `--nofilesystem=host` removes *all* filesystem +access from the parent layer, and `--nofilesystem=home` removes all +file access to the homedir and paths inside it. +The available layers are, in order: + * app permissions + * overrides + * commandline args +This allows you to start from scratch with the filesystem permissions +in the overrides or the commandline. This is a small change in +behaviour, but not a lot of things use --nofilesystem, and the ones +that do probably expects this behaviour. +Conflict:NA +Reference:https://github.com/flatpak/flatpak/commit/445bddeee657fdc8d2a0a1f0de12975400d4fc1a +--- + common/flatpak-context.c | 62 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 62 insertions(+) +diff --git a/common/flatpak-context.c b/common/flatpak-context.c +index 25835b6..3c53225 100644 +--- a/common/flatpak-context.c ++++ b/common/flatpak-context.c +@@ -784,12 +784,39 @@ flatpak_context_take_filesystem (FlatpakContext *context, + g_hash_table_insert (context->filesystems, fs, GINT_TO_POINTER (mode)); + } + ++/* Note: This only works with valid keys, i.e. they passed flatpak_context_parse_filesystem */ ++static gboolean ++flatpak_filesystem_key_in_home (const char *filesystem) ++{ ++ /* "home" is definitely in home */ ++ if (strcmp (filesystem, "home") == 0) ++ return TRUE; ++ ++ /* All the other special fs:es are non-home. ++ * Note: This considers absolute paths that are in the homedir as non-home. ++ */ ++ if (g_strv_contains (flatpak_context_special_filesystems, filesystem) || ++ g_str_has_prefix (filesystem, "/")) ++ return FALSE; ++ ++ /* Files in xdg-run are not in home */ ++ if (g_str_has_prefix (filesystem, "xdg-run")) ++ return FALSE; ++ ++ /* All remaining keys (~/, xdg-data, etc) are considered in home, ++ * Note: technically $XDG_HOME_DATA could point outside the homedir, but we ignore that. ++ */ ++ return TRUE; ++} ++ + void + flatpak_context_merge (FlatpakContext *context, + FlatpakContext *other) + { + GHashTableIter iter; + gpointer key, value; ++ gboolean no_home = FALSE; ++ gboolean no_host = FALSE; + + context->shares &= ~other->shares_valid; + context->shares |= other->shares; +@@ -812,6 +839,41 @@ 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 all negative home and host as they override other ++ keys than themselves from the parent */ ++ if (g_hash_table_lookup_extended (other->filesystems, ++ "host", ++ NULL, &value)) ++ { ++ FlatpakFilesystemMode host_mode = GPOINTER_TO_INT (value); ++ if (host_mode == FLATPAK_FILESYSTEM_MODE_NONE) ++ no_host = TRUE; ++ } ++ ++ if (g_hash_table_lookup_extended (other->filesystems, ++ "home", ++ NULL, &value)) ++ { ++ FlatpakFilesystemMode home_mode = GPOINTER_TO_INT (value); ++ if (home_mode == FLATPAK_FILESYSTEM_MODE_NONE) ++ no_home = TRUE; ++ } ++ ++ if (no_host) ++ { ++ g_hash_table_remove_all (context->filesystems); ++ } ++ else if (no_home) ++ { ++ g_hash_table_iter_init (&iter, context->filesystems); ++ while (g_hash_table_iter_next (&iter, &key, &value)) ++ { ++ if (flatpak_filesystem_key_in_home ((const char *)key)) ++ g_hash_table_iter_remove (&iter); ++ } ++ } ++ ++ /* Then set the new ones, which includes propagating the nohost and nohome ones. */ + 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); +-- +2.19.1 + diff --git a/flatpak.spec b/flatpak.spec index 4c731af..16367f7 100644 --- a/flatpak.spec +++ b/flatpak.spec @@ -1,6 +1,6 @@ Name: flatpak Version: 1.0.3 -Release: 7 +Release: 8 Summary: Application deployment framework for desktop apps License: LGPLv2+ URL: http://flatpak.org/ @@ -26,6 +26,10 @@ Patch6006: backport-0007-CVE-2021-41133.patch 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-devel.patch +Patch6010: backport-0001-CVE-2022-21682.patch +Patch6011: backport-0002-CVE-2022-21682.patch +Patch6012: backport-0003-CVE-2022-21682.patch +Patch6013: backport-0004-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) >= 2018.7 pkgconfig(polkit-gobject-1) pkgconfig(libseccomp) pkgconfig(xau) @@ -120,6 +124,9 @@ flatpak remote-list --system &> /dev/null || : %{_mandir}/man5/flatpak-remote.5* %changelog +* Sat Jan 22 2022 wangkerong - 1.0.3-8 +- Fix CVE-2022-21682 + * Wed Oct 20 2021 zhanzhimin - 1.0.3-7 - Fix CVE-2021-41133 -- Gitee