]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
exec-util,conf-files: skip non-executable files in execute_directories()
authorLennart Poettering <lennart@poettering.net>
Tue, 12 Sep 2017 14:57:33 +0000 (16:57 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 13 Sep 2017 09:42:31 +0000 (11:42 +0200)
Fixes: #6787
22 files changed:
src/basic/conf-files.c
src/basic/conf-files.h
src/basic/exec-util.c
src/binfmt/binfmt.c
src/environment-d-generator/environment-d-generator.c
src/hwdb/hwdb.c
src/journal/catalog.c
src/modules-load/modules-load.c
src/network/netdev/netdev.c
src/network/networkd-network.c
src/resolve/resolved-dns-trust-anchor.c
src/shared/conf-parser.c
src/shared/dropin.c
src/shared/install.c
src/sleep/sleep.c
src/sysctl/sysctl.c
src/sysusers/sysusers.c
src/test/test-conf-files.c
src/tmpfiles/tmpfiles.c
src/udev/net/link-config.c
src/udev/udev-rules.c
src/udev/udevadm-hwdb.c

index b8f0f5d03d227e370d0db4b6a5aa07e152b89016..21921a43e104c889a0fb848c91db4891ced44ba0 100644 (file)
 #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);
 }
index e00e0e81fbd3713e5a5d8d49f1285e2227c6a6a5..20ecf6e5f15da0ec9dd8d70ce0adccb67b44d9e0 100644 (file)
   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);
index aced9e8e3db80004d2b5d398ed36640bf032e3a2..ade8511466c81d1cdef6983b35424be88f72d818 100644 (file)
@@ -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;
 
index eeef04fb1ce4da627e594ea880867983e4214be1..17af233ef88d0595d9d6fe90ea36dfba1c0e0a08 100644 (file)
@@ -182,7 +182,7 @@ int main(int argc, char *argv[]) {
                 _cleanup_strv_free_ char **files = NULL;
                 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) {
                         log_error_errno(r, "Failed to enumerate binfmt.d files: %m");
                         goto finish;
index 9c7250237340a3814e4e3db23edeef6a19559f85..55de68550d10447e74442d4e42ee05b1231b2b8c 100644 (file)
@@ -58,7 +58,7 @@ static int load_and_print(void) {
         if (r < 0)
                 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)
                 return r;
 
index ead4e1770b953727349578f97b3b7a291ff9f6dc..c964a28bce588d5cdcc3d542f3143bc06bb5493f 100644 (file)
@@ -653,7 +653,7 @@ static int hwdb_update(int argc, char *argv[], void *userdata) {
 
         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)
                 return log_error_errno(r, "Failed to enumerate hwdb files: %m");
 
index 886f6efd8bd2da917f24b75c36c6843accdfd56a..f42be0adf945a5dd732a96d0b1e6813459d6b253 100644 (file)
@@ -479,7 +479,7 @@ int catalog_update(const char* database, const char* root, const char* const* di
                 goto finish;
         }
 
-        r = conf_files_list_strv(&files, ".catalog", root, dirs);
+        r = conf_files_list_strv(&files, ".catalog", root, 0, dirs);
         if (r < 0) {
                 log_error_errno(r, "Failed to get catalog files: %m");
                 goto finish;
index 615998a6f60d679a04e2c87b0716e3e18ed9e801..6efebcd94fdecfeec784f98adf97ce5e939e4be8 100644 (file)
@@ -264,7 +264,7 @@ int main(int argc, char *argv[]) {
                                 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) {
                         log_error_errno(k, "Failed to enumerate modules-load.d files: %m");
                         if (r == 0)
index 1cf72bf6d29d4418a8857315c4963cdcc786e084..0e1a7d1335e9902d6411dadcff13eade68c6e6de 100644 (file)
@@ -766,7 +766,7 @@ int netdev_load(Manager *manager) {
         while ((netdev = hashmap_first(manager->netdevs)))
                 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)
                 return log_error_errno(r, "Failed to enumerate netdev files: %m");
 
index a873e55d4c2740f4adfdb816aade5e19b00bb00d..3b52a8a5b96f97d19d03f3f1e7bbcb855181cd4c 100644 (file)
@@ -322,7 +322,7 @@ int network_load(Manager *manager) {
         while ((network = manager->networks))
                 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)
                 return log_error_errno(r, "Failed to enumerate network files: %m");
 
index dda98750632c496733d1349170f30027f3f9828e..e169c8f02f887a22110607dfbdc7b492cdf9e19a 100644 (file)
@@ -435,7 +435,7 @@ static int dns_trust_anchor_load_files(
         assert(suffix);
         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)
                 return log_error_errno(r, "Failed to enumerate %s trust anchor files: %m", suffix);
 
index e08402e3d22ea54e785c8d4bac71f490d9e8a797..8b01b3bf7359542a9974b1af96908103551541d8 100644 (file)
@@ -436,7 +436,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;
 
index 7d8fbeb4359b43cedc02a904c17a04065d6021bc..059b50dbd0e26c47d33ff8e9abcd83390c3d0a00 100644 (file)
@@ -203,7 +203,7 @@ int unit_file_find_dropin_paths(
                 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)
                 return log_warning_errno(r, "Failed to create the list of configuration files: %m");
 
index d0a291b819b6714bc97c1a0217749a9d9184c69c..9e4e0eaf6fd7a89cc33ad5a57605a7486e4b4c82 100644 (file)
@@ -2662,7 +2662,7 @@ static int read_presets(UnitFileScope scope, const char *root_dir, Presets *pres
         assert(presets);
 
         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",
                                     "/usr/local/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
                                     NULL);
         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",
                                     "/usr/local/lib/systemd/user-preset",
                                     "/usr/lib/systemd/user-preset",
index 3bac78b3e4cc84529bb1637175bbda3df51dda92..4c171a2fe5da8d585803f6b5c4adafefa25e394b 100644 (file)
@@ -91,7 +91,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;
index 41a6dcbd1b0264905f01dd25b3de6214069b11b9..ce4ff8c8a3ea25afb13fdeabd481a0a3e927663f 100644 (file)
@@ -280,7 +280,7 @@ int main(int argc, char *argv[]) {
                 _cleanup_strv_free_ char **files = NULL;
                 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) {
                         log_error_errno(r, "Failed to enumerate sysctl.d files: %m");
                         goto finish;
index 448f584733629112a8abe1f53ffe48cc1cc5f958..e3842192337c67d76aef221519841a34691eb57a 100644 (file)
@@ -1798,7 +1798,7 @@ int main(int argc, char *argv[]) {
                 _cleanup_strv_free_ char **files = NULL;
                 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) {
                         log_error_errno(r, "Failed to enumerate sysusers.d files: %m");
                         goto finish;
index 22b7c61204acab2a228a4e36ed3d743311e33e19..777b5ca32b0ec8d4ae61c4581e876e0c440e19f5 100644 (file)
@@ -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);
index 875a886bf3de9cbe92ca2bf060c09c3e4674e87b..3d3967f2719f3c62f5cc55fba8021633b9d25de1 100644 (file)
@@ -2300,7 +2300,7 @@ int main(int argc, char *argv[]) {
                 _cleanup_strv_free_ char **files = NULL;
                 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) {
                         log_error_errno(r, "Failed to enumerate tmpfiles.d files: %m");
                         goto finish;
index 05a186357c5233fb8d31d09c944ddab9d29fb81f..6ece1250f25ce3092a7572e86c4f4decd1d9e1e2 100644 (file)
@@ -213,7 +213,7 @@ int link_config_load(link_config_ctx *ctx) {
         /* update timestamp */
         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)
                 return log_error_errno(r, "failed to enumerate link files: %m");
 
index 294a3225472fa0ba1394d07bccc39c396038377b..76a1d35a19712a62a1181e106fb16c2846d6a96a 100644 (file)
@@ -1533,7 +1533,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) {
 
         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) {
                 log_error_errno(r, "failed to enumerate rules files: %m");
                 return udev_rules_unref(rules);
index 7688f8192b23ecdf644f0cd2ec967533fa15c588..4a23270dfb835de9da64c7fa5f18b9964b7a2824 100644 (file)
@@ -627,7 +627,7 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
                 }
                 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) {
                         log_error_errno(err, "failed to enumerate hwdb files: %m");
                         rc = EXIT_FAILURE;