summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/.gitignore2
l---------src/core/Makefile1
-rw-r--r--src/core/dbus.c46
-rw-r--r--src/core/execute.c9
-rw-r--r--src/core/job.c4
-rw-r--r--src/core/kmod-setup.c2
-rw-r--r--src/core/main.c4
-rw-r--r--src/core/mount-setup.c3
-rw-r--r--src/core/service.c2
-rw-r--r--src/core/smack-setup.c135
-rw-r--r--src/core/socket.c7
-rw-r--r--src/core/unit.c2
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,