diff --git a/src/libostree/ostree-repo-file.c b/src/libostree/ostree-repo-file.c index 016bbb3c..8e5f0fe3 100644 --- a/src/libostree/ostree-repo-file.c +++ b/src/libostree/ostree-repo-file.c @@ -236,6 +236,9 @@ do_resolve_nonroot (OstreeRepoFile *self, g_variant_get_child (container, i, "(&s&s&s)", &name, &content_checksum, &metadata_checksum); + + if (!ot_util_validate_file_name (name, error)) + goto out; if (!ostree_repo_load_variant_checked (self->repo, OSTREE_SERIALIZED_TREE_VARIANT, content_checksum, &tree_contents, diff --git a/src/libotutil/ot-unix-utils.c b/src/libotutil/ot-unix-utils.c index 24fcf8b3..2a2697f8 100644 --- a/src/libotutil/ot-unix-utils.c +++ b/src/libotutil/ot-unix-utils.c @@ -139,6 +139,31 @@ ot_util_filename_has_dotdot (const char *path) return last == '\0' || last == '/'; } +gboolean +ot_util_validate_file_name (const char *name, + GError **error) +{ + if (strcmp (name, ".") == 0) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid self-reference '.' in filename '%s'", name); + return FALSE; + } + if (ot_util_filename_has_dotdot (name)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid path uplink '..' in filename '%s'", name); + return FALSE; + } + if (strchr (name, '/') != NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid / in filename '%s'", name); + return FALSE; + } + return TRUE; +} + GPtrArray * ot_util_path_split (const char *path) { diff --git a/src/libotutil/ot-unix-utils.h b/src/libotutil/ot-unix-utils.h index 8b392cb9..59f8ef21 100644 --- a/src/libotutil/ot-unix-utils.h +++ b/src/libotutil/ot-unix-utils.h @@ -45,6 +45,9 @@ void ot_util_fatal_gerror (GError *error) G_GNUC_NORETURN; gboolean ot_util_filename_has_dotdot (const char *path); +gboolean ot_util_validate_file_name (const char *name, + GError **error); + GPtrArray *ot_util_sort_filenames_by_component_length (GPtrArray *files); GPtrArray* ot_util_path_split (const char *path);