diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/dbus-execute.c | 39 | ||||
-rw-r--r-- | src/core/dbus-manager.c | 21 | ||||
-rw-r--r-- | src/core/dbus.c | 66 | ||||
-rw-r--r-- | src/core/dbus.h | 2 | ||||
-rw-r--r-- | src/core/execute.c | 109 | ||||
-rw-r--r-- | src/core/execute.h | 4 | ||||
-rw-r--r-- | src/core/job.c | 3 | ||||
-rw-r--r-- | src/core/load-fragment-gperf.gperf.m4 | 3 | ||||
-rw-r--r-- | src/core/load-fragment.c | 29 | ||||
-rw-r--r-- | src/core/load-fragment.h | 2 | ||||
-rw-r--r-- | src/core/main.c | 10 | ||||
-rw-r--r-- | src/core/manager.c | 16 | ||||
-rw-r--r-- | src/core/mount-setup.c | 15 | ||||
-rw-r--r-- | src/core/service.c | 14 | ||||
-rw-r--r-- | src/core/service.h | 1 | ||||
-rw-r--r-- | src/core/smack-setup.c | 101 | ||||
-rw-r--r-- | src/core/socket.c | 24 | ||||
-rw-r--r-- | src/core/transaction.c | 2 | ||||
-rw-r--r-- | src/core/unit.c | 7 |
19 files changed, 384 insertions, 84 deletions
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 093179c003..c2238c8c43 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -293,9 +293,25 @@ static int property_get_capability_bounding_set( assert(reply); assert(c); - /* We store this negated internally, to match the kernel, but - * we expose it normalized. */ - return sd_bus_message_append(reply, "t", ~c->capability_bounding_set_drop); + return sd_bus_message_append(reply, "t", c->capability_bounding_set); +} + +static int property_get_ambient_capabilities( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + ExecContext *c = userdata; + + assert(bus); + assert(reply); + assert(c); + + return sd_bus_message_append(reply, "t", c->capability_ambient_set); } static int property_get_capabilities( @@ -632,21 +648,37 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("PassEnvironment", "as", NULL, offsetof(ExecContext, pass_environment), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitCPUSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitDATASoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitCORESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitRSSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitASSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitNICESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST), @@ -673,6 +705,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("Capabilities", "s", property_get_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("CapabilityBoundingSet", "t", property_get_capability_bounding_set, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("AmbientCapabilities", "t", property_get_ambient_capabilities, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 5457b2451b..8a523cc8ac 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -229,7 +229,10 @@ static int property_set_log_level( if (r < 0) return r; - return log_set_max_level_from_string(t); + r = log_set_max_level_from_string(t); + if (r == 0) + log_info("Setting log level to %s.", t); + return r; } static int property_get_n_names( @@ -1939,21 +1942,37 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool, offsetof(Manager, default_memory_accounting), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool, offsetof(Manager, default_tasks_accounting), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitCPU", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitCPUSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitFSIZE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitDATA", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitDATASoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitSTACK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitCORE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitCORESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitRSS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitRSSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitNOFILE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitAS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitASSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitNPROC", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitLOCKS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitNICE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitNICESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitRTPRIO", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultTasksMax", "t", NULL, offsetof(Manager, default_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST), diff --git a/src/core/dbus.c b/src/core/dbus.c index e7ee216f0e..1d89b9e250 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -734,9 +734,11 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void return 0; } -static int bus_list_names(Manager *m, sd_bus *bus) { +int manager_sync_bus_names(Manager *m, sd_bus *bus) { _cleanup_strv_free_ char **names = NULL; - char **i; + const char *name; + Iterator i; + Unit *u; int r; assert(m); @@ -746,15 +748,55 @@ static int bus_list_names(Manager *m, sd_bus *bus) { if (r < 0) return log_error_errno(r, "Failed to get initial list of names: %m"); - /* This is a bit hacky, we say the owner of the name is the - * name itself, because we don't want the extra traffic to - * figure out the real owner. */ - STRV_FOREACH(i, names) { - Unit *u; + /* We have to synchronize the current bus names with the + * list of active services. To do this, walk the list of + * all units with bus names. */ + HASHMAP_FOREACH_KEY(u, name, m->watch_bus, i) { + Service *s = SERVICE(u); + + assert(s); - u = hashmap_get(m->watch_bus, *i); - if (u) - UNIT_VTABLE(u)->bus_name_owner_change(u, *i, NULL, *i); + if (!streq_ptr(s->bus_name, name)) { + log_unit_warning(u, "Bus name has changed from %s → %s, ignoring.", s->bus_name, name); + continue; + } + + /* Check if a service's bus name is in the list of currently + * active names */ + if (strv_contains(names, name)) { + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; + const char *unique; + + /* If it is, determine its current owner */ + r = sd_bus_get_name_creds(bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds); + if (r < 0) { + log_error_errno(r, "Failed to get bus name owner %s: %m", name); + continue; + } + + r = sd_bus_creds_get_unique_name(creds, &unique); + if (r < 0) { + log_error_errno(r, "Failed to get unique name for %s: %m", name); + continue; + } + + /* Now, let's compare that to the previous bus owner, and + * if it's still the same, all is fine, so just don't + * bother the service. Otherwise, the name has apparently + * changed, so synthesize a name owner changed signal. */ + + if (!streq_ptr(unique, s->bus_name_owner)) + UNIT_VTABLE(u)->bus_name_owner_change(u, name, s->bus_name_owner, unique); + } else { + /* So, the name we're watching is not on the bus. + * This either means it simply hasn't appeared yet, + * or it was lost during the daemon reload. + * Check if the service has a stored name owner, + * and synthesize a name loss signal in this case. */ + + if (s->bus_name_owner) + UNIT_VTABLE(u)->bus_name_owner_change(u, name, s->bus_name_owner, NULL); + } } return 0; @@ -808,7 +850,9 @@ static int bus_setup_api(Manager *m, sd_bus *bus) { if (r < 0) return log_error_errno(r, "Failed to register name: %m"); - bus_list_names(m, bus); + r = manager_sync_bus_names(m, bus); + if (r < 0) + return r; log_debug("Successfully connected to API bus."); return 0; diff --git a/src/core/dbus.h b/src/core/dbus.h index 4f06ad11c4..ff761668f3 100644 --- a/src/core/dbus.h +++ b/src/core/dbus.h @@ -34,6 +34,8 @@ void bus_track_serialize(sd_bus_track *t, FILE *f); int bus_track_deserialize_item(char ***l, const char *line); int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l); +int manager_sync_bus_names(Manager *m, sd_bus *bus); + int bus_foreach_bus(Manager *m, sd_bus_track *subscribed2, int (*send_message)(sd_bus *bus, void *userdata), void *userdata); int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error); diff --git a/src/core/execute.c b/src/core/execute.c index 4f67a9de83..ac91568b63 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -737,12 +737,7 @@ static int enforce_user(const ExecContext *context, uid_t uid) { /* Sets (but doesn't lookup) the uid and make sure we keep the * capabilities while doing so. */ - if (context->capabilities) { - _cleanup_cap_free_ cap_t d = NULL; - static const cap_value_t bits[] = { - CAP_SETUID, /* Necessary so that we can run setresuid() below */ - CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */ - }; + if (context->capabilities || context->capability_ambient_set != 0) { /* First step: If we need to keep capabilities but * drop privileges we need to make sure we keep our @@ -758,16 +753,24 @@ static int enforce_user(const ExecContext *context, uid_t uid) { /* Second step: set the capabilities. This will reduce * the capabilities to the minimum we need. */ - d = cap_dup(context->capabilities); - if (!d) - return -errno; + if (context->capabilities) { + _cleanup_cap_free_ cap_t d = NULL; + static const cap_value_t bits[] = { + CAP_SETUID, /* Necessary so that we can run setresuid() below */ + CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */ + }; - if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 || - cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0) - return -errno; + d = cap_dup(context->capabilities); + if (!d) + return -errno; - if (cap_set_proc(d) < 0) - return -errno; + if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 || + cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0) + return -errno; + + if (cap_set_proc(d) < 0) + return -errno; + } } /* Third step: actually set the uids */ @@ -1856,6 +1859,8 @@ static int exec_child( if (params->apply_permissions) { + int secure_bits = context->secure_bits; + for (i = 0; i < _RLIMIT_MAX; i++) { if (!context->rlimit[i]) continue; @@ -1866,28 +1871,71 @@ static int exec_child( } } - if (context->capability_bounding_set_drop) { - r = capability_bounding_set_drop(context->capability_bounding_set_drop, false); + if (!cap_test_all(context->capability_bounding_set)) { + r = capability_bounding_set_drop(context->capability_bounding_set, false); if (r < 0) { *exit_status = EXIT_CAPABILITIES; return r; } } + /* This is done before enforce_user, but ambient set + * does not survive over setresuid() if keep_caps is not set. */ + if (context->capability_ambient_set != 0) { + r = capability_ambient_set_apply(context->capability_ambient_set, true); + if (r < 0) { + *exit_status = EXIT_CAPABILITIES; + return r; + } + + if (context->capabilities) { + + /* The capabilities in ambient set need to be also in the inherited + * set. If they aren't, trying to get them will fail. Add the ambient + * set inherited capabilities to the capability set in the context. + * This is needed because if capabilities are set (using "Capabilities=" + * keyword), they will override whatever we set now. */ + + r = capability_update_inherited_set(context->capabilities, context->capability_ambient_set); + if (r < 0) { + *exit_status = EXIT_CAPABILITIES; + return r; + } + } + } + if (context->user) { r = enforce_user(context, uid); if (r < 0) { *exit_status = EXIT_USER; return r; } + if (context->capability_ambient_set != 0) { + + /* Fix the ambient capabilities after user change. */ + r = capability_ambient_set_apply(context->capability_ambient_set, false); + if (r < 0) { + *exit_status = EXIT_CAPABILITIES; + return r; + } + + /* If we were asked to change user and ambient capabilities + * were requested, we had to add keep-caps to the securebits + * so that we would maintain the inherited capability set + * through the setresuid(). Make sure that the bit is added + * also to the context secure_bits so that we don't try to + * drop the bit away next. */ + + secure_bits |= 1<<SECURE_KEEP_CAPS; + } } /* PR_GET_SECUREBITS is not privileged, while * PR_SET_SECUREBITS is. So to suppress * potential EPERMs we'll try not to call * PR_SET_SECUREBITS unless necessary. */ - if (prctl(PR_GET_SECUREBITS) != context->secure_bits) - if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) { + if (prctl(PR_GET_SECUREBITS) != secure_bits) + if (prctl(PR_SET_SECUREBITS, secure_bits) < 0) { *exit_status = EXIT_SECUREBITS; return -errno; } @@ -2114,6 +2162,7 @@ void exec_context_init(ExecContext *c) { c->timer_slack_nsec = NSEC_INFINITY; c->personality = PERSONALITY_INVALID; c->runtime_directory_mode = 0755; + c->capability_bounding_set = CAP_ALL; } void exec_context_done(ExecContext *c) { @@ -2413,9 +2462,12 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { prefix, c->oom_score_adjust); for (i = 0; i < RLIM_NLIMITS; i++) - if (c->rlimit[i]) - fprintf(f, "%s%s: " RLIM_FMT " " RLIM_FMT "\n", - prefix, rlimit_to_string(i), c->rlimit[i]->rlim_cur, c->rlimit[i]->rlim_max); + if (c->rlimit[i]) { + fprintf(f, "%s%s: " RLIM_FMT "\n", + prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max); + fprintf(f, "%s%sSoft: " RLIM_FMT "\n", + prefix, rlimit_to_string(i), c->rlimit[i]->rlim_cur); + } if (c->ioprio_set) { _cleanup_free_ char *class_str = NULL; @@ -2514,12 +2566,23 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "", (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : ""); - if (c->capability_bounding_set_drop) { + if (c->capability_bounding_set != CAP_ALL) { unsigned long l; fprintf(f, "%sCapabilityBoundingSet:", prefix); for (l = 0; l <= cap_last_cap(); l++) - if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) + if (c->capability_bounding_set & (UINT64_C(1) << l)) + fprintf(f, " %s", strna(capability_to_name(l))); + + fputs("\n", f); + } + + if (c->capability_ambient_set != 0) { + unsigned long l; + fprintf(f, "%sAmbientCapabilities:", prefix); + + for (l = 0; l <= cap_last_cap(); l++) + if (c->capability_ambient_set & (UINT64_C(1) << l)) fprintf(f, " %s", strna(capability_to_name(l))); fputs("\n", f); diff --git a/src/core/execute.h b/src/core/execute.h index be5be9f531..8649620830 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -155,7 +155,9 @@ struct ExecContext { char **read_write_dirs, **read_only_dirs, **inaccessible_dirs; unsigned long mount_flags; - uint64_t capability_bounding_set_drop; + uint64_t capability_bounding_set; + + uint64_t capability_ambient_set; cap_t capabilities; int secure_bits; diff --git a/src/core/job.c b/src/core/job.c index 9654590635..274c554da9 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -35,6 +35,7 @@ #include "parse-util.h" #include "set.h" #include "special.h" +#include "stdio-util.h" #include "string-table.h" #include "string-util.h" #include "strv.h" @@ -754,7 +755,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) { return; DISABLE_WARNING_FORMAT_NONLITERAL; - snprintf(buf, sizeof(buf), format, unit_description(u)); + xsprintf(buf, format, unit_description(u)); REENABLE_WARNING; switch (t) { diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4 index 0408b9a829..29ab1b6b9e 100644 --- a/src/core/load-fragment-gperf.gperf.m4 +++ b/src/core/load-fragment-gperf.gperf.m4 @@ -47,7 +47,8 @@ $1.SyslogLevel, config_parse_log_level, 0, $1.SyslogLevelPrefix, config_parse_bool, 0, offsetof($1, exec_context.syslog_level_prefix) $1.Capabilities, config_parse_exec_capabilities, 0, offsetof($1, exec_context) $1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context) -$1.CapabilityBoundingSet, config_parse_bounding_set, 0, offsetof($1, exec_context.capability_bounding_set_drop) +$1.CapabilityBoundingSet, config_parse_capability_set, 0, offsetof($1, exec_context.capability_bounding_set) +$1.AmbientCapabilities, config_parse_capability_set, 0, offsetof($1, exec_context.capability_ambient_set) $1.TimerSlackNSec, config_parse_nsec, 0, offsetof($1, exec_context.timer_slack_nsec) $1.NoNewPrivileges, config_parse_no_new_privileges, 0, offsetof($1, exec_context) m4_ifdef(`HAVE_SECCOMP', diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index cb553e1252..d3880b4e3c 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -38,6 +38,7 @@ #include "bus-internal.h" #include "bus-util.h" #include "cap-list.h" +#include "capability-util.h" #include "cgroup.h" #include "conf-parser.h" #include "cpu-set-util.h" @@ -1024,7 +1025,7 @@ int config_parse_exec_secure_bits(const char *unit, return 0; } -int config_parse_bounding_set( +int config_parse_capability_set( const char *unit, const char *filename, unsigned line, @@ -1036,8 +1037,8 @@ int config_parse_bounding_set( void *data, void *userdata) { - uint64_t *capability_bounding_set_drop = data; - uint64_t capability_bounding_set, sum = 0; + uint64_t *capability_set = data; + uint64_t sum = 0, initial = 0; bool invert = false; const char *p; @@ -1051,10 +1052,9 @@ int config_parse_bounding_set( rvalue++; } - /* Note that we store this inverted internally, since the - * kernel wants it like this. But we actually expose it - * non-inverted everywhere to have a fully normalized - * interface. */ + if (strcmp(lvalue, "CapabilityBoundingSet") == 0) + initial = CAP_ALL; /* initialized to all bits on */ + /* else "AmbientCapabilities" initialized to all bits off */ p = rvalue; for (;;) { @@ -1073,18 +1073,21 @@ int config_parse_bounding_set( cap = capability_from_name(word); if (cap < 0) { - log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse capability in bounding set, ignoring: %s", word); + log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse capability in bounding/ambient set, ignoring: %s", word); continue; } sum |= ((uint64_t) UINT64_C(1)) << (uint64_t) cap; } - capability_bounding_set = invert ? ~sum : sum; - if (*capability_bounding_set_drop != 0 && capability_bounding_set != 0) - *capability_bounding_set_drop = ~(~*capability_bounding_set_drop | capability_bounding_set); + sum = invert ? ~sum : sum; + + if (sum == 0 || *capability_set == initial) + /* "" or uninitialized data -> replace */ + *capability_set = sum; else - *capability_bounding_set_drop = ~capability_bounding_set; + /* previous data -> merge */ + *capability_set |= sum; return 0; } @@ -4002,7 +4005,7 @@ void unit_dump_config_items(FILE *f) { { config_parse_log_level, "LEVEL" }, { config_parse_exec_capabilities, "CAPABILITIES" }, { config_parse_exec_secure_bits, "SECUREBITS" }, - { config_parse_bounding_set, "BOUNDINGSET" }, + { config_parse_capability_set, "BOUNDINGSET" }, { config_parse_limit, "LIMIT" }, { config_parse_unit_deps, "UNIT [...]" }, { config_parse_exec, "PATH [ARGUMENT [...]]" }, diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h index a451fc164a..f0027a6b43 100644 --- a/src/core/load-fragment.h +++ b/src/core/load-fragment.h @@ -56,7 +56,7 @@ int config_parse_exec_cpu_sched_prio(const char *unit, const char *filename, uns int config_parse_exec_cpu_affinity(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); int config_parse_exec_capabilities(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); int config_parse_exec_secure_bits(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); -int config_parse_bounding_set(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); +int config_parse_capability_set(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); int config_parse_limit(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); int config_parse_bytes_limit(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); int config_parse_sec_limit(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/core/main.c b/src/core/main.c index f9de54028e..7a428fcccf 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -117,7 +117,7 @@ static usec_t arg_runtime_watchdog = 0; static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; static char **arg_default_environment = NULL; static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {}; -static uint64_t arg_capability_bounding_set_drop = 0; +static uint64_t arg_capability_bounding_set = CAP_ALL; static nsec_t arg_timer_slack_nsec = NSEC_INFINITY; static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE; static Set* arg_syscall_archs = NULL; @@ -644,7 +644,7 @@ static int parse_config_file(void) { { "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers }, { "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog }, { "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog }, - { "Manager", "CapabilityBoundingSet", config_parse_bounding_set, 0, &arg_capability_bounding_set_drop }, + { "Manager", "CapabilityBoundingSet", config_parse_capability_set, 0, &arg_capability_bounding_set }, #ifdef HAVE_SECCOMP { "Manager", "SystemCallArchitectures", config_parse_syscall_archs, 0, &arg_syscall_archs }, #endif @@ -1631,14 +1631,14 @@ int main(int argc, char *argv[]) { if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0) log_error_errno(errno, "Failed to adjust timer slack: %m"); - if (arg_capability_bounding_set_drop) { - r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop); + if (!cap_test_all(arg_capability_bounding_set)) { + r = capability_bounding_set_drop_usermode(arg_capability_bounding_set); if (r < 0) { log_emergency_errno(r, "Failed to drop capability bounding set of usermode helpers: %m"); error_message = "Failed to drop capability bounding set of usermode helpers"; goto finish; } - r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true); + r = capability_bounding_set_drop(arg_capability_bounding_set, true); if (r < 0) { log_emergency_errno(r, "Failed to drop capability bounding set: %m"); error_message = "Failed to drop capability bounding set"; diff --git a/src/core/manager.c b/src/core/manager.c index 34dd715e93..711b0cdcee 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -380,6 +380,9 @@ static int enable_special_signals(Manager *m) { assert(m); + if (m->test_run) + return 0; + /* Enable that we get SIGINT on control-alt-del. In containers * this will fail with EPERM (older) or EINVAL (newer), so * ignore that. */ @@ -1885,23 +1888,21 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t switch (sfsi.ssi_signo - SIGRTMIN) { case 20: - log_debug("Enabling showing of status."); manager_set_show_status(m, SHOW_STATUS_YES); break; case 21: - log_debug("Disabling showing of status."); manager_set_show_status(m, SHOW_STATUS_NO); break; case 22: log_set_max_level(LOG_DEBUG); - log_notice("Setting log level to debug."); + log_info("Setting log level to debug."); break; case 23: log_set_max_level(LOG_INFO); - log_notice("Setting log level to info."); + log_info("Setting log level to info."); break; case 24: @@ -2576,6 +2577,10 @@ int manager_reload(Manager *m) { /* Third, fire things up! */ manager_coldplug(m); + /* Sync current state of bus names with our set of listening units */ + if (m->api_bus) + manager_sync_bus_names(m, m->api_bus); + assert(m->n_reloading > 0); m->n_reloading--; @@ -2961,6 +2966,9 @@ void manager_set_show_status(Manager *m, ShowStatus mode) { if (m->running_as != MANAGER_SYSTEM) return; + if (m->show_status != mode) + log_debug("%s showing of status.", + mode == SHOW_STATUS_NO ? "Disabling" : "Enabling"); m->show_status = mode; if (mode > 0) diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index 2b8d590ed1..d73b319c5d 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -304,13 +304,18 @@ int mount_cgroup_controllers(char ***join_controllers) { return log_oom(); r = symlink(options, t); - if (r < 0 && errno != EEXIST) - return log_error_errno(errno, "Failed to create symlink %s: %m", t); + if (r >= 0) { #ifdef SMACK_RUN_LABEL - r = mac_smack_copy(t, options); - if (r < 0 && r != -EOPNOTSUPP) - return log_error_errno(r, "Failed to copy smack label from %s to %s: %m", options, t); + _cleanup_free_ char *src; + src = strappend("/sys/fs/cgroup/", options); + if (!src) + return log_oom(); + r = mac_smack_copy(t, src); + if (r < 0 && r != -EOPNOTSUPP) + return log_error_errno(r, "Failed to copy smack label from %s to %s: %m", src, t); #endif + } else if (errno != EEXIST) + return log_error_errno(errno, "Failed to create symlink %s: %m", t); } } } diff --git a/src/core/service.c b/src/core/service.c index 41a729c421..c5b689a35c 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -323,6 +323,8 @@ static void service_done(Unit *u) { s->bus_name = mfree(s->bus_name); } + s->bus_name_owner = mfree(s->bus_name_owner); + s->bus_endpoint_fd = safe_close(s->bus_endpoint_fd); service_close_socket_fd(s); service_connection_unref(s); @@ -2122,6 +2124,7 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) { unit_serialize_item(u, f, "main-pid-known", yes_no(s->main_pid_known)); unit_serialize_item(u, f, "bus-name-good", yes_no(s->bus_name_good)); + unit_serialize_item(u, f, "bus-name-owner", s->bus_name_owner); r = unit_serialize_item_escaped(u, f, "status-text", s->status_text); if (r < 0) @@ -2249,6 +2252,10 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, log_unit_debug(u, "Failed to parse bus-name-good value: %s", value); else s->bus_name_good = b; + } else if (streq(key, "bus-name-owner")) { + r = free_and_strdup(&s->bus_name_owner, value); + if (r < 0) + log_unit_error_errno(u, r, "Unable to deserialize current bus owner %s: %m", value); } else if (streq(key, "status-text")) { char *t; @@ -3134,6 +3141,13 @@ static void service_bus_name_owner_change( s->bus_name_good = !!new_owner; + /* Track the current owner, so we can reconstruct changes after a daemon reload */ + r = free_and_strdup(&s->bus_name_owner, new_owner); + if (r < 0) { + log_unit_error_errno(u, r, "Unable to set new bus name owner %s: %m", new_owner); + return; + } + if (s->type == SERVICE_DBUS) { /* service_enter_running() will figure out what to diff --git a/src/core/service.h b/src/core/service.h index d0faad88e0..19efbccfc7 100644 --- a/src/core/service.h +++ b/src/core/service.h @@ -172,6 +172,7 @@ struct Service { bool reset_cpu_usage:1; char *bus_name; + char *bus_name_owner; /* unique name of the current owner */ char *status_text; int status_errno; diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c index 0661ff9ecd..c9374ca0e8 100644 --- a/src/core/smack-setup.c +++ b/src/core/smack-setup.c @@ -197,6 +197,75 @@ static int write_cipso2_rules(const char* srcdir) { return r; } +static int write_netlabel_rules(const char* srcdir) { + _cleanup_fclose_ FILE *dst = NULL; + _cleanup_closedir_ DIR *dir = NULL; + struct dirent *entry; + char buf[NAME_MAX]; + int dfd = -1; + int r = 0; + + dst = fopen("/sys/fs/smackfs/netlabel", "we"); + if (!dst) { + if (errno != ENOENT) + log_warning_errno(errno, "Failed to open /sys/fs/smackfs/netlabel: %m"); + return -errno; /* negative error */ + } + + /* write rules to dst from every file in the directory */ + dir = opendir(srcdir); + if (!dir) { + if (errno != ENOENT) + log_warning_errno(errno, "Failed to opendir %s: %m", srcdir); + return errno; /* positive on purpose */ + } + + dfd = dirfd(dir); + assert(dfd >= 0); + + FOREACH_DIRENT(entry, dir, return 0) { + int fd; + _cleanup_fclose_ FILE *policy = NULL; + + fd = openat(dfd, entry->d_name, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + if (r == 0) + r = -errno; + log_warning_errno(errno, "Failed to open %s: %m", entry->d_name); + continue; + } + + policy = fdopen(fd, "re"); + if (!policy) { + if (r == 0) + r = -errno; + safe_close(fd); + log_error_errno(errno, "Failed to open %s: %m", entry->d_name); + continue; + } + + /* load2 write rules in the kernel require a line buffered stream */ + FOREACH_LINE(buf, policy, + log_error_errno(errno, "Failed to read line from %s: %m", + entry->d_name)) { + if (!fputs(buf, dst)) { + if (r == 0) + r = -EINVAL; + log_error_errno(errno, "Failed to write line to /sys/fs/smackfs/netlabel"); + break; + } + if (fflush(dst)) { + if (r == 0) + r = -errno; + log_error_errno(errno, "Failed to flush writes to /sys/fs/smackfs/netlabel: %m"); + break; + } + } + } + + return r; +} + #endif int mac_smack_setup(bool *loaded_policy) { @@ -225,8 +294,18 @@ int mac_smack_setup(bool *loaded_policy) { #ifdef SMACK_RUN_LABEL r = write_string_file("/proc/self/attr/current", SMACK_RUN_LABEL, 0); - if (r) - log_warning_errno(r, "Failed to set SMACK label \"%s\" on self: %m", SMACK_RUN_LABEL); + if (r < 0) + log_warning_errno(r, "Failed to set SMACK label \"" SMACK_RUN_LABEL "\" on self: %m"); + r = write_string_file("/sys/fs/smackfs/ambient", SMACK_RUN_LABEL, 0); + if (r < 0) + log_warning_errno(r, "Failed to set SMACK ambient label \"" SMACK_RUN_LABEL "\": %m"); + r = write_string_file("/sys/fs/smackfs/netlabel", + "0.0.0.0/0 " SMACK_RUN_LABEL, 0); + if (r < 0) + log_warning_errno(r, "Failed to set SMACK netlabel rule \"0.0.0.0/0 " SMACK_RUN_LABEL "\": %m"); + r = write_string_file("/sys/fs/smackfs/netlabel", "127.0.0.1 -CIPSO", 0); + if (r < 0) + log_warning_errno(r, "Failed to set SMACK netlabel rule \"127.0.0.1 -CIPSO\": %m"); #endif r = write_cipso2_rules("/etc/smack/cipso.d/"); @@ -236,13 +315,29 @@ int mac_smack_setup(bool *loaded_policy) { return 0; case ENOENT: log_debug("Smack/CIPSO access rules directory '/etc/smack/cipso.d/' not found"); - return 0; + break; case 0: log_info("Successfully loaded Smack/CIPSO policies."); break; default: log_warning_errno(r, "Failed to load Smack/CIPSO access rules, ignoring: %m"); + break; + } + + r = write_netlabel_rules("/etc/smack/netlabel.d/"); + switch(r) { + case -ENOENT: + log_debug("Smack/CIPSO is not enabled in the kernel."); return 0; + case ENOENT: + log_debug("Smack network host rules directory '/etc/smack/netlabel.d/' not found"); + break; + case 0: + log_info("Successfully loaded Smack network host rules."); + break; + default: + log_warning_errno(r, "Failed to load Smack network host rules: %m, ignoring."); + break; } *loaded_policy = true; diff --git a/src/core/socket.c b/src/core/socket.c index 7beec3644e..2e4173aabc 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -28,9 +28,9 @@ #include <sys/epoll.h> #include <sys/stat.h> #include <unistd.h> +#include <linux/sctp.h> #include "sd-event.h" - #include "alloc-util.h" #include "bus-error.h" #include "bus-util.h" @@ -156,14 +156,16 @@ static void socket_done(Unit *u) { s->tcp_congestion = mfree(s->tcp_congestion); s->bind_to_device = mfree(s->bind_to_device); - free(s->smack); - free(s->smack_ip_in); - free(s->smack_ip_out); + s->smack = mfree(s->smack); + s->smack_ip_in = mfree(s->smack_ip_in); + s->smack_ip_out = mfree(s->smack_ip_out); strv_free(s->symlinks); - free(s->user); - free(s->group); + s->user = mfree(s->user); + s->group = mfree(s->group); + + s->fdname = mfree(s->fdname); s->timer_event_source = sd_event_source_unref(s->timer_event_source); } @@ -875,8 +877,14 @@ static void socket_apply_socket_options(Socket *s, int fd) { if (s->no_delay) { int b = s->no_delay; - if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &b, sizeof(b)) < 0) - log_unit_warning_errno(UNIT(s), errno, "TCP_NODELAY failed: %m"); + + if (s->socket_protocol == IPPROTO_SCTP) { + if (setsockopt(fd, SOL_SCTP, SCTP_NODELAY, &b, sizeof(b)) < 0) + log_unit_warning_errno(UNIT(s), errno, "SCTP_NODELAY failed: %m"); + } else { + if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &b, sizeof(b)) < 0) + log_unit_warning_errno(UNIT(s), errno, "TCP_NODELAY failed: %m"); + } } if (s->broadcast) { diff --git a/src/core/transaction.c b/src/core/transaction.c index 15e79d00b3..2f163190e9 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -950,7 +950,7 @@ int transaction_add_job_and_dependencies( r = transaction_add_job_and_dependencies(tr, JOB_START, dep, ret, false, false, false, ignore_order, e); if (r < 0) { log_unit_full(dep, - r == -EADDRNOTAVAIL ? LOG_DEBUG : LOG_WARNING, r, + r == -EBADR /* unit masked */ ? LOG_DEBUG : LOG_WARNING, r, "Cannot add dependency job, ignoring: %s", bus_error_message(e, r)); sd_bus_error_free(e); diff --git a/src/core/unit.c b/src/core/unit.c index f935b6a601..32267d95f5 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -51,6 +51,7 @@ #include "set.h" #include "special.h" #include "stat-util.h" +#include "stdio-util.h" #include "string-util.h" #include "strv.h" #include "unit-name.h" @@ -1412,7 +1413,7 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) { format = unit_get_status_message_format(u, t); DISABLE_WARNING_FORMAT_NONLITERAL; - snprintf(buf, sizeof(buf), format, unit_description(u)); + xsprintf(buf, format, unit_description(u)); REENABLE_WARNING; mid = t == JOB_START ? SD_MESSAGE_UNIT_STARTING : @@ -3119,7 +3120,7 @@ int unit_kill_common( killed = true; } - if (r == 0 && !killed && IN_SET(who, KILL_ALL_FAIL, KILL_CONTROL_FAIL, KILL_ALL_FAIL)) + if (r == 0 && !killed && IN_SET(who, KILL_ALL_FAIL, KILL_CONTROL_FAIL)) return -ESRCH; return r; @@ -3231,7 +3232,7 @@ int unit_patch_contexts(Unit *u) { ec->no_new_privileges = true; if (ec->private_devices) - ec->capability_bounding_set_drop |= (uint64_t) 1ULL << (uint64_t) CAP_MKNOD; + ec->capability_bounding_set &= ~(UINT64_C(1) << CAP_MKNOD); } cc = unit_get_cgroup_context(u); |