diff options
-rw-r--r-- | README | 7 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | src/bootchart/svg.c | 6 | ||||
-rw-r--r-- | src/core/execute.c | 9 | ||||
-rw-r--r-- | src/core/smack-setup.c | 135 | ||||
-rw-r--r-- | src/test/test-copy.c | 4 |
6 files changed, 138 insertions, 33 deletions
@@ -140,8 +140,7 @@ REQUIREMENTS: dracut (optional) PolicyKit (optional) - When building from git, you need the following additional - dependencies: + When building from git, the following tools are needed: pkg-config docbook-xsl @@ -155,6 +154,10 @@ REQUIREMENTS: python-lxml (optional, but required to build the indices) sphinx (optional) + The build system is initialized with ./autogen.sh. A tar ball + can be created with: + git archive --format=tar --prefix=systemd-222/ v222 | xz > systemd-222.tar.xz + When systemd-hostnamed is used, it is strongly recommended to install nss-myhostname to ensure that, in a world of dynamically changing hostnames, the hostname stays resolvable diff --git a/configure.ac b/configure.ac index 8b1e275d27..88b52c45fe 100644 --- a/configure.ac +++ b/configure.ac @@ -673,8 +673,14 @@ fi AC_ARG_WITH(smack-run-label, AS_HELP_STRING([--with-smack-run-label=STRING], - [run systemd --system with a specific SMACK label]), - [AC_DEFINE_UNQUOTED(SMACK_RUN_LABEL, ["$withval"], [Run with a smack label])], + [run systemd --system itself with a specific SMACK label]), + [AC_DEFINE_UNQUOTED(SMACK_RUN_LABEL, ["$withval"], [Run systemd itself with SMACK label])], + []) + +AC_ARG_WITH(smack-default-process-label, +AS_HELP_STRING([--with-smack-default-process-label=STRING], + [default SMACK label for executed processes]), + [AC_DEFINE_UNQUOTED(SMACK_DEFAULT_PROCESS_LABEL, ["$withval"], [Default SMACK label for executed processes])], []) if test "x${have_smack}" = xyes ; then diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c index 0132475e10..f442200b66 100644 --- a/src/bootchart/svg.c +++ b/src/bootchart/svg.c @@ -69,7 +69,7 @@ static double esize = 0; static struct list_sample_data *sampledata; static struct list_sample_data *prev_sampledata; -static void svg_header(FILE *of, struct list_sample_data *head, double graph_start) { +static void svg_header(FILE *of, struct list_sample_data *head, double graph_start, int n_cpus) { double w; double h; struct list_sample_data *sampledata_last; @@ -90,7 +90,7 @@ static void svg_header(FILE *of, struct list_sample_data *head, double graph_sta /* height is variable based on pss, psize, ksize */ h = 400.0 + (arg_scale_y * 30.0) /* base graphs and title */ + (arg_pss ? (100.0 * arg_scale_y) + (arg_scale_y * 7.0) : 0.0) /* pss estimate */ - + psize + ksize + esize; + + psize + ksize + esize + (n_cpus * 15 * arg_scale_y); fprintf(of, "<?xml version=\"1.0\" standalone=\"no\"?>\n"); fprintf(of, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" "); @@ -1314,7 +1314,7 @@ int svg_do(FILE *of, esize = (arg_entropy ? arg_scale_y * 7 : 0); /* after this, we can draw the header with proper sizing */ - svg_header(of, head, graph_start); + svg_header(of, head, graph_start, arg_percpu ? n_cpus : 0); fprintf(of, "<rect class=\"bg\" width=\"100%%\" height=\"100%%\" />\n\n"); fprintf(of, "<g transform=\"translate(10,400)\">\n"); 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/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/test/test-copy.c b/src/test/test-copy.c index e55ffaa16a..b1385b8b87 100644 --- a/src/test/test-copy.c +++ b/src/test/test-copy.c @@ -139,7 +139,9 @@ static void test_copy_bytes(void) { int r, r2; char buf[1024], buf2[1024]; - infd = open("/etc/os-release", O_RDONLY|O_CLOEXEC); + infd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC); + if (infd < 0) + infd = open("/etc/os-release", O_RDONLY|O_CLOEXEC); assert_se(infd >= 0); assert_se(pipe2(pipefd, O_CLOEXEC) == 0); |