]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/load-fragment.c
tree-wide: use TAKE_PTR() and TAKE_FD() macros
[thirdparty/systemd.git] / src / core / load-fragment.c
index 00408c4b843c9139c31af2e70aeb04a5ae98c336..be4af94fc8f6169ce119f6a858b1652d83a5e85e 100644 (file)
 #include "utf8.h"
 #include "web-util.h"
 
-int config_parse_warn_compat(
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-        Disabled reason = ltype;
-
-        switch(reason) {
-        case DISABLED_CONFIGURATION:
-                log_syntax(unit, LOG_DEBUG, filename, line, 0,
-                           "Support for option %s= has been disabled at compile time and it is ignored", lvalue);
-                break;
-        case DISABLED_LEGACY:
-                log_syntax(unit, LOG_INFO, filename, line, 0,
-                           "Support for option %s= has been removed and it is ignored", lvalue);
-                break;
-        case DISABLED_EXPERIMENTAL:
-                log_syntax(unit, LOG_INFO, filename, line, 0,
-                           "Support for option %s= has not yet been enabled and it is ignored", lvalue);
-                break;
-        };
-
-        return 0;
-}
-
 DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode, "Failed to parse garbage collection mode");
 
 int config_parse_unit_deps(
@@ -257,11 +226,19 @@ int config_parse_unit_path_printf(
         assert(rvalue);
         assert(u);
 
+        /* Let's not bother with anything that is too long */
+        if (strlen(rvalue) >= PATH_MAX) {
+                log_syntax(unit, LOG_ERR, filename, line, 0,
+                           "%s value too long%s.",
+                           lvalue, fatal ? "" : ", ignoring");
+                return fatal ? -ENAMETOOLONG : 0;
+        }
+
         r = unit_full_printf(u, rvalue, &k);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r,
-                           "Failed to resolve unit specifiers on %s%s: %m",
-                           fatal ? "" : ", ignoring", rvalue);
+                           "Failed to resolve unit specifiers in \"%s\"%s: %m",
+                           rvalue, fatal ? "" : ", ignoring");
                 return fatal ? -ENOEXEC : 0;
         }
 
@@ -410,7 +387,6 @@ int config_parse_socket_listen(const char *unit,
                 if (r < 0) {
                         if (r != -EAFNOSUPPORT)
                                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse address value, ignoring: %s", rvalue);
-
                         return 0;
                 }
 
@@ -755,9 +731,9 @@ int config_parse_exec(
 
                         if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
                                 return log_oom();
-                        n[nlen++] = resolved;
+
+                        n[nlen++] = TAKE_PTR(resolved);
                         n[nlen] = NULL;
-                        resolved = NULL;
                 }
 
                 if (!n || !n[0]) {
@@ -771,15 +747,13 @@ int config_parse_exec(
                 if (!nce)
                         return log_oom();
 
-                nce->argv = n;
-                nce->path = path;
+                nce->argv = TAKE_PTR(n);
+                nce->path = TAKE_PTR(path);
                 nce->flags = flags;
 
                 exec_command_append_list(e, nce);
 
                 /* Do not _cleanup_free_ these. */
-                n = NULL;
-                path = NULL;
                 nce = NULL;
 
                 rvalue = p;
@@ -1272,8 +1246,7 @@ int config_parse_exec_cpu_affinity(const char *unit,
         }
 
         if (!c->cpuset) {
-                c->cpuset = cpuset;
-                cpuset = NULL;
+                c->cpuset = TAKE_PTR(cpuset);
                 c->cpuset_ncpus = (unsigned) ncpus;
                 return 0;
         }
@@ -1281,8 +1254,7 @@ int config_parse_exec_cpu_affinity(const char *unit,
         if (c->cpuset_ncpus < (unsigned) ncpus) {
                 CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, cpuset);
                 CPU_FREE(c->cpuset);
-                c->cpuset = cpuset;
-                cpuset = NULL;
+                c->cpuset = TAKE_PTR(cpuset);
                 c->cpuset_ncpus = (unsigned) ncpus;
                 return 0;
         }
@@ -1745,9 +1717,8 @@ int config_parse_trigger_unit(
                 log_syntax(unit, LOG_ERR, filename, line, 0, "Unit type not valid, ignoring: %s", rvalue);
                 return 0;
         }
-
-        if (type == u->type) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Trigger cannot be of same type, ignoring: %s", rvalue);
+        if (unit_has_name(u, p)) {
+                log_syntax(unit, LOG_ERR, filename, line, 0, "Units cannot trigger themselves, ignoring: %s", rvalue);
                 return 0;
         }
 
@@ -1860,7 +1831,7 @@ int config_parse_socket_service(
                 return -ENOEXEC;
         }
 
-        unit_ref_set(&s->service, x);
+        unit_ref_set(&s->service, UNIT(s), x);
 
         return 0;
 }
@@ -2114,8 +2085,7 @@ int config_parse_user_group(
                         return -ENOEXEC;
                 }
 
-                n = k;
-                k = NULL;
+                n = TAKE_PTR(k);
         }
 
         free(*user);
@@ -2345,10 +2315,8 @@ int config_parse_environ(
                                            "Failed to resolve specifiers, ignoring: %s", word);
                                 continue;
                         }
-                } else {
-                        k = word;
-                        word = NULL;
-                }
+                } else
+                        k = TAKE_PTR(word);
 
                 if (!env_assignment_is_valid(k)) {
                         log_syntax(unit, LOG_ERR, filename, line, 0,
@@ -2415,10 +2383,8 @@ int config_parse_pass_environ(
                                            "Failed to resolve specifiers, ignoring: %s", word);
                                 continue;
                         }
-                } else {
-                        k = word;
-                        word = NULL;
-                }
+                } else
+                        k = TAKE_PTR(word);
 
                 if (!env_name_is_valid(k)) {
                         log_syntax(unit, LOG_ERR, filename, line, 0,
@@ -2429,9 +2395,8 @@ int config_parse_pass_environ(
                 if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
                         return log_oom();
 
-                n[nlen++] = k;
+                n[nlen++] = TAKE_PTR(k);
                 n[nlen] = NULL;
-                k = NULL;
         }
 
         if (n) {
@@ -2494,10 +2459,8 @@ int config_parse_unset_environ(
                                            "Failed to resolve specifiers, ignoring: %s", word);
                                 continue;
                         }
-                } else {
-                        k = word;
-                        word = NULL;
-                }
+                } else
+                        k = TAKE_PTR(word);
 
                 if (!env_assignment_is_valid(k) && !env_name_is_valid(k)) {
                         log_syntax(unit, LOG_ERR, filename, line, 0,
@@ -2508,9 +2471,8 @@ int config_parse_unset_environ(
                 if (!GREEDY_REALLOC(n, nbufsize, nlen + 2))
                         return log_oom();
 
-                n[nlen++] = k;
+                n[nlen++] = TAKE_PTR(k);
                 n[nlen] = NULL;
-                k = NULL;
         }
 
         if (n) {
@@ -2581,7 +2543,7 @@ int config_parse_log_extra_fields(
                         continue;
                 }
 
-                t = realloc_multiply(c->log_extra_fields, sizeof(struct iovec), c->n_log_extra_fields+1);
+                t = reallocarray(c->log_extra_fields, c->n_log_extra_fields+1, sizeof(struct iovec));
                 if (!t)
                         return log_oom();
 
@@ -2935,7 +2897,7 @@ int config_parse_syscall_filter(
                         c->syscall_whitelist = true;
 
                         /* Accept default syscalls if we are on a whitelist */
-                        r = seccomp_parse_syscall_filter(false, "@default", -1, c->syscall_filter, true);
+                        r = seccomp_parse_syscall_filter("@default", -1, c->syscall_filter, SECCOMP_PARSE_WHITELIST);
                         if (r < 0)
                                 return r;
                 }
@@ -2962,7 +2924,9 @@ int config_parse_syscall_filter(
                         continue;
                 }
 
-                r = seccomp_parse_syscall_filter_and_warn(invert, name, num, c->syscall_filter, c->syscall_whitelist, unit, filename, line);
+                r = seccomp_parse_syscall_filter_full(name, num, c->syscall_filter,
+                                                      SECCOMP_PARSE_LOG|SECCOMP_PARSE_PERMISSIVE|(invert ? SECCOMP_PARSE_INVERT : 0)|(c->syscall_whitelist ? SECCOMP_PARSE_WHITELIST : 0),
+                                                      unit, filename, line);
                 if (r < 0)
                         return r;
         }
@@ -3344,7 +3308,8 @@ int config_parse_memory_limit(
                 } else
                         bytes = physical_memory_scale(r, 100U);
 
-                if (bytes <= 0 || bytes >= UINT64_MAX) {
+                if (bytes >= UINT64_MAX ||
+                    (bytes <= 0 && !streq(lvalue, "MemorySwapMax"))) {
                         log_syntax(unit, LOG_ERR, filename, line, 0, "Memory limit '%s' out of range. Ignoring.", rvalue);
                         return 0;
                 }
@@ -3509,6 +3474,7 @@ int config_parse_device_allow(
                 log_syntax(unit, LOG_WARNING, filename, line, r,
                            "Failed to resolve specifiers in %s, ignoring: %m",
                            rvalue);
+                return 0;
         }
 
         n = strcspn(t, WHITESPACE);
@@ -3536,8 +3502,7 @@ int config_parse_device_allow(
         if (!a)
                 return log_oom();
 
-        a->path = path;
-        path = NULL;
+        a->path = TAKE_PTR(path);
         a->r = !!strchr(m, 'r');
         a->w = !!strchr(m, 'w');
         a->m = !!strchr(m, 'm');
@@ -3636,8 +3601,7 @@ int config_parse_io_device_weight(
         if (!w)
                 return log_oom();
 
-        w->path = path;
-        path = NULL;
+        w->path = TAKE_PTR(path);
 
         w->weight = u;
 
@@ -3722,8 +3686,7 @@ int config_parse_io_limit(
                 if (!l)
                         return log_oom();
 
-                l->path = path;
-                path = NULL;
+                l->path = TAKE_PTR(path);
                 for (ttype = 0; ttype < _CGROUP_IO_LIMIT_TYPE_MAX; ttype++)
                         l->limits[ttype] = cgroup_io_limit_defaults[ttype];
 
@@ -3825,8 +3788,7 @@ int config_parse_blockio_device_weight(
         if (!w)
                 return log_oom();
 
-        w->path = path;
-        path = NULL;
+        w->path = TAKE_PTR(path);
 
         w->weight = u;
 
@@ -3906,8 +3868,7 @@ int config_parse_blockio_bandwidth(
                 if (!b)
                         return log_oom();
 
-                b->path = path;
-                path = NULL;
+                b->path = TAKE_PTR(path);
                 b->rbps = CGROUP_LIMIT_MAX;
                 b->wbps = CGROUP_LIMIT_MAX;
 
@@ -4175,6 +4136,83 @@ int config_parse_namespace_path_strv(
         return 0;
 }
 
+int config_parse_temporary_filesystems(
+                const char *unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        Unit *u = userdata;
+        ExecContext *c = data;
+        const char *cur;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        if (isempty(rvalue)) {
+                /* Empty assignment resets the list */
+                temporary_filesystem_free_many(c->temporary_filesystems, c->n_temporary_filesystems);
+                c->temporary_filesystems = NULL;
+                c->n_temporary_filesystems = 0;
+                return 0;
+        }
+
+        cur = rvalue;
+        for (;;) {
+                _cleanup_free_ char *word = NULL, *path = NULL, *resolved = NULL;
+                const char *w;
+
+                r = extract_first_word(&cur, &word, NULL, EXTRACT_QUOTES);
+                if (r == 0)
+                        break;
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to extract first word, ignoring: %s", rvalue);
+                        return 0;
+                }
+
+                w = word;
+                r = extract_first_word(&w, &path, ":", EXTRACT_DONT_COALESCE_SEPARATORS);
+                if (r < 0)
+                        return r;
+                if (r == 0)
+                        return -EINVAL;
+
+                r = unit_full_printf(u, path, &resolved);
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve specifiers in %s, ignoring: %m", word);
+                        continue;
+                }
+
+                if (!path_is_absolute(resolved)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Not an absolute path, ignoring: %s", resolved);
+                        continue;
+                }
+
+                path_kill_slashes(resolved);
+
+                r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, w);
+                if (r == -ENOMEM)
+                        return log_oom();
+                if (r < 0) {
+                        log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse mount options, ignoring: %s", word);
+                        continue;
+                }
+        }
+
+        return 0;
+}
+
 int config_parse_bind_paths(
                 const char *unit,
                 const char *filename,
@@ -4720,9 +4758,7 @@ static int load_from_path(Unit *u, const char *path) {
                         return r;
         }
 
-        free(u->fragment_path);
-        u->fragment_path = filename;
-        filename = NULL;
+        free_and_replace(u->fragment_path, filename);
 
         if (u->source_path) {
                 if (stat(u->source_path, &st) >= 0)