From 1e29a967c76106db6980842b6bfb4b10f5b829c9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 1 Jul 2025 11:33:22 +0900 Subject: [PATCH] catalog: do not read catalog files outside of specified root directory --- src/fuzz/fuzz-catalog.c | 2 +- src/libsystemd/sd-journal/catalog.c | 23 +++++++++++++++-------- src/libsystemd/sd-journal/catalog.h | 2 +- src/libsystemd/sd-journal/test-catalog.c | 2 +- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/fuzz/fuzz-catalog.c b/src/fuzz/fuzz-catalog.c index 965828827a4..3c13db2c9b5 100644 --- a/src/fuzz/fuzz-catalog.c +++ b/src/fuzz/fuzz-catalog.c @@ -19,7 +19,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { assert_se(fd >= 0); assert_se(write(fd, data, size) == (ssize_t) size); - (void) catalog_import_file(&h, name); + (void) catalog_import_file(&h, fd, name); return 0; } diff --git a/src/libsystemd/sd-journal/catalog.c b/src/libsystemd/sd-journal/catalog.c index 3ca3b2dab47..ec0445f1227 100644 --- a/src/libsystemd/sd-journal/catalog.c +++ b/src/libsystemd/sd-journal/catalog.c @@ -263,7 +263,7 @@ static int catalog_entry_lang( return strdup_to(ret, t); } -int catalog_import_file(OrderedHashmap **h, const char *path) { +int catalog_import_file(OrderedHashmap **h, int fd, const char *path) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *payload = NULL; size_t payload_size = 0; @@ -274,9 +274,10 @@ int catalog_import_file(OrderedHashmap **h, const char *path) { int r; assert(h); + assert(fd >= 0); assert(path); - f = fopen(path, "re"); + f = fopen(FORMAT_PROC_FD_PATH(fd), "re"); if (!f) return log_error_errno(errno, "Failed to open file %s: %m", path); @@ -449,17 +450,23 @@ int catalog_update(const char *database, const char *root, const char* const *di if (!dirs) dirs = catalog_file_dirs; - _cleanup_strv_free_ char **files = NULL; - r = conf_files_list_strv(&files, ".catalog", root, 0, dirs); + ConfFile **files = NULL; + size_t n_files = 0; + + CLEANUP_ARRAY(files, n_files, conf_file_free_many); + + r = conf_files_list_strv_full(".catalog", root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, dirs, &files, &n_files); if (r < 0) return log_error_errno(r, "Failed to get catalog files: %m"); _cleanup_ordered_hashmap_free_ OrderedHashmap *h = NULL; - STRV_FOREACH(f, files) { - log_debug("Reading file '%s'", *f); - r = catalog_import_file(&h, *f); + FOREACH_ARRAY(i, files, n_files) { + ConfFile *c = *i; + + log_debug("Reading file: '%s' -> '%s'", c->original_path, c->resolved_path); + r = catalog_import_file(&h, c->fd, c->original_path); if (r < 0) - return log_error_errno(r, "Failed to import file '%s': %m", *f); + return log_error_errno(r, "Failed to import file '%s': %m", c->original_path); } if (ordered_hashmap_isempty(h)) { diff --git a/src/libsystemd/sd-journal/catalog.h b/src/libsystemd/sd-journal/catalog.h index c2a20aaddbf..b91bd188b5d 100644 --- a/src/libsystemd/sd-journal/catalog.h +++ b/src/libsystemd/sd-journal/catalog.h @@ -3,7 +3,7 @@ #include "forward.h" -int catalog_import_file(OrderedHashmap **h, const char *path); +int catalog_import_file(OrderedHashmap **h, int fd, const char *path); int catalog_update(const char *database, const char *root, const char* const *dirs); int catalog_get(const char *database, sd_id128_t id, char **ret_text); int catalog_list(FILE *f, const char *database, bool oneline); diff --git a/src/libsystemd/sd-journal/test-catalog.c b/src/libsystemd/sd-journal/test-catalog.c index d86fd533f7b..51e113b3fc6 100644 --- a/src/libsystemd/sd-journal/test-catalog.c +++ b/src/libsystemd/sd-journal/test-catalog.c @@ -31,7 +31,7 @@ static OrderedHashmap* test_import(const char* contents, ssize_t size, int code) assert_se(fd >= 0); assert_se(write(fd, contents, size) == size); - assert_se(catalog_import_file(&h, name) == code); + assert_se(catalog_import_file(&h, fd, name) == code); return h; } -- 2.47.3