X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fsmack-setup.c;h=611bfdb2df155b20e51bf84ff95a478246c50ec9;hp=88e6437445414050bcf161bc67f957e426621148;hb=454f7158c6cecd18555c5e7dd556e3d544301b52;hpb=ffbd2c4d45787ba5ba85a32db6551efba66a1ee6 diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c index 88e643744..611bfdb2d 100644 --- a/src/core/smack-setup.c +++ b/src/core/smack-setup.c @@ -36,63 +36,134 @@ #include "macro.h" #include "smack-setup.h" #include "util.h" +#include "fileio.h" #include "log.h" #include "label.h" -#define ACCESSES_D_PATH "/etc/smack/accesses.d/" +#define SMACK_CONFIG "/etc/smack/accesses.d/" +#define CIPSO_CONFIG "/etc/smack/cipso.d/" -int smack_setup(void) { - _cleanup_fclose_ FILE *smack = NULL; +#ifdef HAVE_SMACK + +static int write_rules(const char* dstpath, 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; - smack = fopen("/sys/fs/smackfs/load2", "we"); - if (!smack) { - log_info("Smack is not enabled in the kernel, not loading access rules."); - return 0; + dst = fopen(dstpath, "we"); + if (!dst) { + if (errno != ENOENT) + log_warning("Failed to open %s: %m", dstpath); + return -errno; /* negative error */ } - /* write rules to load2 from every file in the directory */ - dir = opendir(ACCESSES_D_PATH); + /* write rules to dst from every file in the directory */ + dir = opendir(srcdir); if (!dir) { - log_info("Smack access rules directory not found: " ACCESSES_D_PATH); - return 0; + if (errno != ENOENT) + log_warning("Failed to opendir %s: %m", srcdir); + return errno; /* positive on purpose */ } dfd = dirfd(dir); - if (dfd < 0) { - log_error("Smack access rules directory " ACCESSES_D_PATH " not opened: %m"); - return 0; - } + assert(dfd >= 0); FOREACH_DIRENT(entry, dir, return 0) { + int fd; _cleanup_fclose_ FILE *policy = NULL; - _cleanup_close_ int pol = -1; - pol = openat(dfd, entry->d_name, O_RDONLY|O_CLOEXEC); - if (pol < 0) { - log_error("Smack access rule file %s not opened: %m", entry->d_name); + fd = openat(dfd, entry->d_name, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + if (r == 0) + r = -errno; + log_warning("Failed to open %s: %m", entry->d_name); continue; } - policy = fdopen(pol, "re"); + policy = fdopen(fd, "re"); if (!policy) { - log_error("Smack access rule file %s not opened: %m", entry->d_name); + if (r == 0) + r = -errno; + close_nointr_nofail(fd); + log_error("Failed to open %s: %m", entry->d_name); continue; } - pol = -1; - /* load2 write rules in the kernel require a line buffered stream */ - FOREACH_LINE(buf, policy, log_error("Failed to read from Smack access rule file %s: %m", entry->d_name)) { - fputs(buf, smack); - fflush(smack); + FOREACH_LINE(buf, policy, + log_error("Failed to read line from %s: %m", + entry->d_name)) { + if (!fputs(buf, dst)) { + if (r == 0) + r = -EINVAL; + log_error("Failed to write line to %s", dstpath); + break; + } + if (fflush(dst)) { + if (r == 0) + r = -errno; + log_error("Failed to flush writes to %s: %m", dstpath); + break; + } } } - log_info("Successfully loaded Smack policies."); + return r; +} + +#endif + +int smack_setup(void) { + +#ifdef HAVE_SMACK + + int r; + + r = write_rules("/sys/fs/smackfs/load2", SMACK_CONFIG); + 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"); + return 0; + case 0: + log_info("Successfully loaded Smack policies."); + break; + default: + log_warning("Failed to load Smack access rules: %s, ignoring.", + strerror(abs(r))); + return 0; + } + +#ifdef SMACK_RUN_LABEL + r = write_string_file("/proc/self/attr/current", SMACK_RUN_LABEL); + if (r) + log_warning("Failed to set SMACK label \"%s\" on self: %s", + SMACK_RUN_LABEL, strerror(-r)); +#endif + + r = write_rules("/sys/fs/smackfs/cipso2", CIPSO_CONFIG); + 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"); + return 0; + case 0: + log_info("Successfully loaded Smack/CIPSO policies."); + return 0; + default: + log_warning("Failed to load Smack/CIPSO access rules: %s, ignoring.", + strerror(abs(r))); + return 0; + } + +#endif return 0; }