diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/.gitignore | 2 | ||||
l--------- | src/core/Makefile | 1 | ||||
-rw-r--r-- | src/core/dbus.c | 46 | ||||
-rw-r--r-- | src/core/execute.c | 9 | ||||
-rw-r--r-- | src/core/job.c | 4 | ||||
-rw-r--r-- | src/core/kmod-setup.c | 2 | ||||
-rw-r--r-- | src/core/main.c | 4 | ||||
-rw-r--r-- | src/core/mount-setup.c | 3 | ||||
-rw-r--r-- | src/core/service.c | 2 | ||||
-rw-r--r-- | src/core/smack-setup.c | 135 | ||||
-rw-r--r-- | src/core/socket.c | 7 | ||||
-rw-r--r-- | src/core/unit.c | 2 |
12 files changed, 167 insertions, 50 deletions
diff --git a/src/core/.gitignore b/src/core/.gitignore new file mode 100644 index 0000000000..f293bbdc93 --- /dev/null +++ b/src/core/.gitignore @@ -0,0 +1,2 @@ +/macros.systemd +/systemd.pc diff --git a/src/core/Makefile b/src/core/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/core/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/core/dbus.c b/src/core/dbus.c index 86886e6d2c..057653a8b5 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -69,13 +69,37 @@ int bus_send_queued_message(Manager *m) { } static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + const char *cgroup, *me; Manager *m = userdata; - const char *cgroup; + uid_t sender_uid; + sd_bus *bus; int r; assert(message); assert(m); + /* ignore recursive events sent by us on the system/user bus */ + bus = sd_bus_message_get_bus(message); + if (!sd_bus_is_server(bus)) { + r = sd_bus_get_unique_name(bus, &me); + if (r < 0) + return r; + + if (streq_ptr(sd_bus_message_get_sender(message), me)) + return 0; + } + + /* only accept org.freedesktop.systemd1.Agent from UID=0 */ + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_euid(creds, &sender_uid); + if (r < 0 || sender_uid != 0) + return 0; + + /* parse 'cgroup-empty' notification */ r = sd_bus_message_read(message, "s", &cgroup); if (r < 0) { bus_log_parse_error(r); @@ -84,19 +108,15 @@ static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus manager_notify_cgroup_empty(m, cgroup); - /* only forward to system bus if running as system instance */ - if (m->running_as != MANAGER_SYSTEM || !m->system_bus) - return 0; - - r = sd_bus_message_rewind(message, 1); - if (r < 0) - goto exit; - - r = sd_bus_send(m->system_bus, message, NULL); + /* if running as system-instance, forward under our name */ + if (m->running_as == MANAGER_SYSTEM && m->system_bus) { + r = sd_bus_message_rewind(message, 1); + if (r >= 0) + r = sd_bus_send(m->system_bus, message, NULL); + if (r < 0) + log_warning_errno(r, "Failed to forward Released message: %m"); + } -exit: - if (r < 0) - log_warning_errno(r, "Failed to forward Released message: %m"); return 0; } diff --git a/src/core/execute.c b/src/core/execute.c index 94cc101738..c92db51330 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1717,6 +1717,15 @@ static int exec_child( return r; } } +#ifdef SMACK_DEFAULT_PROCESS_LABEL + else { + r = mac_smack_apply_pid(0, SMACK_DEFAULT_PROCESS_LABEL); + if (r < 0) { + *exit_status = EXIT_SMACK_PROCESS_LABEL; + return r; + } + } +#endif #endif if (context->user) { diff --git a/src/core/job.c b/src/core/job.c index 8a047df0c3..1448e5b69a 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -452,7 +452,7 @@ static bool job_is_runnable(Job *j) { j->type == JOB_RELOAD) { /* Immediate result is that the job is or might be - * started. In this case lets wait for the + * started. In this case let's wait for the * dependencies, regardless whether they are * starting or stopping something. */ @@ -462,7 +462,7 @@ static bool job_is_runnable(Job *j) { } /* Also, if something else is being stopped and we should - * change state after it, then lets wait. */ + * change state after it, then let's wait. */ SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) if (other->job && diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c index e7a6bdc8c4..fc6d2f4acb 100644 --- a/src/core/kmod-setup.c +++ b/src/core/kmod-setup.c @@ -116,7 +116,7 @@ int kmod_setup(void) { else if (r == KMOD_PROBE_APPLY_BLACKLIST) log_info("Module '%s' is blacklisted", kmod_module_get_name(mod)); else { - bool print_warning = kmod_table[i].warn_if_unavailable || (r < 0 && r != -ENOSYS); + bool print_warning = kmod_table[i].warn_if_unavailable || (r < 0 && r != -ENOENT); log_full_errno(print_warning ? LOG_WARNING : LOG_DEBUG, r, "Failed to insert module '%s': %m", kmod_module_get_name(mod)); diff --git a/src/core/main.c b/src/core/main.c index 332453a0ea..523f0ce020 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1995,6 +1995,10 @@ finish: command_line[pos++] = "kmsg"; break; + case LOG_TARGET_NULL: + command_line[pos++] = "null"; + break; + case LOG_TARGET_CONSOLE: default: command_line[pos++] = "console"; diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index 42a6b952b9..1782d40720 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -27,6 +27,7 @@ #include "mount-setup.h" #include "dev-setup.h" +#include "bus-util.h" #include "log.h" #include "macro.h" #include "util.h" @@ -105,7 +106,7 @@ static const MountPoint mount_table[] = { is_efi_boot, MNT_NONE }, #endif { "kdbusfs", "/sys/fs/kdbus", "kdbusfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, - NULL, MNT_IN_CONTAINER }, + is_kdbus_wanted, MNT_IN_CONTAINER }, }; /* These are API file systems that might be mounted by other software, diff --git a/src/core/service.c b/src/core/service.c index fa1e80b710..d72ff54daa 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1235,7 +1235,7 @@ static int main_pid_good(Service *s) { /* Returns 0 if the pid is dead, 1 if it is good, -1 if we * don't know */ - /* If we know the pid file, then lets just check if it is + /* If we know the pid file, then let's just check if it is * still valid */ if (s->main_pid_known) { diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c index ff2a02004d..ddb02a1580 100644 --- a/src/core/smack-setup.c +++ b/src/core/smack-setup.c @@ -34,31 +34,35 @@ #include "fileio.h" #include "log.h" -#define SMACK_CONFIG "/etc/smack/accesses.d/" -#define CIPSO_CONFIG "/etc/smack/cipso.d/" - #ifdef HAVE_SMACK -static int write_rules(const char* dstpath, const char* srcdir) { - _cleanup_fclose_ FILE *dst = NULL; +static int write_access2_rules(const char* srcdir) { + _cleanup_close_ int load2_fd = -1, change_fd = -1; _cleanup_closedir_ DIR *dir = NULL; struct dirent *entry; char buf[NAME_MAX]; int dfd = -1; int r = 0; - dst = fopen(dstpath, "we"); - if (!dst) { + load2_fd = open("/sys/fs/smackfs/load2", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (load2_fd < 0) { + if (errno != ENOENT) + log_warning_errno(errno, "Failed to open '/sys/fs/smackfs/load2': %m"); + return -errno; /* negative error */ + } + + change_fd = open("/sys/fs/smackfs/change-rule", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (change_fd < 0) { if (errno != ENOENT) - log_warning_errno(errno, "Failed to open %s: %m", dstpath); + log_warning_errno(errno, "Failed to open '/sys/fs/smackfs/change-rule': %m"); return -errno; /* negative error */ } - /* write rules to dst from every file in the directory */ + /* write rules to load2 or change-rule from every file in the directory */ dir = opendir(srcdir); if (!dir) { if (errno != ENOENT) - log_warning_errno(errno, "Failed to opendir %s: %m", srcdir); + log_warning_errno(errno, "Failed to opendir '%s': %m", srcdir); return errno; /* positive on purpose */ } @@ -69,11 +73,14 @@ static int write_rules(const char* dstpath, const char* srcdir) { int fd; _cleanup_fclose_ FILE *policy = NULL; + if (!dirent_is_file(entry)) + continue; + 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); + log_warning_errno(errno, "Failed to open '%s': %m", entry->d_name); continue; } @@ -82,30 +89,108 @@ static int write_rules(const char* dstpath, const char* srcdir) { if (r == 0) r = -errno; safe_close(fd); - log_error_errno(errno, "Failed to open %s: %m", entry->d_name); + 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)) { + log_error_errno(errno, "Failed to read line from '%s': %m", + entry->d_name)) { + + _cleanup_free_ char *sbj = NULL, *obj = NULL, *acc1 = NULL, *acc2 = NULL; + + if (isempty(truncate_nl(buf))) + continue; + + /* if 3 args -> load rule : subject object access1 */ + /* if 4 args -> change rule : subject object access1 access2 */ + if (sscanf(buf, "%ms %ms %ms %ms", &sbj, &obj, &acc1, &acc2) < 3) { + log_error_errno(errno, "Failed to parse rule '%s' in '%s', ignoring.", buf, entry->d_name); + continue; + } + + if (write(isempty(acc2) ? load2_fd : change_fd, buf, strlen(buf)) < 0) { if (r == 0) - r = -EINVAL; - log_error("Failed to write line to %s", dstpath); - break; + r = -errno; + log_error_errno(errno, "Failed to write '%s' to '%s' in '%s'", + buf, isempty(acc2) ? "/sys/fs/smackfs/load2" : "/sys/fs/smackfs/change-rule", entry->d_name); } - if (fflush(dst)) { + } + } + + return r; +} + +static int write_cipso2_rules(const char* srcdir) { + _cleanup_close_ int cipso2_fd = -1; + _cleanup_closedir_ DIR *dir = NULL; + struct dirent *entry; + char buf[NAME_MAX]; + int dfd = -1; + int r = 0; + + cipso2_fd = open("/sys/fs/smackfs/cipso2", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (cipso2_fd < 0) { + if (errno != ENOENT) + log_warning_errno(errno, "Failed to open '/sys/fs/smackfs/cipso2': %m"); + return -errno; /* negative error */ + } + + /* write rules to cipso2 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; + + if (!dirent_is_file(entry)) + continue; + + fd = openat(dfd, entry->d_name, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + if (r == 0) + r = -errno; + log_error_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; + } + + /* cipso2 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 (isempty(truncate_nl(buf))) + continue; + + if (write(cipso2_fd, buf, strlen(buf)) < 0) { if (r == 0) r = -errno; - log_error_errno(errno, "Failed to flush writes to %s: %m", dstpath); + log_error_errno(errno, "Failed to write '%s' to '/sys/fs/smackfs/cipso2' in '%s'", + buf, entry->d_name); break; } } } - return r; + return r; } #endif @@ -118,13 +203,13 @@ int mac_smack_setup(bool *loaded_policy) { assert(loaded_policy); - r = write_rules("/sys/fs/smackfs/load2", SMACK_CONFIG); + r = write_access2_rules("/etc/smack/accesses.d/"); switch(r) { case -ENOENT: log_debug("Smack is not enabled in the kernel."); return 0; case ENOENT: - log_debug("Smack access rules directory " SMACK_CONFIG " not found"); + log_debug("Smack access rules directory '/etc/smack/accesses.d/' not found"); return 0; case 0: log_info("Successfully loaded Smack policies."); @@ -142,13 +227,13 @@ int mac_smack_setup(bool *loaded_policy) { SMACK_RUN_LABEL, strerror(-r)); #endif - r = write_rules("/sys/fs/smackfs/cipso2", CIPSO_CONFIG); + r = write_cipso2_rules("/etc/smack/cipso.d/"); switch(r) { case -ENOENT: log_debug("Smack/CIPSO is not enabled in the kernel."); return 0; case ENOENT: - log_debug("Smack/CIPSO access rules directory " CIPSO_CONFIG " not found"); + log_debug("Smack/CIPSO access rules directory '/etc/smack/cipso.d/' not found"); return 0; case 0: log_info("Successfully loaded Smack/CIPSO policies."); diff --git a/src/core/socket.c b/src/core/socket.c index d3178e642b..693cbc6080 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -922,12 +922,6 @@ static void socket_apply_socket_options(Socket *s, int fd) { if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0) log_unit_warning_errno(UNIT(s), errno, "TCP_CONGESTION failed: %m"); - if (s->reuse_port) { - int b = s->reuse_port; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &b, sizeof(b)) < 0) - log_unit_warning_errno(UNIT(s), errno, "SO_REUSEPORT failed: %m"); - } - if (s->smack_ip_in) { r = mac_smack_apply_ip_in_fd(fd, s->smack_ip_in); if (r < 0) @@ -1183,6 +1177,7 @@ static int socket_open_fds(Socket *s) { s->backlog, s->bind_ipv6_only, s->bind_to_device, + s->reuse_port, s->free_bind, s->transparent, s->directory_mode, diff --git a/src/core/unit.c b/src/core/unit.c index 7bb2afc9f2..fac017c57d 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1596,7 +1596,7 @@ static void unit_check_unneeded(Unit *u) { static const UnitDependency needed_dependencies[] = { UNIT_REQUIRED_BY, UNIT_REQUIRED_BY_OVERRIDABLE, - UNIT_REQUISITE, + UNIT_REQUISITE_OF, UNIT_REQUISITE_OF_OVERRIDABLE, UNIT_WANTED_BY, UNIT_BOUND_BY, |