shared/conf-parser: use chase() in config_parse_many_files()

The function was partially implementing chroot lookups. It would be given
file names that were prefixed with the chroot, so it would mostly work.
But if any of those files were symlinks, fopen() would do the wrong thing.

Also we don't need locking.

So give 'root' as the argument and use chase_and_fopen_unlocked() to get
proper chroot-aware lookups.

The only place where config_parse_many() is called with root is is repart.c.
So this is a follow-up for e594a3b154 and
34f2fd5096.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2024-02-21 22:29:56 +01:00
parent 9bc7493098
commit d8a91c6b9f
2 changed files with 18 additions and 21 deletions

View File

@@ -8,6 +8,7 @@
#include <sys/types.h>
#include "alloc-util.h"
#include "chase.h"
#include "conf-files.h"
#include "conf-parser.h"
#include "constants.h"
@@ -480,6 +481,7 @@ int hashmap_put_stats_by_path(Hashmap **stats_by_path, const char *path, const s
}
static int config_parse_many_files(
const char *root,
const char* const* conf_files,
char **files,
const char *sections,
@@ -502,19 +504,16 @@ static int config_parse_many_files(
}
STRV_FOREACH(fn, files) {
_cleanup_free_ struct stat *st_dropin = NULL;
_cleanup_fclose_ FILE *f = NULL;
int fd;
_cleanup_free_ char *fname = NULL;
f = fopen(*fn, "re");
if (!f) {
if (errno == ENOENT)
continue;
r = chase_and_fopen_unlocked(*fn, root, CHASE_AT_RESOLVE_IN_ROOT, "re", &fname, &f);
if (r == -ENOENT)
continue;
if (r < 0)
return r;
return -errno;
}
fd = fileno(f);
int fd = fileno(f);
r = ordered_hashmap_ensure_put(&dropins, &config_file_hash_ops_fclose, *fn, f);
if (r < 0) {
@@ -527,7 +526,7 @@ static int config_parse_many_files(
/* Get inodes for all drop-ins. Later we'll verify if main config is a symlink to or is
* symlinked as one of them. If so, we skip reading main config file directly. */
st_dropin = new(struct stat, 1);
_cleanup_free_ struct stat *st_dropin = new(struct stat, 1);
if (!st_dropin)
return -ENOMEM;
@@ -543,13 +542,11 @@ static int config_parse_many_files(
STRV_FOREACH(fn, conf_files) {
_cleanup_fclose_ FILE *f = NULL;
f = fopen(*fn, "re");
if (!f) {
if (errno == ENOENT)
continue;
return -errno;
}
r = chase_and_fopen_unlocked(*fn, root, CHASE_AT_RESOLVE_IN_ROOT, "re", NULL, &f);
if (r == -ENOENT)
continue;
if (r < 0)
return r;
if (inodes) {
if (fstat(fileno(f), &st) < 0)
@@ -642,7 +639,7 @@ int config_parse_config_file(
const char *sysconf_file = strjoina(SYSCONF_DIR, "/", conf_file);
return config_parse_many_files(STRV_MAKE_CONST(sysconf_file), dropins,
return config_parse_many_files(NULL, STRV_MAKE_CONST(sysconf_file), dropins,
sections, lookup, table, flags, userdata, NULL);
}
@@ -672,7 +669,7 @@ int config_parse_many(
if (r < 0)
return r;
r = config_parse_many_files(conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path);
r = config_parse_many_files(root, conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path);
if (r < 0)
return r;

View File

@@ -106,7 +106,7 @@ int config_parse_many(
const char* const* conf_file_dirs,
const char *dropin_dirname,
const char *root,
const char *sections, /* nulstr */
const char *sections, /* nulstr */
ConfigItemLookup lookup,
const void *table,
ConfigParseFlags flags,