summaryrefslogtreecommitdiff
path: root/common/flatpak-context.c
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2020-08-26 19:05:21 +0100
committerAlexander Larsson <alexander.larsson@gmail.com>2020-08-27 17:48:50 +0200
commitaafe1d36e0225f54db8ca2ba03d8b1981c2d09e0 (patch)
tree8e59a47035473e138427eb06e1bf8395e756b200 /common/flatpak-context.c
parentc0faab35fabb469e3945ad99c32f041d2d7a0dab (diff)
downloadflatpak-aafe1d36e0225f54db8ca2ba03d8b1981c2d09e0.tar.gz
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>
Diffstat (limited to 'common/flatpak-context.c')
-rw-r--r--common/flatpak-context.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/common/flatpak-context.c b/common/flatpak-context.c
index 32fb07b5..cc235d54 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) ||