Fix CVE-2022-21682

This commit is contained in:
dongyuzhen 2022-02-15 14:28:40 +08:00
parent c0f3b3adb9
commit 36a9729ecf
7 changed files with 904 additions and 1 deletions

View File

@ -0,0 +1,60 @@
From 949a3ec479d5ca0c962cf12adec70aea30bf0186 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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

View File

@ -0,0 +1,276 @@
From 517ad25b5fe83376af258acef646551cb97af97c Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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

View File

@ -0,0 +1,49 @@
From 5a83c73ed859fe3e4bd93a228a4bc8981d649c5e Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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

View File

@ -0,0 +1,47 @@
From 55b27b1393a3880b79dfe108b6f13f1a2fa1888b Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Wed, 26 Aug 2020 20:25:15 +0100
Subject: [PATCH] context: Expose flatpak_context_parse_filesystem for testing
Signed-off-by: Simon McVittie <smcv@collabora.com>
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

View File

@ -0,0 +1,81 @@
From aafe1d36e0225f54db8ca2ba03d8b1981c2d09e0 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
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 <smcv@collabora.com>
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

View File

@ -0,0 +1,381 @@
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 ++++++++++++++++++++++++++++---
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.
+ </para><para>
+ As a special case,
+ <option>--nofilesystem=host:reset</option>
+ will ignore all <option>--filesystem</option>
+ permissions inherited from the app manifest or a
+ lower-precedence layer of overrides, in addition to
+ having the behaviour of
+ <option>--nofilesystem=host</option>.
</para></listitem>
</varlistentry>
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.
+ </para><para>
+ As a special case,
+ <option>--nofilesystem=host:reset</option>
+ will ignore all <option>--filesystem</option>
+ permissions inherited from the app manifest or
+ <citerefentry><refentrytitle>flatpak-override</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+ in addition to having the behaviour of
+ <option>--nofilesystem=host</option>.
</para></listitem>
</varlistentry>
--
2.27.0

View File

@ -1,6 +1,6 @@
Name: flatpak
Version: 1.0.3
Release: 8
Release: 9
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 <dongyuzhen@h-partners.com> - 1.0.3-9
- Fix CVE-2022-21682
* Sat Jan 29 2022 dongyuzhen <dongyuzhen@h-partners.com> - 1.0.3-8
- Fix CVE-2021-43860