exec-util,conf-files: skip non-executable files in execute_directories()

Fixes: #6787
This commit is contained in:
Lennart Poettering 2017-09-12 16:57:33 +02:00
parent 586377fc92
commit b50846055e
22 changed files with 68 additions and 35 deletions

View file

@ -32,11 +32,12 @@
#include "macro.h" #include "macro.h"
#include "missing.h" #include "missing.h"
#include "path-util.h" #include "path-util.h"
#include "stat-util.h"
#include "string-util.h" #include "string-util.h"
#include "strv.h" #include "strv.h"
#include "util.h" #include "util.h"
static int files_add(Hashmap *h, const char *root, const char *path, const char *suffix) { static int files_add(Hashmap *h, const char *suffix, const char *root, unsigned flags, const char *path) {
_cleanup_closedir_ DIR *dir = NULL; _cleanup_closedir_ DIR *dir = NULL;
const char *dirpath; const char *dirpath;
struct dirent *de; struct dirent *de;
@ -59,6 +60,31 @@ static int files_add(Hashmap *h, const char *root, const char *path, const char
if (!dirent_is_file_with_suffix(de, suffix)) if (!dirent_is_file_with_suffix(de, suffix))
continue; continue;
if (flags & CONF_FILES_EXECUTABLE) {
struct stat st;
/* As requested: check if the file is marked exectuable. Note that we don't check access(X_OK)
* here, as we care about whether the file is marked executable at all, and not whether it is
* executable for us, because if such errors are stuff we should log about. */
if (fstatat(dirfd(dir), de->d_name, &st, 0) < 0) {
log_debug_errno(errno, "Failed to stat %s/%s, ignoring: %m", dirpath, de->d_name);
continue;
}
/* We only want executable regular files (or symlinks to them), or symlinks to /dev/null */
if (S_ISREG(st.st_mode)) {
if ((st.st_mode & 0111) == 0) { /* not executable */
log_debug("Ignoring %s/%s, as it is not marked executable.", dirpath, de->d_name);
continue;
}
} else if (!null_or_empty(&st)) { /* /dev/null? */
log_debug("Ignoring %s/%s, as it is not a regular file (or symlink to /dev/null).", dirpath, de->d_name);
continue;
}
}
p = strjoin(dirpath, "/", de->d_name); p = strjoin(dirpath, "/", de->d_name);
if (!p) if (!p)
return -ENOMEM; return -ENOMEM;
@ -87,7 +113,7 @@ static int base_cmp(const void *a, const void *b) {
return strcmp(basename(s1), basename(s2)); return strcmp(basename(s1), basename(s2));
} }
static int conf_files_list_strv_internal(char ***strv, const char *suffix, const char *root, char **dirs) { static int conf_files_list_strv_internal(char ***strv, const char *suffix, const char *root, unsigned flags, char **dirs) {
_cleanup_hashmap_free_ Hashmap *fh = NULL; _cleanup_hashmap_free_ Hashmap *fh = NULL;
char **files, **p; char **files, **p;
int r; int r;
@ -103,7 +129,7 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const
return -ENOMEM; return -ENOMEM;
STRV_FOREACH(p, dirs) { STRV_FOREACH(p, dirs) {
r = files_add(fh, root, *p, suffix); r = files_add(fh, suffix, root, flags, *p);
if (r == -ENOMEM) if (r == -ENOMEM)
return r; return r;
if (r < 0) if (r < 0)
@ -120,7 +146,7 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const
return 0; return 0;
} }
int conf_files_list_strv(char ***strv, const char *suffix, const char *root, const char* const* dirs) { int conf_files_list_strv(char ***strv, const char *suffix, const char *root, unsigned flags, const char* const* dirs) {
_cleanup_strv_free_ char **copy = NULL; _cleanup_strv_free_ char **copy = NULL;
assert(strv); assert(strv);
@ -129,10 +155,10 @@ int conf_files_list_strv(char ***strv, const char *suffix, const char *root, con
if (!copy) if (!copy)
return -ENOMEM; return -ENOMEM;
return conf_files_list_strv_internal(strv, suffix, root, copy); return conf_files_list_strv_internal(strv, suffix, root, flags, copy);
} }
int conf_files_list(char ***strv, const char *suffix, const char *root, const char *dir, ...) { int conf_files_list(char ***strv, const char *suffix, const char *root, unsigned flags, const char *dir, ...) {
_cleanup_strv_free_ char **dirs = NULL; _cleanup_strv_free_ char **dirs = NULL;
va_list ap; va_list ap;
@ -145,10 +171,10 @@ int conf_files_list(char ***strv, const char *suffix, const char *root, const ch
if (!dirs) if (!dirs)
return -ENOMEM; return -ENOMEM;
return conf_files_list_strv_internal(strv, suffix, root, dirs); return conf_files_list_strv_internal(strv, suffix, root, flags, dirs);
} }
int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, const char *d) { int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, unsigned flags, const char *d) {
_cleanup_strv_free_ char **dirs = NULL; _cleanup_strv_free_ char **dirs = NULL;
assert(strv); assert(strv);
@ -157,5 +183,5 @@ int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, c
if (!dirs) if (!dirs)
return -ENOMEM; return -ENOMEM;
return conf_files_list_strv_internal(strv, suffix, root, dirs); return conf_files_list_strv_internal(strv, suffix, root, flags, dirs);
} }

View file

@ -20,6 +20,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>. along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/ ***/
int conf_files_list(char ***ret, const char *suffix, const char *root, const char *dir, ...); enum {
int conf_files_list_strv(char ***ret, const char *suffix, const char *root, const char* const* dirs); CONF_FILES_EXECUTABLE = 1,
int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, const char *dirs); };
int conf_files_list(char ***ret, const char *suffix, const char *root, unsigned flags, const char *dir, ...);
int conf_files_list_strv(char ***ret, const char *suffix, const char *root, unsigned flags, const char* const* dirs);
int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, unsigned flags, const char *dirs);

View file

@ -111,7 +111,7 @@ static int do_execute(
assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
r = conf_files_list_strv(&paths, NULL, NULL, (const char* const*) directories); r = conf_files_list_strv(&paths, NULL, NULL, CONF_FILES_EXECUTABLE, (const char* const*) directories);
if (r < 0) if (r < 0)
return r; return r;

View file

@ -182,7 +182,7 @@ int main(int argc, char *argv[]) {
_cleanup_strv_free_ char **files = NULL; _cleanup_strv_free_ char **files = NULL;
char **f; char **f;
r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs); r = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to enumerate binfmt.d files: %m"); log_error_errno(r, "Failed to enumerate binfmt.d files: %m");
goto finish; goto finish;

View file

@ -58,7 +58,7 @@ static int load_and_print(void) {
if (r < 0) if (r < 0)
return r; return r;
r = conf_files_list_strv(&files, ".conf", NULL, (const char **) dirs); r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char **) dirs);
if (r < 0) if (r < 0)
return r; return r;

View file

@ -653,7 +653,7 @@ static int hwdb_update(int argc, char *argv[], void *userdata) {
trie->nodes_count++; trie->nodes_count++;
r = conf_files_list_strv(&files, ".hwdb", arg_root, conf_file_dirs); r = conf_files_list_strv(&files, ".hwdb", arg_root, 0, conf_file_dirs);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enumerate hwdb files: %m"); return log_error_errno(r, "Failed to enumerate hwdb files: %m");

View file

@ -479,7 +479,7 @@ int catalog_update(const char* database, const char* root, const char* const* di
goto finish; goto finish;
} }
r = conf_files_list_strv(&files, ".catalog", root, dirs); r = conf_files_list_strv(&files, ".catalog", root, 0, dirs);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to get catalog files: %m"); log_error_errno(r, "Failed to get catalog files: %m");
goto finish; goto finish;

View file

@ -264,7 +264,7 @@ int main(int argc, char *argv[]) {
r = k; r = k;
} }
k = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs); k = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
if (k < 0) { if (k < 0) {
log_error_errno(k, "Failed to enumerate modules-load.d files: %m"); log_error_errno(k, "Failed to enumerate modules-load.d files: %m");
if (r == 0) if (r == 0)

View file

@ -766,7 +766,7 @@ int netdev_load(Manager *manager) {
while ((netdev = hashmap_first(manager->netdevs))) while ((netdev = hashmap_first(manager->netdevs)))
netdev_unref(netdev); netdev_unref(netdev);
r = conf_files_list_strv(&files, ".netdev", NULL, network_dirs); r = conf_files_list_strv(&files, ".netdev", NULL, 0, network_dirs);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enumerate netdev files: %m"); return log_error_errno(r, "Failed to enumerate netdev files: %m");

View file

@ -322,7 +322,7 @@ int network_load(Manager *manager) {
while ((network = manager->networks)) while ((network = manager->networks))
network_free(network); network_free(network);
r = conf_files_list_strv(&files, ".network", NULL, network_dirs); r = conf_files_list_strv(&files, ".network", NULL, 0, network_dirs);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enumerate network files: %m"); return log_error_errno(r, "Failed to enumerate network files: %m");

View file

@ -435,7 +435,7 @@ static int dns_trust_anchor_load_files(
assert(suffix); assert(suffix);
assert(loader); assert(loader);
r = conf_files_list_nulstr(&files, suffix, NULL, trust_anchor_dirs); r = conf_files_list_nulstr(&files, suffix, NULL, 0, trust_anchor_dirs);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enumerate %s trust anchor files: %m", suffix); return log_error_errno(r, "Failed to enumerate %s trust anchor files: %m", suffix);

View file

@ -436,7 +436,7 @@ int config_parse_many_nulstr(
_cleanup_strv_free_ char **files = NULL; _cleanup_strv_free_ char **files = NULL;
int r; int r;
r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs); r = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
if (r < 0) if (r < 0)
return r; return r;
@ -465,7 +465,7 @@ int config_parse_many(
if (r < 0) if (r < 0)
return r; return r;
r = conf_files_list_strv(&files, ".conf", NULL, (const char* const*) dropin_dirs); r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char* const*) dropin_dirs);
if (r < 0) if (r < 0)
return r; return r;

View file

@ -203,7 +203,7 @@ int unit_file_find_dropin_paths(
return 0; return 0;
} }
r = conf_files_list_strv(ret, file_suffix, NULL, (const char**) dirs); r = conf_files_list_strv(ret, file_suffix, NULL, 0, (const char**) dirs);
if (r < 0) if (r < 0)
return log_warning_errno(r, "Failed to create the list of configuration files: %m"); return log_warning_errno(r, "Failed to create the list of configuration files: %m");

View file

@ -2662,7 +2662,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
assert(presets); assert(presets);
if (scope == UNIT_FILE_SYSTEM) if (scope == UNIT_FILE_SYSTEM)
r = conf_files_list(&files, ".preset", root_dir, r = conf_files_list(&files, ".preset", root_dir, 0,
"/etc/systemd/system-preset", "/etc/systemd/system-preset",
"/usr/local/lib/systemd/system-preset", "/usr/local/lib/systemd/system-preset",
"/usr/lib/systemd/system-preset", "/usr/lib/systemd/system-preset",
@ -2671,7 +2671,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
#endif #endif
NULL); NULL);
else if (scope == UNIT_FILE_GLOBAL) else if (scope == UNIT_FILE_GLOBAL)
r = conf_files_list(&files, ".preset", root_dir, r = conf_files_list(&files, ".preset", root_dir, 0,
"/etc/systemd/user-preset", "/etc/systemd/user-preset",
"/usr/local/lib/systemd/user-preset", "/usr/local/lib/systemd/user-preset",
"/usr/lib/systemd/user-preset", "/usr/lib/systemd/user-preset",

View file

@ -91,7 +91,10 @@ static int execute(char **modes, char **states) {
arg_verb, arg_verb,
NULL NULL
}; };
static const char* const dirs[] = {SYSTEM_SLEEP_PATH, NULL}; static const char* const dirs[] = {
SYSTEM_SLEEP_PATH,
NULL
};
int r; int r;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;

View file

@ -280,7 +280,7 @@ int main(int argc, char *argv[]) {
_cleanup_strv_free_ char **files = NULL; _cleanup_strv_free_ char **files = NULL;
char **f; char **f;
r = conf_files_list_nulstr(&files, ".conf", NULL, conf_file_dirs); r = conf_files_list_nulstr(&files, ".conf", NULL, 0, conf_file_dirs);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to enumerate sysctl.d files: %m"); log_error_errno(r, "Failed to enumerate sysctl.d files: %m");
goto finish; goto finish;

View file

@ -1798,7 +1798,7 @@ int main(int argc, char *argv[]) {
_cleanup_strv_free_ char **files = NULL; _cleanup_strv_free_ char **files = NULL;
char **f; char **f;
r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs); r = conf_files_list_nulstr(&files, ".conf", arg_root, 0, conf_file_dirs);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to enumerate sysusers.d files: %m"); log_error_errno(r, "Failed to enumerate sysusers.d files: %m");
goto finish; goto finish;

View file

@ -75,7 +75,7 @@ static void test_conf_files_list(bool use_root) {
log_debug("/* Check when filtered by suffix */"); log_debug("/* Check when filtered by suffix */");
assert_se(conf_files_list(&found_files, ".conf", root_dir, search_1, search_2, NULL) == 0); assert_se(conf_files_list(&found_files, ".conf", root_dir, 0, search_1, search_2, NULL) == 0);
strv_print(found_files); strv_print(found_files);
assert_se(found_files); assert_se(found_files);
@ -84,7 +84,7 @@ static void test_conf_files_list(bool use_root) {
assert_se(found_files[2] == NULL); assert_se(found_files[2] == NULL);
log_debug("/* Check when unfiltered */"); log_debug("/* Check when unfiltered */");
assert_se(conf_files_list(&found_files2, NULL, root_dir, search_1, search_2, NULL) == 0); assert_se(conf_files_list(&found_files2, NULL, root_dir, 0, search_1, search_2, NULL) == 0);
strv_print(found_files2); strv_print(found_files2);
assert_se(found_files2); assert_se(found_files2);

View file

@ -2300,7 +2300,7 @@ int main(int argc, char *argv[]) {
_cleanup_strv_free_ char **files = NULL; _cleanup_strv_free_ char **files = NULL;
char **f; char **f;
r = conf_files_list_nulstr(&files, ".conf", arg_root, conf_file_dirs); r = conf_files_list_nulstr(&files, ".conf", arg_root, 0, conf_file_dirs);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m"); log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
goto finish; goto finish;

View file

@ -213,7 +213,7 @@ int link_config_load(link_config_ctx *ctx) {
/* update timestamp */ /* update timestamp */
paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, true); paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, true);
r = conf_files_list_strv(&files, ".link", NULL, link_dirs); r = conf_files_list_strv(&files, ".link", NULL, 0, link_dirs);
if (r < 0) if (r < 0)
return log_error_errno(r, "failed to enumerate link files: %m"); return log_error_errno(r, "failed to enumerate link files: %m");

View file

@ -1533,7 +1533,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) {
udev_rules_check_timestamp(rules); udev_rules_check_timestamp(rules);
r = conf_files_list_strv(&files, ".rules", NULL, rules_dirs); r = conf_files_list_strv(&files, ".rules", NULL, 0, rules_dirs);
if (r < 0) { if (r < 0) {
log_error_errno(r, "failed to enumerate rules files: %m"); log_error_errno(r, "failed to enumerate rules files: %m");
return udev_rules_unref(rules); return udev_rules_unref(rules);

View file

@ -627,7 +627,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
} }
trie->nodes_count++; trie->nodes_count++;
err = conf_files_list_strv(&files, ".hwdb", root, conf_file_dirs); err = conf_files_list_strv(&files, ".hwdb", root, 0, conf_file_dirs);
if (err < 0) { if (err < 0) {
log_error_errno(err, "failed to enumerate hwdb files: %m"); log_error_errno(err, "failed to enumerate hwdb files: %m");
rc = EXIT_FAILURE; rc = EXIT_FAILURE;