diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/architecture.c | 3 | ||||
-rw-r--r-- | src/basic/architecture.h | 3 | ||||
-rw-r--r-- | src/basic/calendarspec.c | 3 | ||||
-rw-r--r-- | src/core/dbus-manager.c | 164 | ||||
-rw-r--r-- | src/core/dbus-unit.c | 4 | ||||
-rw-r--r-- | src/core/dbus.c | 12 | ||||
-rw-r--r-- | src/core/execute.c | 25 | ||||
-rw-r--r-- | src/core/unit.c | 2 | ||||
-rw-r--r-- | src/network/networkd-ipv6-proxy-ndp.c | 209 | ||||
-rw-r--r-- | src/network/networkd-ipv6-proxy-ndp.h | 44 | ||||
-rw-r--r-- | src/network/networkd-link.c | 5 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 1 | ||||
-rw-r--r-- | src/network/networkd-network.c | 6 | ||||
-rw-r--r-- | src/network/networkd-network.h | 3 | ||||
-rw-r--r-- | src/shared/bus-unit-util.c | 6 | ||||
-rw-r--r-- | src/shared/dropin.c | 38 | ||||
-rw-r--r-- | src/shared/install.c | 62 | ||||
-rw-r--r-- | src/shared/path-lookup.c | 65 | ||||
-rw-r--r-- | src/shared/seccomp-util.c | 68 | ||||
-rw-r--r-- | src/test/test-calendarspec.c | 1 | ||||
-rw-r--r-- | src/test/test-execute.c | 5 |
21 files changed, 565 insertions, 164 deletions
diff --git a/src/basic/architecture.c b/src/basic/architecture.c index b74dc0db78..5a3dc08a4a 100644 --- a/src/basic/architecture.c +++ b/src/basic/architecture.c @@ -123,7 +123,8 @@ int uname_architecture(void) { { "crisv32", ARCHITECTURE_CRIS }, #elif defined(__nios2__) { "nios2", ARCHITECTURE_NIOS2 }, -#elif defined(__riscv__) +#elif defined(__riscv__) || defined(__riscv) + /* __riscv__ is obsolete, remove in 2018 */ { "riscv32", ARCHITECTURE_RISCV32 }, { "riscv64", ARCHITECTURE_RISCV64 }, # if __SIZEOF_POINTER__ == 4 diff --git a/src/basic/architecture.h b/src/basic/architecture.h index b329df2f6d..d6b8603b06 100644 --- a/src/basic/architecture.h +++ b/src/basic/architecture.h @@ -194,7 +194,8 @@ int uname_architecture(void); #elif defined(__nios2__) # define native_architecture() ARCHITECTURE_NIOS2 # define LIB_ARCH_TUPLE "nios2-linux-gnu" -#elif defined(__riscv__) +#elif defined(__riscv__) || defined(__riscv) + /* __riscv__ is obsolete, remove in 2018 */ # if __SIZEOF_POINTER__ == 4 # define native_architecture() ARCHITECTURE_RISCV32 # define LIB_ARCH_TUPLE "riscv32-linux-gnu" diff --git a/src/basic/calendarspec.c b/src/basic/calendarspec.c index 3fa1c51ace..2323eb8555 100644 --- a/src/basic/calendarspec.c +++ b/src/basic/calendarspec.c @@ -116,8 +116,7 @@ static void normalize_chain(CalendarComponent **c) { /* Drop non-unique entries */ for (k = n-1; k > 0; k--) { - if (b[k-1]->start == next->start && - b[k-1]->repeat == next->repeat) { + if (component_compare(&b[k-1], &next) == 0) { free(b[k-1]); continue; } diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index bcc17726ed..f87b52a266 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -848,13 +848,9 @@ static int method_get_unit_processes(sd_bus_message *message, void *userdata, sd if (r < 0) return r; - r = manager_load_unit(m, name, NULL, error, &u); - if (r < 0) - return r; - - r = bus_unit_check_load_state(u, error); - if (r < 0) - return r; + u = manager_get_unit(m, name); + if (!u) + return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name); return bus_unit_method_get_processes(message, u, error); } @@ -1916,63 +1912,6 @@ static int send_unit_files_changed(sd_bus *bus, void *userdata) { return sd_bus_send(bus, message, NULL); } -static int reply_unit_file_changes_and_free( - Manager *m, - sd_bus_message *message, - int carries_install_info, - UnitFileChange *changes, - unsigned n_changes) { - - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; - unsigned i; - int r; - - if (unit_file_changes_have_modification(changes, n_changes)) { - r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL); - if (r < 0) - log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m"); - } - - r = sd_bus_message_new_method_return(message, &reply); - if (r < 0) - goto fail; - - if (carries_install_info >= 0) { - r = sd_bus_message_append(reply, "b", carries_install_info); - if (r < 0) - goto fail; - } - - r = sd_bus_message_open_container(reply, 'a', "(sss)"); - if (r < 0) - goto fail; - - for (i = 0; i < n_changes; i++) - if (changes[i].type >= 0) { - const char *change = unit_file_change_type_to_string(changes[i].type); - assert(change != NULL); - - r = sd_bus_message_append( - reply, "(sss)", - change, - changes[i].path, - changes[i].source); - if (r < 0) - goto fail; - } - - r = sd_bus_message_close_container(reply); - if (r < 0) - goto fail; - - unit_file_changes_free(changes, n_changes); - return sd_bus_send(NULL, reply, NULL); - -fail: - unit_file_changes_free(changes, n_changes); - return r; -} - /* Create an error reply, using the error information from changes[] * if possible, and fall back to generating an error from error code c. * The error message only describes the first error. @@ -1986,12 +1925,14 @@ static int install_error( unsigned n_changes) { int r; unsigned i; - assert(c < 0); for (i = 0; i < n_changes; i++) + switch(changes[i].type) { + case 0 ... INT_MAX: continue; + case -EEXIST: if (changes[i].source) r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, @@ -2002,29 +1943,106 @@ static int install_error( "File %s already exists.", changes[i].path); goto found; + case -ERFKILL: r = sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file %s is masked.", changes[i].path); goto found; + case -EADDRNOTAVAIL: r = sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit %s is transient or generated.", changes[i].path); goto found; + case -ELOOP: r = sd_bus_error_setf(error, BUS_ERROR_UNIT_LINKED, "Refusing to operate on linked unit file %s", changes[i].path); goto found; + + case -ENOENT: + r = sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit file %s does not exist.", changes[i].path); + goto found; + default: r = sd_bus_error_set_errnof(error, changes[i].type, "File %s: %m", changes[i].path); goto found; } - r = c; + r = c < 0 ? c : -EINVAL; + found: unit_file_changes_free(changes, n_changes); return r; } +static int reply_unit_file_changes_and_free( + Manager *m, + sd_bus_message *message, + int carries_install_info, + UnitFileChange *changes, + unsigned n_changes, + sd_bus_error *error) { + + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + bool bad = false, good = false; + unsigned i; + int r; + + if (unit_file_changes_have_modification(changes, n_changes)) { + r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL); + if (r < 0) + log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m"); + } + + r = sd_bus_message_new_method_return(message, &reply); + if (r < 0) + goto fail; + + if (carries_install_info >= 0) { + r = sd_bus_message_append(reply, "b", carries_install_info); + if (r < 0) + goto fail; + } + + r = sd_bus_message_open_container(reply, 'a', "(sss)"); + if (r < 0) + goto fail; + + for (i = 0; i < n_changes; i++) { + + if (changes[i].type < 0) { + bad = true; + continue; + } + + r = sd_bus_message_append( + reply, "(sss)", + unit_file_change_type_to_string(changes[i].type), + changes[i].path, + changes[i].source); + if (r < 0) + goto fail; + + good = true; + } + + /* If there was a failed change, and no successful change, then return the first failure as proper method call + * error. */ + if (bad && !good) + return install_error(error, 0, changes, n_changes); + + r = sd_bus_message_close_container(reply); + if (r < 0) + goto fail; + + unit_file_changes_free(changes, n_changes); + return sd_bus_send(NULL, reply, NULL); + +fail: + unit_file_changes_free(changes, n_changes); + return r; +} + static int method_enable_unit_files_generic( sd_bus_message *message, Manager *m, @@ -2061,7 +2079,7 @@ static int method_enable_unit_files_generic( if (r < 0) return install_error(error, r, changes, n_changes); - return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes); + return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error); } static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -2130,7 +2148,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use if (r < 0) return install_error(error, r, changes, n_changes); - return reply_unit_file_changes_and_free(m, message, r, changes, n_changes); + return reply_unit_file_changes_and_free(m, message, r, changes, n_changes, error); } static int method_disable_unit_files_generic( @@ -2165,7 +2183,7 @@ static int method_disable_unit_files_generic( if (r < 0) return install_error(error, r, changes, n_changes); - return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); + return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error); } static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -2200,7 +2218,7 @@ static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_ if (r < 0) return install_error(error, r, changes, n_changes); - return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); + return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error); } static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -2231,7 +2249,7 @@ static int method_set_default_target(sd_bus_message *message, void *userdata, sd if (r < 0) return install_error(error, r, changes, n_changes); - return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); + return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error); } static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -2274,7 +2292,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, if (r < 0) return install_error(error, r, changes, n_changes); - return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); + return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error); } static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -2314,7 +2332,7 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd if (r < 0) return install_error(error, r, changes, n_changes); - return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); + return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error); } static int method_get_unit_file_links(sd_bus_message *message, void *userdata, sd_bus_error *error) { diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 60e889e1ef..f1306a023f 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -1006,6 +1006,10 @@ int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bu assert(message); + r = mac_selinux_unit_access_check(u, message, "status", error); + if (r < 0) + return r; + pids = set_new(NULL); if (!pids) return -ENOMEM; diff --git a/src/core/dbus.c b/src/core/dbus.c index a3f701c064..0493e5786c 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -1041,6 +1041,7 @@ int bus_init(Manager *m, bool try_bus_connect) { static void destroy_bus(Manager *m, sd_bus **bus) { Iterator i; + Unit *u; Job *j; assert(m); @@ -1049,6 +1050,17 @@ static void destroy_bus(Manager *m, sd_bus **bus) { if (!*bus) return; + /* Make sure all bus slots watching names are released. */ + HASHMAP_FOREACH(u, m->watch_bus, i) { + if (!u->match_bus_slot) + continue; + + if (sd_bus_slot_get_bus(u->match_bus_slot) != *bus) + continue; + + u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot); + } + /* Get rid of tracked clients on this bus */ if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus) m->subscribed = sd_bus_track_unref(m->subscribed); diff --git a/src/core/execute.c b/src/core/execute.c index 6041da46d6..4c2968f971 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1938,10 +1938,13 @@ static int compile_read_write_paths( return 0; } -static int apply_mount_namespace(Unit *u, const ExecContext *context, - const ExecParameters *params, - ExecRuntime *runtime) { - int r; +static int apply_mount_namespace( + Unit *u, + ExecCommand *command, + const ExecContext *context, + const ExecParameters *params, + ExecRuntime *runtime) { + _cleanup_strv_free_ char **rw = NULL; char *tmp = NULL, *var = NULL; const char *root_dir = NULL, *root_image = NULL; @@ -1953,6 +1956,8 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context, .protect_kernel_modules = context->protect_kernel_modules, .mount_apivfs = context->mount_apivfs, }; + bool apply_restrictions; + int r; assert(context); @@ -1986,16 +1991,18 @@ static int apply_mount_namespace(Unit *u, const ExecContext *context, if (!context->dynamic_user && root_dir) ns_info.ignore_protect_paths = true; + apply_restrictions = (params->flags & EXEC_APPLY_PERMISSIONS) && !command->privileged; + r = setup_namespace(root_dir, root_image, &ns_info, rw, - context->read_only_paths, - context->inaccessible_paths, + apply_restrictions ? context->read_only_paths : NULL, + apply_restrictions ? context->inaccessible_paths : NULL, context->bind_mounts, context->n_bind_mounts, tmp, var, - context->protect_home, - context->protect_system, + apply_restrictions ? context->protect_home : PROTECT_HOME_NO, + apply_restrictions ? context->protect_system : PROTECT_SYSTEM_NO, context->mount_flags, DISSECT_IMAGE_DISCARD_ON_LOOP); @@ -2606,7 +2613,7 @@ static int exec_child( needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime); if (needs_mount_namespace) { - r = apply_mount_namespace(unit, context, params, runtime); + r = apply_mount_namespace(unit, command, context, params, runtime); if (r < 0) { *exit_status = EXIT_NAMESPACE; return r; diff --git a/src/core/unit.c b/src/core/unit.c index 90d7eea956..5e4b1567d8 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2650,7 +2650,7 @@ void unit_unwatch_bus_name(Unit *u, const char *name) { assert(u); assert(name); - hashmap_remove_value(u->manager->watch_bus, name, u); + (void) hashmap_remove_value(u->manager->watch_bus, name, u); u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot); } diff --git a/src/network/networkd-ipv6-proxy-ndp.c b/src/network/networkd-ipv6-proxy-ndp.c new file mode 100644 index 0000000000..11c1cd9268 --- /dev/null +++ b/src/network/networkd-ipv6-proxy-ndp.c @@ -0,0 +1,209 @@ +/*** + This file is part of systemd. + + Copyright 2017 Florian Klink <flokli@flokli.de> + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <netinet/ether.h> +#include <linux/if.h> +#include <unistd.h> + +#include "fileio.h" +#include "netlink-util.h" +#include "networkd-ipv6-proxy-ndp.h" +#include "networkd-link.h" +#include "networkd-manager.h" +#include "networkd-network.h" +#include "string-util.h" + +static bool ipv6_proxy_ndp_is_needed(Link *link) { + assert(link); + + if (link->flags & IFF_LOOPBACK) + return false; + + if (!link->network) + return false; + + if (link->network->n_ipv6_proxy_ndp_addresses == 0) + return false; + + return true; +} + +static int ipv6_proxy_ndp_set(Link *link) { + const char *p = NULL; + int r, v; + + assert(link); + + v = ipv6_proxy_ndp_is_needed(link); + p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/proxy_ndp"); + + r = write_string_file(p, one_zero(v), WRITE_STRING_FILE_VERIFY_ON_FAILURE); + if (r < 0) + log_link_warning_errno(link, r, "Cannot configure proxy NDP for interface: %m"); + + return 0; +} + +int ipv6_proxy_ndp_address_new_static(Network *network, IPv6ProxyNDPAddress **ret) { + _cleanup_(ipv6_proxy_ndp_address_freep) IPv6ProxyNDPAddress *ipv6_proxy_ndp_address = NULL; + + assert(network); + assert(ret); + + /* allocate space for IPv6ProxyNDPAddress entry */ + ipv6_proxy_ndp_address = new0(IPv6ProxyNDPAddress, 1); + if (!ipv6_proxy_ndp_address) + return -ENOMEM; + + ipv6_proxy_ndp_address->network = network; + + LIST_PREPEND(ipv6_proxy_ndp_addresses, network->ipv6_proxy_ndp_addresses, ipv6_proxy_ndp_address); + network->n_ipv6_proxy_ndp_addresses++; + + *ret = ipv6_proxy_ndp_address; + ipv6_proxy_ndp_address = NULL; + + return 0; +} + +void ipv6_proxy_ndp_address_free(IPv6ProxyNDPAddress *ipv6_proxy_ndp_address) { + if (!ipv6_proxy_ndp_address) + return; + + if (ipv6_proxy_ndp_address->network) { + LIST_REMOVE(ipv6_proxy_ndp_addresses, ipv6_proxy_ndp_address->network->ipv6_proxy_ndp_addresses, + ipv6_proxy_ndp_address); + + assert(ipv6_proxy_ndp_address->network->n_ipv6_proxy_ndp_addresses > 0); + ipv6_proxy_ndp_address->network->n_ipv6_proxy_ndp_addresses--; + } + + free(ipv6_proxy_ndp_address); +} + +int config_parse_ipv6_proxy_ndp_address( + 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) { + + Network *network = userdata; + _cleanup_(ipv6_proxy_ndp_address_freep) IPv6ProxyNDPAddress *ipv6_proxy_ndp_address = NULL; + int r; + union in_addr_union buffer; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + assert(data); + + r = ipv6_proxy_ndp_address_new_static(network, &ipv6_proxy_ndp_address); + if (r < 0) + return r; + + r = in_addr_from_string(AF_INET6, rvalue, &buffer); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse IPv6 proxy NDP address, ignoring: %s", + rvalue); + return 0; + } + + r = in_addr_is_null(AF_INET6, &buffer); + if (r != 0) { + log_syntax(unit, LOG_ERR, filename, line, r, + "IPv6 proxy NDP address can not be the ANY address, ignoring: %s", rvalue); + return 0; + } + + ipv6_proxy_ndp_address->in_addr = buffer.in6; + ipv6_proxy_ndp_address = NULL; + + return 0; +} + +static int set_ipv6_proxy_ndp_address_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { + Link *link = userdata; + int r; + + assert(link); + + r = sd_netlink_message_get_errno(m); + if (r < 0 && r != -EEXIST) + log_link_error_errno(link, r, "Could not add IPv6 proxy ndp address entry: %m"); + + return 1; +} + +/* send a request to the kernel to add a IPv6 Proxy entry to the neighbour table */ +int ipv6_proxy_ndp_address_configure(Link *link, IPv6ProxyNDPAddress *ipv6_proxy_ndp_address) { + _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; + sd_netlink *rtnl; + int r; + + assert(link); + assert(link->network); + assert(link->manager); + assert(ipv6_proxy_ndp_address); + + rtnl = link->manager->rtnl; + + /* create new netlink message */ + r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_NEWNEIGH, link->ifindex, AF_INET6); + if (r < 0) + return rtnl_log_create_error(r); + + r = sd_rtnl_message_neigh_set_flags(req, NLM_F_REQUEST | NTF_PROXY); + if (r < 0) + return rtnl_log_create_error(r); + + r = sd_netlink_message_append_in6_addr(req, NDA_DST, &ipv6_proxy_ndp_address->in_addr); + if (r < 0) + return rtnl_log_create_error(r); + + r = sd_netlink_call_async(rtnl, req, set_ipv6_proxy_ndp_address_handler, link, 0, NULL); + if (r < 0) + return log_link_error_errno(link, r, "Could not send rtnetlink message: %m"); + + return 0; +} + +/* configure all ipv6 proxy ndp addresses */ +int ipv6_proxy_ndp_addresses_configure(Link *link) { + IPv6ProxyNDPAddress *ipv6_proxy_ndp_address; + int r; + + /* enable or disable proxy_ndp itself depending on whether ipv6_proxy_ndp_addresses are set or not */ + r = ipv6_proxy_ndp_set(link); + if (r != 0) + return r; + + LIST_FOREACH(ipv6_proxy_ndp_addresses, ipv6_proxy_ndp_address, link->network->ipv6_proxy_ndp_addresses) { + r = ipv6_proxy_ndp_address_configure(link, ipv6_proxy_ndp_address); + if (r != 0) + return r; + } + return 0; +} diff --git a/src/network/networkd-ipv6-proxy-ndp.h b/src/network/networkd-ipv6-proxy-ndp.h new file mode 100644 index 0000000000..f09169f40f --- /dev/null +++ b/src/network/networkd-ipv6-proxy-ndp.h @@ -0,0 +1,44 @@ +#pragma once + +/*** + This file is part of systemd. + + Copyright 2017 Florian Klink <flokli@flokli.de> + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include "list.h" +#include "macro.h" + +typedef struct Network Network; +typedef struct IPv6ProxyNDPAddress IPv6ProxyNDPAddress; +typedef struct Link Link; + +struct IPv6ProxyNDPAddress { + Network *network; + struct in6_addr in_addr; + + LIST_FIELDS(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses); +}; + + +int ipv6_proxy_ndp_address_new_static(Network *network, IPv6ProxyNDPAddress ** ipv6_proxy_ndp_address); +void ipv6_proxy_ndp_address_free(IPv6ProxyNDPAddress *ipv6_proxy_ndp_address); +int ipv6_proxy_ndp_address_configure(Link *link, IPv6ProxyNDPAddress *ipv6_proxy_ndp_address); +int ipv6_proxy_ndp_addresses_configure(Link *link); + +DEFINE_TRIVIAL_CLEANUP_FUNC(IPv6ProxyNDPAddress*, ipv6_proxy_ndp_address_free); + +int config_parse_ipv6_proxy_ndp_address(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); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index b993d27c2f..0c1229336b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -28,6 +28,7 @@ #include "fileio.h" #include "netlink-util.h" #include "network-internal.h" +#include "networkd-ipv6-proxy-ndp.h" #include "networkd-lldp-tx.h" #include "networkd-manager.h" #include "networkd-ndisc.h" @@ -2448,6 +2449,10 @@ static int link_configure(Link *link) { if (r < 0) return r; + r = ipv6_proxy_ndp_addresses_configure(link); + if (r < 0) + return r; + r = link_set_ipv4_forward(link); if (r < 0) return r; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 7b54e81fb8..68052ba544 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -67,6 +67,7 @@ Network.ActiveSlave, config_parse_bool, Network.PrimarySlave, config_parse_bool, 0, offsetof(Network, primary_slave) Network.IPv4ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp) Network.ProxyARP, config_parse_tristate, 0, offsetof(Network, proxy_arp) +Network.IPv6ProxyNDPAddress, config_parse_ipv6_proxy_ndp_address, 0, 0 Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier) Address.Address, config_parse_address, 0, 0 Address.Peer, config_parse_address, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index bc4dc95ff9..92062ca00c 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -70,6 +70,7 @@ static int network_load_one(Manager *manager, const char *filename) { LIST_HEAD_INIT(network->static_addresses); LIST_HEAD_INIT(network->static_routes); LIST_HEAD_INIT(network->static_fdb_entries); + LIST_HEAD_INIT(network->ipv6_proxy_ndp_addresses); network->stacked_netdevs = hashmap_new(&string_hash_ops); if (!network->stacked_netdevs) @@ -152,6 +153,7 @@ static int network_load_one(Manager *manager, const char *filename) { "DHCPv4\0" /* compat */ "DHCPServer\0" "IPv6AcceptRA\0" + "IPv6NDPProxyAddress\0" "Bridge\0" "BridgeFDB\0" "BridgeVLAN\0", @@ -224,6 +226,7 @@ void network_free(Network *network) { Route *route; Address *address; FdbEntry *fdb_entry; + IPv6ProxyNDPAddress *ipv6_proxy_ndp_address; Iterator i; if (!network) @@ -268,6 +271,9 @@ void network_free(Network *network) { while ((fdb_entry = network->static_fdb_entries)) fdb_entry_free(fdb_entry); + while ((ipv6_proxy_ndp_address = network->ipv6_proxy_ndp_addresses)) + ipv6_proxy_ndp_address_free(ipv6_proxy_ndp_address); + hashmap_free(network->addresses_by_section); hashmap_free(network->routes_by_section); hashmap_free(network->fdb_entries_by_section); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index b7da9d22d4..f06828a899 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -31,6 +31,7 @@ #include "networkd-brvlan.h" #include "networkd-fdb.h" #include "networkd-lldp-tx.h" +#include "networkd-ipv6-proxy-ndp.h" #include "networkd-route.h" #include "networkd-util.h" #include "netdev/netdev.h" @@ -188,10 +189,12 @@ struct Network { LIST_HEAD(Address, static_addresses); LIST_HEAD(Route, static_routes); LIST_HEAD(FdbEntry, static_fdb_entries); + LIST_HEAD(IPv6ProxyNDPAddress, ipv6_proxy_ndp_addresses); unsigned n_static_addresses; unsigned n_static_routes; unsigned n_static_fdb_entries; + unsigned n_ipv6_proxy_ndp_addresses; Hashmap *addresses_by_section; Hashmap *routes_by_section; diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 20c1085697..4ca614f647 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -554,7 +554,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen } else if (streq(field, "RestrictNamespaces")) { bool invert = false; - uint64_t flags = 0; + unsigned long flags = 0; if (eq[0] == '~') { invert = true; @@ -575,7 +575,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen if (invert) flags = (~flags) & NAMESPACE_FLAGS_ALL; - r = sd_bus_message_append(m, "v", "t", flags); + r = sd_bus_message_append(m, "v", "t", (uint64_t) flags); } else if ((dep = unit_dependency_from_string(field)) >= 0) r = sd_bus_message_append(m, "v", "as", 1, eq); else if (streq(field, "MountFlags")) { @@ -585,7 +585,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen if (r < 0) return log_error_errno(r, "Failed to parse mount propagation flags: %s", eq); - r = sd_bus_message_append(m, "v", "t", f); + r = sd_bus_message_append(m, "v", "t", (uint64_t) f); } else if (STR_IN_SET(field, "BindPaths", "BindReadOnlyPaths")) { const char *p = eq; diff --git a/src/shared/dropin.c b/src/shared/dropin.c index 3917eb8f23..15ccd1b6ca 100644 --- a/src/shared/dropin.c +++ b/src/shared/dropin.c @@ -43,11 +43,10 @@ int drop_in_file(const char *dir, const char *unit, unsigned level, const char *name, char **_p, char **_q) { + char prefix[DECIMAL_STR_MAX(unsigned)]; _cleanup_free_ char *b = NULL; char *p, *q; - char prefix[DECIMAL_STR_MAX(unsigned)]; - assert(unit); assert(name); assert(_p); @@ -128,9 +127,10 @@ static int unit_file_find_dir( assert(path); r = chase_symlinks(path, original_root, 0, &chased); + if (r == -ENOENT) /* Ignore -ENOENT, after all most units won't have a drop-in dir */ + return 0; if (r < 0) - return log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, - r, "Failed to canonicalize path %s: %m", path); + return log_full_errno(LOG_WARNING, r, "Failed to canonicalize path %s: %m", path); r = strv_push(dirs, chased); if (r < 0) @@ -148,16 +148,14 @@ static int unit_file_find_dirs( const char *suffix, char ***dirs) { - _cleanup_free_ char *path = NULL; + char *path; int r; assert(unit_path); assert(name); assert(suffix); - path = strjoin(unit_path, "/", name, suffix); - if (!path) - return log_oom(); + path = strjoina(unit_path, "/", name, suffix); if (!unit_path_cache || set_get(unit_path_cache, path)) { r = unit_file_find_dir(original_root, path, dirs); @@ -166,22 +164,15 @@ static int unit_file_find_dirs( } if (unit_name_is_valid(name, UNIT_NAME_INSTANCE)) { - _cleanup_free_ char *template = NULL, *p = NULL; /* Also try the template dir */ + _cleanup_free_ char *template = NULL; + r = unit_name_template(name, &template); if (r < 0) return log_error_errno(r, "Failed to generate template from unit name: %m"); - p = strjoin(unit_path, "/", template, suffix); - if (!p) - return log_oom(); - - if (!unit_path_cache || set_get(unit_path_cache, p)) { - r = unit_file_find_dir(original_root, p, dirs); - if (r < 0) - return r; - } + return unit_file_find_dirs(original_root, unit_path_cache, unit_path, template, suffix, dirs); } return 0; @@ -194,27 +185,30 @@ int unit_file_find_dropin_paths( const char *dir_suffix, const char *file_suffix, Set *names, - char ***paths) { + char ***ret) { _cleanup_strv_free_ char **dirs = NULL, **ans = NULL; Iterator i; char *t, **p; int r; - assert(paths); + assert(ret); SET_FOREACH(t, names, i) STRV_FOREACH(p, lookup_path) unit_file_find_dirs(original_root, unit_path_cache, *p, t, dir_suffix, &dirs); - if (strv_isempty(dirs)) + if (strv_isempty(dirs)) { + *ret = NULL; return 0; + } r = conf_files_list_strv(&ans, file_suffix, NULL, (const char**) dirs); if (r < 0) return log_warning_errno(r, "Failed to sort the list of configuration files: %m"); - *paths = ans; + *ret = ans; ans = NULL; + return 1; } diff --git a/src/shared/install.c b/src/shared/install.c index f25ed685f6..58c8e852b2 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -389,6 +389,12 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang verb, changes[i].path); logged = true; break; + + case -ENOENT: + log_error_errno(changes[i].type, "Failed to %s unit, unit %s does not exist.", verb, changes[i].path); + logged = true; + break; + default: assert(changes[i].type < 0); log_error_errno(changes[i].type, "Failed to %s unit, file %s: %m.", @@ -1807,7 +1813,9 @@ static int install_context_mark_for_removal( InstallContext *c, const LookupPaths *paths, Set **remove_symlinks_to, - const char *config_path) { + const char *config_path, + UnitFileChange **changes, + unsigned *n_changes) { UnitFileInstallInfo *i; int r; @@ -1833,19 +1841,26 @@ static int install_context_mark_for_removal( r = install_info_traverse(scope, c, paths, i, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL); if (r == -ENOLINK) { - log_debug_errno(r, "Name %s leads to a dangling symlink, ignoring.", i->name); - continue; - } else if (r == -ENOENT && i->auxiliary) { - /* some unit specified in Also= or similar is missing */ - log_debug_errno(r, "Auxiliary unit %s not found, ignoring.", i->name); - continue; - } else if (r < 0) - return log_debug_errno(r, "Failed to find unit %s: %m", i->name); + log_debug_errno(r, "Name %s leads to a dangling symlink, removing name.", i->name); + unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_DANGLING, i->path ?: i->name, NULL); + } else if (r == -ENOENT) { - if (i->type != UNIT_FILE_TYPE_REGULAR) { - log_debug("Unit %s has type %s, ignoring.", - i->name, - unit_file_type_to_string(i->type) ?: "invalid"); + if (i->auxiliary) /* some unit specified in Also= or similar is missing */ + log_debug_errno(r, "Auxiliary unit of %s not found, removing name.", i->name); + else { + log_debug_errno(r, "Unit %s not found, removing name.", i->name); + unit_file_changes_add(changes, n_changes, r, i->path ?: i->name, NULL); + } + + } else if (r < 0) { + log_debug_errno(r, "Failed to find unit %s, removing name: %m", i->name); + unit_file_changes_add(changes, n_changes, r, i->path ?: i->name, NULL); + } else if (i->type == UNIT_FILE_TYPE_MASKED) { + log_debug("Unit file %s is masked, ignoring.", i->name); + unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_MASKED, i->path ?: i->name, NULL); + continue; + } else if (i->type != UNIT_FILE_TYPE_REGULAR) { + log_debug("Unit %s has type %s, ignoring.", i->name, unit_file_type_to_string(i->type) ?: "invalid"); continue; } @@ -1878,6 +1893,8 @@ int unit_file_mask( return r; config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config; + if (!config_path) + return -ENXIO; STRV_FOREACH(i, files) { _cleanup_free_ char *path = NULL; @@ -1926,6 +1943,9 @@ int unit_file_unmask( return r; config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config; + if (!config_path) + return -ENXIO; + dry_run = !!(flags & UNIT_FILE_DRY_RUN); STRV_FOREACH(i, files) { @@ -2015,6 +2035,8 @@ int unit_file_link( return r; config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config; + if (!config_path) + return -ENXIO; STRV_FOREACH(i, files) { _cleanup_free_ char *full = NULL; @@ -2282,6 +2304,8 @@ int unit_file_add_dependency( return r; config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config; + if (!config_path) + return -ENXIO; r = install_info_discover(scope, &c, &paths, target, SEARCH_FOLLOW_CONFIG_SYMLINKS, &target_info, changes, n_changes); @@ -2347,6 +2371,8 @@ int unit_file_enable( return r; config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config; + if (!config_path) + return -ENXIO; STRV_FOREACH(f, files) { r = install_info_discover(scope, &c, &paths, *f, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, @@ -2391,6 +2417,8 @@ int unit_file_disable( return r; config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config; + if (!config_path) + return -ENXIO; STRV_FOREACH(i, files) { if (!unit_name_is_valid(*i, UNIT_NAME_ANY)) @@ -2401,7 +2429,7 @@ int unit_file_disable( return r; } - r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path); + r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path, changes, n_changes); if (r < 0) return r; @@ -2790,7 +2818,7 @@ static int execute_preset( if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) { _cleanup_set_free_free_ Set *remove_symlinks_to = NULL; - r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path); + r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path, changes, n_changes); if (r < 0) return r; @@ -2885,6 +2913,8 @@ int unit_file_preset( return r; config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config; + if (!config_path) + return -ENXIO; r = read_presets(scope, root_dir, &presets); if (r < 0) @@ -2923,6 +2953,8 @@ int unit_file_preset_all( return r; config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config; + if (!config_path) + return -ENXIO; r = read_presets(scope, root_dir, &presets); if (r < 0) diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c index 586ef64e72..09a44534e2 100644 --- a/src/shared/path-lookup.c +++ b/src/shared/path-lookup.c @@ -33,6 +33,7 @@ #include "stat-util.h" #include "string-util.h" #include "strv.h" +#include "user-util.h" #include "util.h" static int user_runtime_dir(char **ret, const char *suffix) { @@ -57,6 +58,7 @@ static int user_runtime_dir(char **ret, const char *suffix) { static int user_config_dir(char **ret, const char *suffix) { const char *e; char *j; + int r; assert(ret); @@ -64,11 +66,11 @@ static int user_config_dir(char **ret, const char *suffix) { if (e) j = strappend(e, suffix); else { - const char *home; + _cleanup_free_ char *home = NULL; - home = getenv("HOME"); - if (!home) - return -ENXIO; + r = get_home_dir(&home); + if (r < 0) + return r; j = strjoin(home, "/.config", suffix); } @@ -83,6 +85,7 @@ static int user_config_dir(char **ret, const char *suffix) { static int user_data_dir(char **ret, const char *suffix) { const char *e; char *j; + int r; assert(ret); assert(suffix); @@ -95,12 +98,11 @@ static int user_data_dir(char **ret, const char *suffix) { if (e) j = strappend(e, suffix); else { - const char *home; - - home = getenv("HOME"); - if (!home) - return -ENXIO; + _cleanup_free_ char *home = NULL; + r = get_home_dir(&home); + if (r < 0) + return r; j = strjoin(home, "/.local/share", suffix); } @@ -136,10 +138,10 @@ static char** user_dirs( NULL }; - const char *e; _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL; _cleanup_free_ char *data_home = NULL; _cleanup_strv_free_ char **res = NULL; + const char *e; char **tmp; int r; @@ -186,9 +188,8 @@ static char** user_dirs( if (strv_extend(&res, generator_early) < 0) return NULL; - if (!strv_isempty(config_dirs)) - if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0) - return NULL; + if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0) + return NULL; if (strv_extend(&res, persistent_config) < 0) return NULL; @@ -205,9 +206,8 @@ static char** user_dirs( if (strv_extend(&res, data_home) < 0) return NULL; - if (!strv_isempty(data_dirs)) - if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0) - return NULL; + if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0) + return NULL; if (strv_extend_strv(&res, (char**) data_unit_paths, false) < 0) return NULL; @@ -220,6 +220,7 @@ static char** user_dirs( tmp = res; res = NULL; + return tmp; } @@ -328,12 +329,18 @@ static int acquire_config_dirs(UnitFileScope scope, char **persistent, char **ru case UNIT_FILE_USER: r = user_config_dir(&a, "/systemd/user"); - if (r < 0) + if (r < 0 && r != -ENXIO) return r; r = user_runtime_dir(runtime, "/systemd/user"); - if (r < 0) - return r; + if (r < 0) { + if (r != -ENXIO) + return r; + + /* If XDG_RUNTIME_DIR is not set, don't consider that fatal, simply initialize the runtime + * directory to NULL */ + *runtime = NULL; + } *persistent = a; a = NULL; @@ -382,12 +389,18 @@ static int acquire_control_dirs(UnitFileScope scope, char **persistent, char **r case UNIT_FILE_USER: r = user_config_dir(&a, "/systemd/system.control"); - if (r < 0) + if (r < 0 && r != -ENXIO) return r; r = user_runtime_dir(runtime, "/systemd/system.control"); - if (r < 0) - return r; + if (r < 0) { + if (r != -ENXIO) + return r; + + /* If XDG_RUNTIME_DIR is not set, don't consider this fatal, simply initialize the directory to + * NULL */ + *runtime = NULL; + } break; @@ -474,22 +487,26 @@ int lookup_paths_init( return -ENOMEM; } + /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_config to NULL */ r = acquire_config_dirs(scope, &persistent_config, &runtime_config); - if (r < 0 && r != -ENXIO) + if (r < 0) return r; if ((flags & LOOKUP_PATHS_EXCLUDE_GENERATED) == 0) { + /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */ r = acquire_generator_dirs(scope, &generator, &generator_early, &generator_late); if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO) return r; } + /* Note: if XDG_RUNTIME_DIR is not set, this will fail completely with ENXIO */ r = acquire_transient_dir(scope, &transient); if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO) return r; + /* Note: when XDG_RUNTIME_DIR is not set this will not return -ENXIO, but simply set runtime_control to NULL */ r = acquire_control_dirs(scope, &persistent_control, &runtime_control); - if (r < 0 && r != -EOPNOTSUPP && r != -ENXIO) + if (r < 0 && r != -EOPNOTSUPP) return r; /* First priority is whatever has been passed to us via env vars */ diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index e35f18471c..451669d9d5 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -36,31 +36,72 @@ const uint32_t seccomp_local_archs[] = { -#if defined(__i386__) || defined(__x86_64__) + /* Note: always list the native arch we are compiled as last, so that users can blacklist seccomp(), but our own calls to it still succeed */ + +#if defined(__x86_64__) && defined(__ILP32__) SCMP_ARCH_X86, SCMP_ARCH_X86_64, + SCMP_ARCH_X32, /* native */ +#elif defined(__x86_64__) && !defined(__ILP32__) + SCMP_ARCH_X86, SCMP_ARCH_X32, - -#elif defined(__arm__) || defined(__aarch64__) + SCMP_ARCH_X86_64, /* native */ +#elif defined(__i386__) + SCMP_ARCH_X86, +#elif defined(__aarch64__) SCMP_ARCH_ARM, - SCMP_ARCH_AARCH64, - -#elif defined(__mips__) || defined(__mips64__) + SCMP_ARCH_AARCH64, /* native */ +#elif defined(__arm__) + SCMP_ARCH_ARM, +#elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI32 + SCMP_ARCH_MIPSEL, + SCMP_ARCH_MIPS, /* native */ +#elif defined(__mips__) && __BYTE_ORDER == __LITTLE_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI32 SCMP_ARCH_MIPS, - SCMP_ARCH_MIPS64, + SCMP_ARCH_MIPSEL, /* native */ +#elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI64 + SCMP_ARCH_MIPSEL, + SCMP_ARCH_MIPS, + SCMP_ARCH_MIPSEL64N32, SCMP_ARCH_MIPS64N32, + SCMP_ARCH_MIPSEL64, + SCMP_ARCH_MIPS64, /* native */ +#elif defined(__mips__) && __BYTE_ORDER == __LITTLE_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI64 + SCMP_ARCH_MIPS, SCMP_ARCH_MIPSEL, + SCMP_ARCH_MIPS64N32, + SCMP_ARCH_MIPSEL64N32, + SCMP_ARCH_MIPS64, + SCMP_ARCH_MIPSEL64, /* native */ +#elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_NABI32 + SCMP_ARCH_MIPSEL, + SCMP_ARCH_MIPS, SCMP_ARCH_MIPSEL64, + SCMP_ARCH_MIPS64, SCMP_ARCH_MIPSEL64N32, - -#elif defined(__powerpc__) || defined(__powerpc64__) + SCMP_ARCH_MIPS64N32, /* native */ +#elif defined(__mips__) && __BYTE_ORDER == __LITTLE_ENDIAN && _MIPS_SIM == _MIPS_SIM_NABI32 + SCMP_ARCH_MIPS, + SCMP_ARCH_MIPSEL, + SCMP_ARCH_MIPS64, + SCMP_ARCH_MIPSEL64, + SCMP_ARCH_MIPS64N32, + SCMP_ARCH_MIPSEL64N32, /* native */ +#elif defined(__powerpc64__) && __BYTE_ORDER == __BIG_ENDIAN SCMP_ARCH_PPC, - SCMP_ARCH_PPC64, SCMP_ARCH_PPC64LE, - -#elif defined(__s390__) || defined(__s390x__) + SCMP_ARCH_PPC64, /* native */ +#elif defined(__powerpc64__) && __BYTE_ORDER == __LITTLE_ENDIAN + SCMP_ARCH_PPC, + SCMP_ARCH_PPC64, + SCMP_ARCH_PPC64LE, /* native */ +#elif defined(__powerpc__) + SCMP_ARCH_PPC, +#elif defined(__s390x__) + SCMP_ARCH_S390, + SCMP_ARCH_S390X, /* native */ +#elif defined(__s390__) SCMP_ARCH_S390, - SCMP_ARCH_S390X, #endif (uint32_t) -1 }; @@ -344,6 +385,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = { "mknodat\0" "mmap2\0" "mmap\0" + "munmap\0" "newfstatat\0" "open\0" "openat\0" diff --git a/src/test/test-calendarspec.c b/src/test/test-calendarspec.c index 1f34a91b10..f90b73aeaf 100644 --- a/src/test/test-calendarspec.c +++ b/src/test/test-calendarspec.c @@ -192,6 +192,7 @@ int main(int argc, char* argv[]) { test_one("00..07-*-*", "2000..2007-*-* 00:00:00"); test_one("*:20..39/5", "*-*-* *:20..35/5:00"); test_one("00:00:20..40/1", "*-*-* 00:00:20..40"); + test_one("*~03/1,03..05", "*-*~03/1,03..05 00:00:00"); test_next("2016-03-27 03:17:00", "", 12345, 1459048620000000); test_next("2016-03-27 03:17:00", "CET", 12345, 1459041420000000); diff --git a/src/test/test-execute.c b/src/test/test-execute.c index bc9a2021f9..1e479b9843 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -422,6 +422,10 @@ static void test_exec_spec_interpolation(Manager *m) { test(m, "exec-spec-interpolation.service", 0, CLD_EXITED); } +static void test_exec_read_only_path_suceed(Manager *m) { + test(m, "exec-read-only-path-succeed.service", 0, CLD_EXITED); +} + static int run_tests(UnitFileScope scope, const test_function_t *tests) { const test_function_t *test = NULL; Manager *m = NULL; @@ -475,6 +479,7 @@ int main(int argc, char *argv[]) { test_exec_oomscoreadjust, test_exec_ioschedulingclass, test_exec_spec_interpolation, + test_exec_read_only_path_suceed, NULL, }; static const test_function_t system_tests[] = { |