diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | src/build.h | 8 | ||||
-rw-r--r-- | src/ima-setup.c | 115 | ||||
-rw-r--r-- | src/ima-setup.h | 29 | ||||
-rw-r--r-- | src/main.c | 6 |
6 files changed, 171 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index d8155fdac7..6d0b51a090 100644 --- a/Makefile.am +++ b/Makefile.am @@ -510,6 +510,7 @@ libsystemd_core_la_SOURCES = \ src/mount-setup.c \ src/hostname-setup.c \ src/selinux-setup.c \ + src/ima-setup.c \ src/loopback-setup.c \ src/kmod-setup.c \ src/locale-setup.c \ diff --git a/configure.ac b/configure.ac index fa17e8be26..47a08dda64 100644 --- a/configure.ac +++ b/configure.ac @@ -127,6 +127,19 @@ PKG_CHECK_MODULES(UDEV, [ libudev >= 172 ]) PKG_CHECK_MODULES(DBUS, [ dbus-1 >= 1.3.2 ]) PKG_CHECK_MODULES(KMOD, [ libkmod >= 5 ]) +have_ima=yes +AC_ARG_ENABLE([ima], AS_HELP_STRING([--disable-ima],[Disable optional IMA support]), + [case "${enableval}" in + yes) have_ima=yes ;; + no) have_ima=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-ima) ;; + esac], + [have_ima=yes]) + +if test "x${have_ima}" != xno ; then + AC_DEFINE(HAVE_IMA, 1, [Define if IMA is available]) +fi + have_selinux=no AC_ARG_ENABLE(selinux, AS_HELP_STRING([--disable-selinux], [Disable optional SELINUX support])) if test "x$enable_selinux" != "xno"; then @@ -609,6 +622,7 @@ AC_MSG_RESULT([ tcpwrap: ${have_tcpwrap} PAM: ${have_pam} AUDIT: ${have_audit} + IMA: ${have_ima} SELinux: ${have_selinux} XZ: ${have_xz} ACL: ${have_acl} diff --git a/src/build.h b/src/build.h index 50cd79dc7c..0619013141 100644 --- a/src/build.h +++ b/src/build.h @@ -46,6 +46,12 @@ #define _SELINUX_FEATURE_ "-SELINUX" #endif +#ifdef HAVE_IMA +#define _IMA_FEATURE_ "+IMA" +#else +#define _IMA_FEATURE_ "-IMA" +#endif + #ifdef HAVE_SYSV_COMPAT #define _SYSVINIT_FEATURE_ "+SYSVINIT" #else @@ -58,6 +64,6 @@ #define _LIBCRYPTSETUP_FEATURE_ "-LIBCRYPTSETUP" #endif -#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_ " " _SYSVINIT_FEATURE_ " " _LIBCRYPTSETUP_FEATURE_ +#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_ " " _IMA_FEATURE_ " " _SYSVINIT_FEATURE_ " " _LIBCRYPTSETUP_FEATURE_ #endif diff --git a/src/ima-setup.c b/src/ima-setup.c new file mode 100644 index 0000000000..03e43dcf16 --- /dev/null +++ b/src/ima-setup.c @@ -0,0 +1,115 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy + TORSEC group -- http://security.polito.it + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +#include <unistd.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/mman.h> + +#include "ima-setup.h" +#include "mount-setup.h" +#include "macro.h" +#include "util.h" +#include "log.h" +#include "label.h" + +#define IMA_SECFS_DIR "/sys/kernel/security/ima" +#define IMA_SECFS_POLICY IMA_SECFS_DIR "/policy" +#define IMA_POLICY_PATH "/etc/ima/ima-policy" + +int ima_setup(void) { + +#ifdef HAVE_IMA + struct stat st; + ssize_t policy_size = 0, written = 0; + char *policy; + int policyfd = -1, imafd = -1; + int result = 0; + +#ifndef HAVE_SELINUX + /* Mount the securityfs filesystem */ + mount_setup_early(); +#endif + + if (stat(IMA_POLICY_PATH, &st) < 0) + return 0; + + policy_size = st.st_size; + if (stat(IMA_SECFS_DIR, &st) < 0) { + log_debug("IMA support is disabled in the kernel, ignoring."); + return 0; + } + + if (stat(IMA_SECFS_POLICY, &st) < 0) { + log_error("Another IMA custom policy has already been loaded, " + "ignoring."); + return 0; + } + + policyfd = open(IMA_POLICY_PATH, O_RDONLY|O_CLOEXEC); + if (policyfd < 0) { + log_error("Failed to open the IMA custom policy file %s (%m), " + "ignoring.", IMA_POLICY_PATH); + return 0; + } + + imafd = open(IMA_SECFS_POLICY, O_WRONLY|O_CLOEXEC); + if (imafd < 0) { + log_error("Failed to open the IMA kernel interface %s (%m), " + "ignoring.", IMA_SECFS_POLICY); + goto out; + } + + policy = mmap(NULL, policy_size, PROT_READ, MAP_PRIVATE, policyfd, 0); + if (policy == MAP_FAILED) { + log_error("mmap() failed (%m), freezing"); + result = -errno; + goto out; + } + + written = loop_write(imafd, policy, (size_t)policy_size, false); + if (written != policy_size) { + log_error("Failed to load the IMA custom policy file %s (%m), " + "ignoring.", IMA_POLICY_PATH); + goto out_mmap; + } + + log_info("Successfully loaded the IMA custom policy %s.", + IMA_POLICY_PATH); +out_mmap: + munmap(policy, policy_size); +out: + if (policyfd >= 0) + close_nointr_nofail(policyfd); + if (imafd >= 0) + close_nointr_nofail(imafd); + if (result) + return result; +#endif /* HAVE_IMA */ + + return 0; +} diff --git a/src/ima-setup.h b/src/ima-setup.h new file mode 100644 index 0000000000..7d677cf852 --- /dev/null +++ b/src/ima-setup.h @@ -0,0 +1,29 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +#ifndef fooimasetuphfoo +#define fooimasetuphfoo + +/*** + This file is part of systemd. + + Copyright 2010 Lennart Poettering + Copyright (C) 2012 Roberto Sassu - Politecnico di Torino, Italy + TORSEC group -- http://security.polito.it + + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with systemd; If not, see <http://www.gnu.org/licenses/>. +***/ + +int ima_setup(void); + +#endif diff --git a/src/main.c b/src/main.c index ed317b4413..7ae88414a9 100644 --- a/src/main.c +++ b/src/main.c @@ -41,6 +41,7 @@ #include "kmod-setup.h" #include "locale-setup.h" #include "selinux-setup.h" +#include "ima-setup.h" #include "machine-id-setup.h" #include "load-fragment.h" #include "fdset.h" @@ -1203,9 +1204,12 @@ int main(int argc, char *argv[]) { arg_running_as = MANAGER_SYSTEM; log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_CONSOLE : LOG_TARGET_JOURNAL_OR_KMSG); - if (!is_reexec) + if (!is_reexec) { if (selinux_setup(&loaded_policy) < 0) goto finish; + if (ima_setup() < 0) + goto finish; + } log_open(); |