summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2017-09-12 16:57:33 +0200
committerSven Eden <yamakuzure@gmx.net>2017-09-25 14:37:36 +0200
commit3053a76e3f84eea8e4f0f8245efadda5c4917c1b (patch)
tree5481ecffd2cba2306befaba6b175f0f580ceacd6 /src
parent0b0f1f6bc9447ad0d8abad941e384868b2932828 (diff)
exec-util,conf-files: skip non-executable files in execute_directories()
Fixes: #6787
Diffstat (limited to 'src')
-rw-r--r--src/basic/conf-files.c44
-rw-r--r--src/basic/conf-files.h10
-rw-r--r--src/basic/exec-util.c2
-rw-r--r--src/shared/conf-parser.c10
-rw-r--r--src/sleep/sleep.c5
-rw-r--r--src/test/test-conf-files.c4
6 files changed, 51 insertions, 24 deletions
diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c
index b8f0f5d03..21921a43e 100644
--- a/src/basic/conf-files.c
+++ b/src/basic/conf-files.c
@@ -32,11 +32,12 @@
#include "macro.h"
#include "missing.h"
#include "path-util.h"
+#include "stat-util.h"
#include "string-util.h"
#include "strv.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;
const char *dirpath;
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))
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);
if (!p)
return -ENOMEM;
@@ -87,7 +113,7 @@ static int base_cmp(const void *a, const void *b) {
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;
char **files, **p;
int r;
@@ -103,7 +129,7 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const
return -ENOMEM;
STRV_FOREACH(p, dirs) {
- r = files_add(fh, root, *p, suffix);
+ r = files_add(fh, suffix, root, flags, *p);
if (r == -ENOMEM)
return r;
if (r < 0)
@@ -120,7 +146,7 @@ static int conf_files_list_strv_internal(char ***strv, const char *suffix, const
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;
assert(strv);
@@ -129,10 +155,10 @@ int conf_files_list_strv(char ***strv, const char *suffix, const char *root, con
if (!copy)
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;
va_list ap;
@@ -145,10 +171,10 @@ int conf_files_list(char ***strv, const char *suffix, const char *root, const ch
if (!dirs)
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;
assert(strv);
@@ -157,5 +183,5 @@ int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, c
if (!dirs)
return -ENOMEM;
- return conf_files_list_strv_internal(strv, suffix, root, dirs);
+ return conf_files_list_strv_internal(strv, suffix, root, flags, dirs);
}
diff --git a/src/basic/conf-files.h b/src/basic/conf-files.h
index e00e0e81f..20ecf6e5f 100644
--- a/src/basic/conf-files.h
+++ b/src/basic/conf-files.h
@@ -20,6 +20,10 @@
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, ...);
-int conf_files_list_strv(char ***ret, const char *suffix, const char *root, const char* const* dirs);
-int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, const char *dirs);
+enum {
+ CONF_FILES_EXECUTABLE = 1,
+};
+
+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);
diff --git a/src/basic/exec-util.c b/src/basic/exec-util.c
index e542d5c93..861af3264 100644
--- a/src/basic/exec-util.c
+++ b/src/basic/exec-util.c
@@ -111,7 +111,7 @@ static int do_execute(
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)
return r;
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
index c8a95c7f3..2437c1ca7 100644
--- a/src/shared/conf-parser.c
+++ b/src/shared/conf-parser.c
@@ -435,7 +435,7 @@ int config_parse_many_nulstr(
_cleanup_strv_free_ char **files = NULL;
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)
return r;
@@ -465,7 +465,7 @@ int config_parse_many(
if (r < 0)
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)
return r;
@@ -734,11 +734,6 @@ int config_parse_path(
assert(rvalue);
assert(data);
- if (isempty(rvalue)) {
- n = NULL;
- goto finalize;
- }
-
if (!utf8_is_valid(rvalue)) {
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, rvalue);
return fatal ? -ENOEXEC : 0;
@@ -757,7 +752,6 @@ int config_parse_path(
path_kill_slashes(n);
-finalize:
free(*s);
*s = n;
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index 4b402abcd..01fa22349 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -94,7 +94,10 @@ static int execute(char **modes, char **states) {
arg_verb,
NULL
};
- static const char* const dirs[] = {SYSTEM_SLEEP_PATH, NULL};
+ static const char* const dirs[] = {
+ SYSTEM_SLEEP_PATH,
+ NULL
+ };
int r;
_cleanup_fclose_ FILE *f = NULL;
diff --git a/src/test/test-conf-files.c b/src/test/test-conf-files.c
index 22b7c6120..777b5ca32 100644
--- a/src/test/test-conf-files.c
+++ b/src/test/test-conf-files.c
@@ -75,7 +75,7 @@ static void test_conf_files_list(bool use_root) {
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);
assert_se(found_files);
@@ -84,7 +84,7 @@ static void test_conf_files_list(bool use_root) {
assert_se(found_files[2] == NULL);
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);
assert_se(found_files2);