diff --git a/backport-0001-CVE-2022-21682.patch b/backport-0001-CVE-2022-21682.patch new file mode 100644 index 0000000000000000000000000000000000000000..a1251ca5d39c6eea832956df29ac19ca8550e2e9 --- /dev/null +++ b/backport-0001-CVE-2022-21682.patch @@ -0,0 +1,60 @@ +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 + +Conflict:NA +Reference:https://github.com/flatpak/flatpak/commit/949a3ec479d5ca0c962cf12adec70aea30bf0186 + +--- + 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 6df9b1e..4892d7b 100644 +--- a/common/flatpak-context.c ++++ b/common/flatpak-context.c +@@ -78,6 +78,12 @@ const char *flatpak_context_features[] = { + NULL + }; + ++const char *flatpak_context_special_filesystems[] = { ++ "home", ++ "host", ++ NULL ++}; ++ + FlatpakContext * + flatpak_context_new (void) + { +@@ -747,9 +753,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; +@@ -1988,8 +1992,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-")) +-- +2.27.0 + diff --git a/backport-0002-CVE-2022-21682.patch b/backport-0002-CVE-2022-21682.patch new file mode 100644 index 0000000000000000000000000000000000000000..c13dca4838745b4a8a261a3892e979d745e9953a --- /dev/null +++ b/backport-0002-CVE-2022-21682.patch @@ -0,0 +1,276 @@ +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 | 77 +++++++++++++++++--------------- + common/flatpak-exports-private.h | 1 + + common/flatpak-exports.c | 14 +++--- + 3 files changed, 48 insertions(+), 44 deletions(-) + +diff --git a/common/flatpak-context.c b/common/flatpak-context.c +index 4892d7b..3a99646 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; +@@ -1978,7 +1981,7 @@ flatpak_context_export (FlatpakContext *context, + } + + home_mode = (FlatpakFilesystemMode) g_hash_table_lookup (context->filesystems, "home"); +- if (home_mode != 0) ++ if (home_mode != FLATPAK_FILESYSTEM_MODE_NONE) + { + g_debug ("Allowing homedir access"); + home_access = TRUE; +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..d31ef95 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, +@@ -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.27.0 + diff --git a/backport-0003-CVE-2022-21682.patch b/backport-0003-CVE-2022-21682.patch new file mode 100644 index 0000000000000000000000000000000000000000..5d2ac39c3f8f38b2dfacc686bdabcccbd0be6eb1 --- /dev/null +++ b/backport-0003-CVE-2022-21682.patch @@ -0,0 +1,49 @@ +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 | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/common/flatpak-context.c b/common/flatpak-context.c +index 3a99646..0d53b13 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; +@@ -1677,10 +1681,7 @@ flatpak_context_save_metadata (FlatpakContext *context, + { + FlatpakFilesystemMode mode = GPOINTER_TO_INT (value); + +- 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)); ++ g_ptr_array_add (array, unparse_filesystem_flags (key, mode)); + } + + g_key_file_set_string_list (metakey, +-- +2.27.0 + diff --git a/backport-0004-CVE-2022-21682.patch b/backport-0004-CVE-2022-21682.patch new file mode 100644 index 0000000000000000000000000000000000000000..a759a187a8664068960f72d726213116eec0f491 --- /dev/null +++ b/backport-0004-CVE-2022-21682.patch @@ -0,0 +1,47 @@ +From 55b27b1393a3880b79dfe108b6f13f1a2fa1888b Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Wed, 26 Aug 2020 20:25:15 +0100 +Subject: [PATCH] context: Expose flatpak_context_parse_filesystem for testing + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://github.com/flatpak/flatpak/commit/55b27b1393a3880b79dfe108b6f13f1a2fa1888b + +--- + common/flatpak-context-private.h | 5 +++++ + common/flatpak-context.c | 2 +- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/common/flatpak-context-private.h b/common/flatpak-context-private.h +index f47079b..d84f4e0 100644 +--- a/common/flatpak-context-private.h ++++ b/common/flatpak-context-private.h +@@ -79,6 +79,11 @@ extern const char *flatpak_context_devices[]; + extern const char *flatpak_context_features[]; + extern const char *flatpak_context_shares[]; + ++gboolean flatpak_context_parse_filesystem (const char *filesystem_and_mode, ++ char **filesystem_out, ++ FlatpakFilesystemMode *mode_out, ++ GError **error); ++ + FlatpakContext *flatpak_context_new (void); + void flatpak_context_free (FlatpakContext *context); + void flatpak_context_merge (FlatpakContext *context, +diff --git a/common/flatpak-context.c b/common/flatpak-context.c +index 0d53b13..3b2bcfe 100644 +--- a/common/flatpak-context.c ++++ b/common/flatpak-context.c +@@ -752,7 +752,7 @@ parse_filesystem_flags (const char *filesystem, + return g_string_free (g_steal_pointer (&s), FALSE); + } + +-static gboolean ++gboolean + flatpak_context_parse_filesystem (const char *filesystem_and_mode, + char **filesystem_out, + FlatpakFilesystemMode *mode_out, +-- +2.27.0 + diff --git a/backport-0005-CVE-2022-21682.patch b/backport-0005-CVE-2022-21682.patch new file mode 100644 index 0000000000000000000000000000000000000000..f4a19ffa3b94c5fe55fcf985a04f20dfa7bcb339 --- /dev/null +++ b/backport-0005-CVE-2022-21682.patch @@ -0,0 +1,81 @@ +From aafe1d36e0225f54db8ca2ba03d8b1981c2d09e0 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Wed, 26 Aug 2020 19:05:21 +0100 +Subject: [PATCH] context: Do some syntactic normalization on filesystems + +Paths containing ".." are rejected: they're almost certainly a +terrible idea. + +Paths containing "." or multiple slashes are syntactically normalized. + +This assumes that nobody is going to use "--filesystem=/foo/bar/" to +mean "make /foo/bar available, unless it's a non-directory, in which +case fail". + +Signed-off-by: Simon McVittie + +Conflict:NA +Reference:https://github.com/flatpak/flatpak/commit/aafe1d36e0225f54db8ca2ba03d8b1981c2d09e0 + +--- + common/flatpak-context.c | 44 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +diff --git a/common/flatpak-context.c b/common/flatpak-context.c +index 3b2bcfe..84b292e 100644 +--- a/common/flatpak-context.c ++++ b/common/flatpak-context.c +@@ -759,6 +759,50 @@ flatpak_context_parse_filesystem (const char *filesystem_and_mode, + GError **error) + { + g_autofree char *filesystem = parse_filesystem_flags (filesystem_and_mode, mode_out); ++ char *slash; ++ ++ slash = strchr (filesystem, '/'); ++ ++ /* Forbid /../ in paths */ ++ if (slash != NULL) ++ { ++ if (g_str_has_prefix (slash + 1, "../") || ++ g_str_has_suffix (slash + 1, "/..") || ++ strstr (slash + 1, "/../") != NULL) ++ { ++ g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, ++ _("Filesystem location \"%s\" contains \"..\""), ++ filesystem); ++ return FALSE; ++ } ++ ++ /* Convert "//" and "/./" to "/" */ ++ for (; slash != NULL; slash = strchr (slash + 1, '/')) ++ { ++ while (TRUE) ++ { ++ if (slash[1] == '/') ++ memmove (slash + 1, slash + 2, strlen (slash + 2) + 1); ++ else if (slash[1] == '.' && slash[2] == '/') ++ memmove (slash + 1, slash + 3, strlen (slash + 3) + 1); ++ else ++ break; ++ } ++ } ++ ++ /* Eliminate trailing "/." or "/". */ ++ while (TRUE) ++ { ++ slash = strrchr (filesystem, '/'); ++ ++ if (slash != NULL && ++ ((slash != filesystem && slash[1] == '\0') || ++ (slash[1] == '.' && slash[2] == '\0'))) ++ *slash = '\0'; ++ else ++ break; ++ } ++ } + + if (g_strv_contains (flatpak_context_special_filesystems, filesystem) || + get_xdg_user_dir_from_string (filesystem, NULL, NULL, NULL) || +-- +2.27.0 + diff --git a/backport-0006-CVE-2022-21682.patch b/backport-0006-CVE-2022-21682.patch new file mode 100644 index 0000000000000000000000000000000000000000..1cbe9a9861a3a02c3bfa4bccf2f4fb875282e06f --- /dev/null +++ b/backport-0006-CVE-2022-21682.patch @@ -0,0 +1,381 @@ +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 ++++++++++++++++++++++++++++--- + doc/flatpak-override.xml | 8 ++ + doc/flatpak-run.xml | 8 ++ + 4 files changed, 169 insertions(+), 14 deletions(-) + +diff --git a/common/flatpak-context-private.h b/common/flatpak-context-private.h +index d84f4e0..2d2a40e 100644 +--- a/common/flatpak-context-private.h ++++ b/common/flatpak-context-private.h +@@ -80,6 +80,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 84b292e..30a84bd 100644 +--- a/common/flatpak-context.c ++++ b/common/flatpak-context.c +@@ -81,6 +81,7 @@ const char *flatpak_context_features[] = { + const char *flatpak_context_special_filesystems[] = { + "home", + "host", ++ "host-reset", + NULL + }; + +@@ -699,6 +700,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: +@@ -711,11 +718,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 != ':') +@@ -730,7 +740,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 == ':') + { +@@ -742,10 +776,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; + +@@ -754,13 +841,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 */ +@@ -825,6 +917,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)); + } + +@@ -856,6 +956,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); +@@ -1044,7 +1152,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); +@@ -1061,7 +1169,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), +@@ -1491,15 +1599,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); + } + } + } +@@ -1720,11 +1826,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)); + } + +@@ -1829,7 +1948,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 +@@ -1889,18 +2009,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])); ++ } + } + } + +diff --git a/doc/flatpak-override.xml b/doc/flatpak-override.xml +index 60fa58c..bddb36e 100644 +--- a/doc/flatpak-override.xml ++++ b/doc/flatpak-override.xml +@@ -221,6 +221,14 @@ + xdg-music, xdg-pictures, xdg-public-share, xdg-templates, xdg-videos, + an absolute path, or a homedir-relative path like ~/dir. + This option can be used multiple times. ++ ++ As a special case, ++ ++ will ignore all ++ permissions inherited from the app manifest or a ++ lower-precedence layer of overrides, in addition to ++ having the behaviour of ++ . + + + +diff --git a/doc/flatpak-run.xml b/doc/flatpak-run.xml +index 8e1a3fd..be77092 100644 +--- a/doc/flatpak-run.xml ++++ b/doc/flatpak-run.xml +@@ -324,6 +324,14 @@ + xdg-music, xdg-pictures, xdg-public-share, xdg-templates, xdg-videos, + an absolute path, or a homedir-relative path like ~/dir. + This option can be used multiple times. ++ ++ As a special case, ++ ++ will ignore all ++ permissions inherited from the app manifest or ++ flatpak-override1, ++ in addition to having the behaviour of ++ . + + + +-- +2.27.0 + diff --git a/flatpak.spec b/flatpak.spec index f847d7d5497b67c0d68633655cede7a4571761bd..362e6f01c9cb4169646aa425aea2fa5929b265f0 100644 --- a/flatpak.spec +++ b/flatpak.spec @@ -1,6 +1,6 @@ Name: flatpak Version: 1.0.3 -Release: 10 +Release: 11 Summary: Application deployment framework for desktop apps License: LGPLv2+ URL: http://flatpak.org/ @@ -30,6 +30,12 @@ Patch6010: backport-0001-CVE-2021-43860.patch Patch6011: backport-0002-CVE-2021-43860.patch Patch6012: backport-0003-CVE-2021-43860.patch Patch6013: backport-0004-CVE-2021-43860.patch +Patch6014: backport-0001-CVE-2022-21682.patch +Patch6015: backport-0002-CVE-2022-21682.patch +Patch6016: backport-0003-CVE-2022-21682.patch +Patch6017: backport-0004-CVE-2022-21682.patch +Patch6018: backport-0005-CVE-2022-21682.patch +Patch6019: backport-0006-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) @@ -124,6 +130,9 @@ flatpak remote-list --system &> /dev/null || : %{_mandir}/man5/flatpak-remote.5* %changelog +* Tue Feb 15 2022 dongyuzhen - 1.0.3-11 +- Fix CVE-2022-21682 + * Sat Jan 29 2022 dongyuzhen - 1.0.3-10 - Fix CVE-2021-43860