From: Yu Watanabe Date: Sun, 29 Jun 2025 20:22:53 +0000 (+0900) Subject: pretty-print: make conf_files_cat() not show files outside of the specified root. X-Git-Tag: v258-rc1~101^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=661b5bfd216e383ac7836261eea9671875e6709b;p=thirdparty%2Fsystemd.git pretty-print: make conf_files_cat() not show files outside of the specified root. Then, make the function show the original and resolved path if they are different. With this change, procfs needs to be mounted on /proc/, hence the test code is slightly updated. --- diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c index 65f77e4cc9e..cbcf2a4be21 100644 --- a/src/shared/pretty-print.c +++ b/src/shared/pretty-print.c @@ -6,6 +6,7 @@ #include #include "alloc-util.h" +#include "chase.h" #include "color-util.h" #include "conf-files.h" #include "constants.h" @@ -13,6 +14,7 @@ #include "errno-util.h" #include "fd-util.h" #include "fileio.h" +#include "fs-util.h" #include "log.h" #include "path-util.h" #include "pretty-print.h" @@ -184,12 +186,15 @@ int terminal_urlify_man(const char *page, const char *section, char **ret) { return terminal_urlify(url, text, ret); } -static int cat_file(const char *filename, bool *newline, CatFlags flags) { +static int cat_file(const ConfFile *c, bool *newline, CatFlags flags) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *urlified = NULL, *section = NULL, *old_section = NULL; int r; - assert(filename); + assert(c); + assert(c->original_path); + assert(c->resolved_path); + assert(c->fd >= 0); if (newline) { if (*newline) @@ -197,25 +202,29 @@ static int cat_file(const char *filename, bool *newline, CatFlags flags) { *newline = true; } - r = terminal_urlify_path(filename, NULL, &urlified); + bool resolved = !path_equal(c->original_path, c->resolved_path); + + r = terminal_urlify_path(c->resolved_path, NULL, &urlified); if (r < 0) - return log_error_errno(r, "Failed to urlify path \"%s\": %m", filename); + return log_error_errno(r, "Failed to urlify path \"%s\": %m", c->resolved_path); - printf("%s# %s%s\n", + printf("%s# %s%s%s%s\n", ansi_highlight_blue(), + resolved ? c->original_path : "", + resolved ? " -> " : "", urlified, ansi_normal()); - f = fopen(filename, "re"); + f = fopen(FORMAT_PROC_FD_PATH(c->fd), "re"); if (!f) - return log_error_errno(errno, "Failed to open \"%s\": %m", filename); + return log_error_errno(errno, "Failed to open \"%s\": %m", c->resolved_path); for (bool continued = false;;) { _cleanup_free_ char *line = NULL; r = read_line(f, LONG_LINE_MAX, &line); if (r < 0) - return log_error_errno(r, "Failed to read \"%s\": %m", filename); + return log_error_errno(r, "Failed to read \"%s\": %m", c->resolved_path); if (r == 0) break; @@ -296,15 +305,43 @@ static int cat_file(const char *filename, bool *newline, CatFlags flags) { return 0; } -int cat_files(const char *file, char **dropins, CatFlags flags) { +int cat_files_full(const ConfFile *file, ConfFile * const *dropins, size_t n_dropins, CatFlags flags) { bool newline = false; int ret = 0; + assert(dropins || n_dropins == 0); + if (file) ret = cat_file(file, &newline, flags); + FOREACH_ARRAY(i, dropins, n_dropins) + RET_GATHER(ret, cat_file(*i, &newline, flags)); + + return ret; +} + +static int cat_file_by_path(const char *p, bool *newline, CatFlags flags) { + _cleanup_(conf_file_freep) ConfFile *c = NULL; + int r; + + assert(p); + + r = conf_file_new(p, /* root = */ NULL, CHASE_MUST_BE_REGULAR, &c); + if (r < 0) + return log_error_errno(r, "Failed to chase '%s': %m", p); + + return cat_file(c, newline, flags); +} + +int cat_files(const char *file, char **dropins, CatFlags flags) { + bool newline = false; + int ret = 0; + + if (file) + ret = cat_file_by_path(file, &newline, flags); + STRV_FOREACH(path, dropins) - RET_GATHER(ret, cat_file(*path, &newline, flags)); + RET_GATHER(ret, cat_file_by_path(*path, &newline, flags)); return ret; } @@ -384,8 +421,7 @@ static int guess_type(const char **name, char ***ret_prefixes, bool *ret_is_coll } int conf_files_cat(const char *root, const char *name, CatFlags flags) { - _cleanup_strv_free_ char **dirs = NULL, **files = NULL; - _cleanup_free_ char *path = NULL; + _cleanup_strv_free_ char **dirs = NULL; char **prefixes = NULL; /* explicit initialization to appease gcc */ bool is_collection; const char *extension; @@ -416,17 +452,18 @@ int conf_files_cat(const char *root, const char *name, CatFlags flags) { } /* First locate the main config file, if any */ + _cleanup_(conf_file_freep) ConfFile *c = NULL; if (!is_collection) { STRV_FOREACH(prefix, prefixes) { - path = path_join(root, *prefix, name); - if (!path) + _cleanup_free_ char *p = path_join(*prefix, name); + if (!p) return log_oom(); - if (access(path, F_OK) == 0) + + if (conf_file_new(p, root, CHASE_MUST_BE_REGULAR, &c) >= 0) break; - path = mfree(path); } - if (!path) + if (!c) printf("%s# Main configuration file %s not found%s\n", ansi_highlight_magenta(), name, @@ -434,7 +471,10 @@ int conf_files_cat(const char *root, const char *name, CatFlags flags) { } /* Then locate the drop-ins, if any */ - r = conf_files_list_strv(&files, extension, root, 0, (const char* const*) dirs); + ConfFile **dropins = NULL; + size_t n_dropins = 0; + CLEANUP_ARRAY(dropins, n_dropins, conf_file_free_many); + r = conf_files_list_strv_full(extension, root, CONF_FILES_REGULAR | CONF_FILES_FILTER_MASKED, (const char* const*) dirs, &dropins, &n_dropins); if (r < 0) return log_error_errno(r, "Failed to query file list: %m"); @@ -442,7 +482,7 @@ int conf_files_cat(const char *root, const char *name, CatFlags flags) { if (is_collection) flags |= CAT_FORMAT_HAS_SECTIONS; - return cat_files(path, files, flags); + return cat_files_full(c, dropins, n_dropins, flags); } int terminal_tint_color(double hue, char **ret) { diff --git a/src/shared/pretty-print.h b/src/shared/pretty-print.h index fc0ba5355f8..56491886fa2 100644 --- a/src/shared/pretty-print.h +++ b/src/shared/pretty-print.h @@ -30,6 +30,7 @@ typedef enum CatFlags { CAT_TLDR = 1 << 2, /* Only print comments and relevant section headers */ } CatFlags; +int cat_files_full(const ConfFile *file, ConfFile * const *dropins, size_t n_dropins, CatFlags flags); int cat_files(const char *file, char **dropins, CatFlags flags); int conf_files_cat(const char *root, const char *name, CatFlags flags); diff --git a/test/units/TEST-65-ANALYZE.sh b/test/units/TEST-65-ANALYZE.sh index 7fd4543e76a..5a5a9ba206d 100755 --- a/test/units/TEST-65-ANALYZE.sh +++ b/test/units/TEST-65-ANALYZE.sh @@ -313,6 +313,7 @@ if [[ ! -v ASAN_OPTIONS ]]; then # check that systemd-analyze cat-config paths work in a chroot mkdir -p /tmp/root mount --bind / /tmp/root + mount -t proc proc /tmp/root/proc if mountpoint -q /usr; then mount --bind /usr /tmp/root/usr fi