[lxc-devel] [PATCH v2 rebased against github master 9d0cda4f] refactor AppArmor into LSM backend, add SELinux support
Serge Hallyn
serge.hallyn at ubuntu.com
Wed Sep 25 22:09:35 UTC 2013
Quoting Dwight Engen (dwight.engen at oracle.com):
> Currently, a maximum of one LSM within LXC will be initialized and
> used. If in the future stacked LSMs become a reality, we can support it
> without changing the configuration syntax and add support for more than
> a single LSM at a time to the lsm code.
>
> Generic LXC code should note that lsm_process_label_set() will take
> effect "now" for AppArmor, and upon exec() for SELinux.
>
> - fix Oracle template mounting of proc and sysfs, needed when using SELinux
>
> Signed-off-by: Dwight Engen <dwight.engen at oracle.com>
Thanks, Dwight, this worked perfectly for me with and without apparmor
compiled in. Tested lxc-start and lxc-attach (and checked
new context of course)
Acked-by: Serge E. Hallyn <serge.hallyn at ubuntu.com>
> ---
> configure.ac | 14 +++
> doc/lxc.conf.sgml.in | 25 ++++++
> src/lxc/Makefile.am | 21 ++++-
> src/lxc/apparmor.c | 230 ------------------------------------------------
> src/lxc/apparmor.h | 56 ------------
> src/lxc/attach.c | 31 +++----
> src/lxc/attach.h | 2 +-
> src/lxc/conf.c | 43 +++------
> src/lxc/conf.h | 12 +--
> src/lxc/confile.c | 56 +++++++-----
> src/lxc/lsm/apparmor.c | 179 +++++++++++++++++++++++++++++++++++++
> src/lxc/lsm/lsm.c | 156 ++++++++++++++++++++++++++++++++
> src/lxc/lsm/lsm.h | 52 +++++++++++
> src/lxc/lsm/nop.c | 46 ++++++++++
> src/lxc/lsm/selinux.c | 101 +++++++++++++++++++++
> src/lxc/start.c | 15 +++-
> src/lxc/start.h | 3 -
> templates/lxc-oracle.in | 9 +-
> 18 files changed, 674 insertions(+), 377 deletions(-)
> delete mode 100644 src/lxc/apparmor.c
> delete mode 100644 src/lxc/apparmor.h
> create mode 100644 src/lxc/lsm/apparmor.c
> create mode 100644 src/lxc/lsm/lsm.c
> create mode 100644 src/lxc/lsm/lsm.h
> create mode 100644 src/lxc/lsm/nop.c
> create mode 100644 src/lxc/lsm/selinux.c
>
> diff --git a/configure.ac b/configure.ac
> index adc4e8a..1a5c8aa 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -116,6 +116,20 @@ AM_COND_IF([ENABLE_APPARMOR],
> AC_CHECK_LIB([apparmor], [aa_change_profile],[],[AC_MSG_ERROR([You must install the AppArmor development package in order to compile lxc])])
> AC_SUBST([APPARMOR_LIBS], [-lapparmor])])
>
> +# SELinux
> +AC_ARG_ENABLE([selinux],
> + [AC_HELP_STRING([--enable-selinux], [enable SELinux support])],
> + [], [enable_selinux=check])
> +
> +if test "x$enable_selinux" = xcheck; then
> + AC_CHECK_LIB([selinux],[setexeccon_raw],[enable_selinux=yes],[enable_selinux=no])
> +fi
> +AM_CONDITIONAL([ENABLE_SELINUX], [test "x$enable_selinux" = "xyes"])
> +AM_COND_IF([ENABLE_SELINUX],
> + [AC_CHECK_HEADER([selinux/selinux.h],[],[AC_MSG_ERROR([You must install the SELinux development package in order to compile lxc])])
> + AC_CHECK_LIB([selinux], [setexeccon_raw],[],[AC_MSG_ERROR([You must install the SELinux development package in order to compile lxc])])
> + AC_SUBST([SELINUX_LIBS])])
> +
> # Seccomp syscall filter
> AC_ARG_ENABLE([seccomp],
> [AC_HELP_STRING([--enable-seccomp], [enable seccomp])],
> diff --git a/doc/lxc.conf.sgml.in b/doc/lxc.conf.sgml.in
> index dc416e8..bad553c 100644
> --- a/doc/lxc.conf.sgml.in
> +++ b/doc/lxc.conf.sgml.in
> @@ -811,6 +811,31 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> </refsect2>
>
> <refsect2>
> + <title>SELinux context</title>
> + <para>
> + If lxc was compiled and installed with SELinux support, and the host
> + system has SELinux enabled, then the SELinux context under which the
> + container should be run can be specified in the container
> + configuration. The default is <command>unconfined_t</command>,
> + which means that lxc will not attempt to change contexts.
> + </para>
> + <variablelist>
> + <varlistentry>
> + <term>
> + <option>lxc.se_context</option>
> + </term>
> + <listitem>
> + <para>
> + Specify the SELinux context under which the container should
> + be run or <command>unconfined_t</command>. For example
> + </para>
> + <programlisting>lxc.se_context = unconfined_u:unconfined_r:lxc_t:s0-s0:c0.c1023</programlisting>
> + </listitem>
> + </varlistentry>
> + </variablelist>
> + </refsect2>
> +
> + <refsect2>
> <title>Seccomp configuration</title>
> <para>
> A container can be started with a reduced set of available
> diff --git a/src/lxc/Makefile.am b/src/lxc/Makefile.am
> index f19a994..873b97d 100644
> --- a/src/lxc/Makefile.am
> +++ b/src/lxc/Makefile.am
> @@ -37,6 +37,18 @@ sodir=$(libdir)
> # use PROGRAMS to avoid complains from automake
> so_PROGRAMS = liblxc.so
>
> +LSM_SOURCES = \
> + lsm/nop.c \
> + lsm/lsm.h lsm/lsm.c
> +
> +if ENABLE_APPARMOR
> +LSM_SOURCES += lsm/apparmor.c
> +endif
> +
> +if ENABLE_SELINUX
> +LSM_SOURCES += lsm/selinux.c
> +endif
> +
> liblxc_so_SOURCES = \
> arguments.c arguments.h \
> bdev.c bdev.h \
> @@ -73,10 +85,11 @@ liblxc_so_SOURCES = \
> af_unix.c af_unix.h \
> \
> lxcutmp.c lxcutmp.h \
> - apparmor.c apparmor.h \
> lxclock.h lxclock.c \
> lxccontainer.c lxccontainer.h \
> - version.c version.h
> + version.c version.h \
> + \
> + $(LSM_SOURCES)
>
> if IS_BIONIC
> liblxc_so_SOURCES += \
> @@ -107,6 +120,10 @@ if ENABLE_APPARMOR
> AM_CFLAGS += -DHAVE_APPARMOR
> endif
>
> +if ENABLE_SELINUX
> +AM_CFLAGS += -DHAVE_SELINUX
> +endif
> +
> if HAVE_NEWUIDMAP
> AM_CFLAGS += -DHAVE_NEWUIDMAP
> endif
> diff --git a/src/lxc/apparmor.c b/src/lxc/apparmor.c
> deleted file mode 100644
> index c31cce7..0000000
> --- a/src/lxc/apparmor.c
> +++ /dev/null
> @@ -1,230 +0,0 @@
> -/* apparmor
> - *
> - * Copyright © 2012 Serge Hallyn <serge.hallyn at ubuntu.com>.
> - * Copyright © 2012 Canonical Ltd.
> - *
> - * This library is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2.1 of the License, or (at your option) any later version.
> -
> - * This library 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
> - * Lesser General Public License for more details.
> -
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with this library; if not, write to the Free Software
> - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> - */
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <unistd.h>
> -#include <errno.h>
> -#include <sys/types.h>
> -#include <sys/stat.h>
> -#include <sys/mount.h>
> -
> -#include "log.h"
> -#include "apparmor.h"
> -#include "lxclock.h"
> -
> -lxc_log_define(lxc_apparmor, lxc);
> -
> -#if HAVE_APPARMOR
> -#include <sys/apparmor.h>
> -
> -#define AA_MOUNT_RESTR "/sys/kernel/security/apparmor/features/mount/mask"
> -#define AA_ENABLED_FILE "/sys/module/apparmor/parameters/enabled"
> -
> -
> -/* caller must free the returned profile */
> -extern char *aa_get_profile(pid_t pid)
> -{
> - char path[100], *space;
> - int ret;
> - char *buf = NULL;
> - int sz = 0;
> - FILE *f;
> -
> - ret = snprintf(path, 100, "/proc/%d/attr/current", pid);
> - if (ret < 0 || ret >= 100) {
> - ERROR("path name too long");
> - return NULL;
> - }
> -again:
> - process_lock();
> - f = fopen(path, "r");
> - process_unlock();
> - if (!f) {
> - SYSERROR("opening %s\n", path);
> - if (buf)
> - free(buf);
> - return NULL;
> - }
> - sz += 1024;
> - buf = realloc(buf, sz);
> - memset(buf, 0, sz);
> - if (!buf) {
> - ERROR("out of memory");
> - process_lock();
> - fclose(f);
> - process_unlock();
> - return NULL;
> - }
> - ret = fread(buf, 1, sz - 1, f);
> - process_lock();
> - fclose(f);
> - process_unlock();
> - if (ret >= sz)
> - goto again;
> - if (ret < 0) {
> - ERROR("reading %s\n", path);
> - free(buf);
> - return NULL;
> - }
> - space = index(buf, '\n');
> - if (space)
> - *space = '\0';
> - space = index(buf, ' ');
> - if (space)
> - *space = '\0';
> - return buf;
> -}
> -
> -static int aa_am_unconfined(void)
> -{
> - char *p = aa_get_profile(getpid());
> - int ret = 0;
> - if (!p || strcmp(p, "unconfined") == 0)
> - ret = 1;
> - if (p)
> - free(p);
> - return ret;
> -}
> -
> -/* aa_getcon is not working right now. Use our hand-rolled version below */
> -static int check_apparmor_enabled(void)
> -{
> - struct stat statbuf;
> - FILE *fin;
> - char e;
> - int ret;
> -
> - ret = stat(AA_MOUNT_RESTR, &statbuf);
> - if (ret != 0)
> - return 0;
> - process_lock();
> - fin = fopen(AA_ENABLED_FILE, "r");
> - process_unlock();
> - if (!fin)
> - return 0;
> - ret = fscanf(fin, "%c", &e);
> - process_lock();
> - fclose(fin);
> - process_unlock();
> - if (ret == 1 && e == 'Y')
> - return 1;
> - return 0;
> -}
> -
> -extern void apparmor_handler_init(struct lxc_handler *handler)
> -{
> - handler->aa_enabled = check_apparmor_enabled();
> - INFO("aa_enabled set to %d\n", handler->aa_enabled);
> -}
> -
> -#define AA_DEF_PROFILE "lxc-container-default"
> -
> -extern int do_apparmor_load(int aa_enabled, char *aa_profile,
> - int umount_proc, int dropprivs)
> -{
> - if (!aa_enabled) {
> - INFO("apparmor not enabled");
> - return 0;
> - }
> - INFO("setting up apparmor");
> -
> - if (!aa_profile)
> - aa_profile = AA_DEF_PROFILE;
> -
> - if (strcmp(aa_profile, "unconfined") == 0 && !dropprivs && aa_am_unconfined()) {
> - INFO("apparmor profile unchanged");
> - return 0;
> - }
> -
> - //if (aa_change_onexec(aa_profile) < 0) {
> - if (aa_change_profile(aa_profile) < 0) {
> - SYSERROR("failed to change apparmor profile to %s", aa_profile);
> - return -1;
> - }
> - if (umount_proc == 1)
> - umount("/proc");
> -
> - INFO("changed apparmor profile to %s", aa_profile);
> -
> - return 0;
> -}
> -
> -extern int apparmor_load(struct lxc_handler *handler)
> -{
> - if (!handler->conf->aa_profile)
> - handler->conf->aa_profile = AA_DEF_PROFILE;
> - return do_apparmor_load(handler->aa_enabled,
> - handler->conf->aa_profile,
> - handler->conf->lsm_umount_proc, 0);
> -}
> -
> -extern int attach_apparmor(char *profile)
> -{
> - if (!profile)
> - return 0;
> - if (!check_apparmor_enabled())
> - return 0;
> - if (strcmp(profile, "unconfined") == 0)
> - return 0;
> - return do_apparmor_load(1, profile, 0, 1);
> -}
> -
> -/*
> - * this will likely move to a generic lsm.c, as selinux and smack will both
> - * also want proc mounted in the container so as to transition
> - */
> -extern int lsm_mount_proc_if_needed(char *root_src, char *rootfs_tgt)
> -{
> - char path[MAXPATHLEN];
> - char link[20];
> - int linklen, ret;
> -
> - ret = snprintf(path, MAXPATHLEN, "%s/proc/self", root_src ? rootfs_tgt : "");
> - if (ret < 0 || ret >= MAXPATHLEN) {
> - SYSERROR("proc path name too long");
> - return -1;
> - }
> - memset(link, 0, 20);
> - linklen = readlink(path, link, 20);
> - INFO("I am %d, /proc/self points to %s\n", getpid(), link);
> - ret = snprintf(path, MAXPATHLEN, "%s/proc", root_src ? rootfs_tgt : "");
> - if (linklen < 0) /* /proc not mounted */
> - goto domount;
> - /* can't be longer than rootfs/proc/1 */
> - if (strncmp(link, "1", linklen) != 0) {
> - /* wrong /procs mounted */
> - umount2(path, MNT_DETACH); /* ignore failure */
> - goto domount;
> - }
> - /* the right proc is already mounted */
> - return 0;
> -
> -domount:
> - if (mount("proc", path, "proc", 0, NULL))
> - return -1;
> - INFO("Mounted /proc for the container\n");
> - return 1;
> -}
> -#else
> -extern void apparmor_handler_init(struct lxc_handler *handler) {
> - INFO("apparmor_load - apparmor is disabled");
> -}
> -#endif
> diff --git a/src/lxc/apparmor.h b/src/lxc/apparmor.h
> deleted file mode 100644
> index e27a728..0000000
> --- a/src/lxc/apparmor.h
> +++ /dev/null
> @@ -1,56 +0,0 @@
> -/* apparmor
> - *
> - * Copyright © 2012 Serge Hallyn <serge.hallyn at ubuntu.com>.
> - * Copyright © 2012 Canonical Ltd.
> - *
> - * This library is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU Lesser General Public
> - * License as published by the Free Software Foundation; either
> - * version 2.1 of the License, or (at your option) any later version.
> -
> - * This library 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
> - * Lesser General Public License for more details.
> -
> - * You should have received a copy of the GNU Lesser General Public
> - * License along with this library; if not, write to the Free Software
> - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> - */
> -
> -#include <lxc/start.h> /* for lxc_handler */
> -#include <lxc/conf.h>
> -
> -struct lxc_handler;
> -
> -/*
> - * apparmor_handler_init is really just a wrapper around check_apparmor_enabled
> - * to allow us to keep from having #ifdef APPARMOR in start.c
> - */
> -extern void apparmor_handler_init(struct lxc_handler *handler);
> -
> -#if HAVE_APPARMOR
> -extern char *aa_get_profile(pid_t pid);
> -extern int do_apparmor_load(int aa_enabled, char *aa_profile,
> - int umount_proc, int dropprivs);
> -extern int apparmor_load(struct lxc_handler *handler);
> -extern int attach_apparmor(char *profile);
> -extern int lsm_mount_proc_if_needed(char *root_src, char *rootfs_tgt);
> -#else
> -static inline char *aa_get_profile(pid_t pid) {
> - return NULL;
> -}
> -static inline int do_apparmor_load(int aa_enabled, char *aa_profile,
> - int umount_proc, int dropprivs) {
> - return 0;
> -}
> -static inline int attach_apparmor(char *profile) {
> - return 0;
> -}
> -static inline int apparmor_load(struct lxc_handler *handler) {
> - return 0;
> -}
> -static inline int lsm_mount_proc_if_needed(char *root_src, char *rootfs_tgt) {
> - return 0;
> -}
> -#endif
> diff --git a/src/lxc/attach.c b/src/lxc/attach.c
> index cc95079..37cefb0 100644
> --- a/src/lxc/attach.c
> +++ b/src/lxc/attach.c
> @@ -46,11 +46,11 @@
> #include "attach.h"
> #include "caps.h"
> #include "config.h"
> -#include "apparmor.h"
> #include "utils.h"
> #include "commands.h"
> #include "cgroup.h"
> #include "lxclock.h"
> +#include "lsm/lsm.h"
>
> #if HAVE_SYS_PERSONALITY_H
> #include <sys/personality.h>
> @@ -129,7 +129,7 @@ struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
> errno = ENOENT;
> goto out_error;
> }
> - info->aa_profile = aa_get_profile(pid);
> + info->lsm_label = lsm_process_label_get(pid);
>
> return info;
>
> @@ -138,6 +138,13 @@ out_error:
> return NULL;
> }
>
> +static void lxc_proc_put_context_info(struct lxc_proc_context_info *ctx)
> +{
> + if (ctx->lsm_label)
> + free(ctx->lsm_label);
> + free(ctx);
> +}
> +
> int lxc_attach_to_ns(pid_t pid, int which)
> {
> char path[MAXPATHLEN];
> @@ -644,8 +651,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
> ERROR("failed to automatically determine the "
> "namespaces which the container unshared");
> free(cwd);
> - free(init_ctx->aa_profile);
> - free(init_ctx);
> + lxc_proc_put_context_info(init_ctx);
> return -1;
> }
> }
> @@ -683,8 +689,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
> if (ret < 0) {
> SYSERROR("could not set up required IPC mechanism for attaching");
> free(cwd);
> - free(init_ctx->aa_profile);
> - free(init_ctx);
> + lxc_proc_put_context_info(init_ctx);
> return -1;
> }
>
> @@ -705,8 +710,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
> if (pid < 0) {
> SYSERROR("failed to create first subprocess");
> free(cwd);
> - free(init_ctx->aa_profile);
> - free(init_ctx);
> + lxc_proc_put_context_info(init_ctx);
> return -1;
> }
>
> @@ -794,8 +798,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
> process_lock();
> close(ipc_sockets[0]);
> process_unlock();
> - free(init_ctx->aa_profile);
> - free(init_ctx);
> + lxc_proc_put_context_info(init_ctx);
>
> /* we're done, the child process should now execute whatever
> * it is that the user requested. The parent can now track it
> @@ -815,8 +818,7 @@ int lxc_attach(const char* name, const char* lxcpath, lxc_attach_exec_t exec_fun
> process_unlock();
> if (to_cleanup_pid)
> (void) wait_for_pid(to_cleanup_pid);
> - free(init_ctx->aa_profile);
> - free(init_ctx);
> + lxc_proc_put_context_info(init_ctx);
> return -1;
> }
>
> @@ -918,7 +920,7 @@ int attach_child_main(void* data)
>
> /* load apparmor profile */
> if ((options->namespaces & CLONE_NEWNS) && (options->attach_flags & LXC_ATTACH_APPARMOR)) {
> - ret = attach_apparmor(init_ctx->aa_profile);
> + ret = lsm_process_label_set(init_ctx->lsm_label, 0);
> if (ret < 0) {
> shutdown(ipc_socket, SHUT_RDWR);
> rexit(-1);
> @@ -1021,8 +1023,7 @@ int attach_child_main(void* data)
>
> shutdown(ipc_socket, SHUT_RDWR);
> close(ipc_socket);
> - free(init_ctx->aa_profile);
> - free(init_ctx);
> + lxc_proc_put_context_info(init_ctx);
>
> /* The following is done after the communication socket is
> * shut down. That way, all errors that might (though
> diff --git a/src/lxc/attach.h b/src/lxc/attach.h
> index 518d086..b5f3ea1 100644
> --- a/src/lxc/attach.h
> +++ b/src/lxc/attach.h
> @@ -28,7 +28,7 @@
> #include "attach_options.h"
>
> struct lxc_proc_context_info {
> - char *aa_profile;
> + char *lsm_label;
> unsigned long personality;
> unsigned long long capability_mask;
> };
> diff --git a/src/lxc/conf.c b/src/lxc/conf.c
> index e933c9a..18a92c9 100644
> --- a/src/lxc/conf.c
> +++ b/src/lxc/conf.c
> @@ -74,10 +74,7 @@
> #include "bdev.h"
> #include "cgroup.h"
> #include "lxclock.h"
> -
> -#if HAVE_APPARMOR
> -#include <apparmor.h>
> -#endif
> +#include "lsm/lsm.h"
>
> #if HAVE_SYS_CAPABILITY_H
> #include <sys/capability.h>
> @@ -2398,12 +2395,9 @@ struct lxc_conf *lxc_conf_init(void)
> lxc_list_init(&new->id_map);
> for (i=0; i<NUM_LXC_HOOKS; i++)
> lxc_list_init(&new->hooks[i]);
> -#if HAVE_APPARMOR
> - new->aa_profile = NULL;
> -#endif
> -#if HAVE_APPARMOR /* || HAVE_SMACK || HAVE_SELINUX */
> + new->lsm_aa_profile = NULL;
> + new->lsm_se_context = NULL;
> new->lsm_umount_proc = 0;
> -#endif
>
> return new;
> }
> @@ -3043,10 +3037,6 @@ int uid_shift_ttys(int pid, struct lxc_conf *conf)
>
> int lxc_setup(const char *name, struct lxc_conf *lxc_conf, const char *lxcpath, struct cgroup_process_info *cgroup_info)
> {
> -#if HAVE_APPARMOR /* || HAVE_SMACK || HAVE_SELINUX */
> - int mounted;
> -#endif
> -
> if (setup_utsname(lxc_conf->utsname)) {
> ERROR("failed to setup the utsname for '%s'", name);
> return -1;
> @@ -3140,24 +3130,11 @@ int lxc_setup(const char *name, struct lxc_conf *lxc_conf, const char *lxcpath,
> return -1;
> }
>
> -#if HAVE_APPARMOR /* || HAVE_SMACK || HAVE_SELINUX */
> - INFO("rootfs path is .%s., mount is .%s.", lxc_conf->rootfs.path,
> - lxc_conf->rootfs.mount);
> - if (lxc_conf->rootfs.path == NULL || strlen(lxc_conf->rootfs.path) == 0) {
> - if (mount("proc", "/proc", "proc", 0, NULL)) {
> - SYSERROR("Failed mounting /proc, proceeding");
> - mounted = 0;
> - } else
> - mounted = 1;
> - } else
> - mounted = lsm_mount_proc_if_needed(lxc_conf->rootfs.path, lxc_conf->rootfs.mount);
> - if (mounted == -1) {
> - SYSERROR("failed to mount /proc in the container.");
> + /* mount /proc if needed for LSM transition */
> + if (lsm_proc_mount(lxc_conf) < 0) {
> + ERROR("failed to LSM mount proc for '%s'", name);
> return -1;
> - } else if (mounted == 1) {
> - lxc_conf->lsm_umount_proc = 1;
> }
> -#endif
>
> if (setup_pivot_root(&lxc_conf->rootfs)) {
> ERROR("failed to set rootfs for '%s'", name);
> @@ -3488,10 +3465,10 @@ void lxc_conf_free(struct lxc_conf *conf)
> if (conf->rcfile)
> free(conf->rcfile);
> lxc_clear_config_network(conf);
> -#if HAVE_APPARMOR
> - if (conf->aa_profile)
> - free(conf->aa_profile);
> -#endif
> + if (conf->lsm_aa_profile)
> + free(conf->lsm_aa_profile);
> + if (conf->lsm_se_context)
> + free(conf->lsm_se_context);
> lxc_seccomp_free(conf);
> lxc_clear_config_caps(conf);
> lxc_clear_config_keepcaps(conf);
> diff --git a/src/lxc/conf.h b/src/lxc/conf.h
> index d99bdfe..8c2dc4e 100644
> --- a/src/lxc/conf.h
> +++ b/src/lxc/conf.h
> @@ -247,9 +247,8 @@ enum {
> * @tty_info : tty data
> * @console : console data
> * @ttydir : directory (under /dev) in which to create console and ttys
> -#if HAVE_APPARMOR
> - * @aa_profile : apparmor profile to switch to
> -#endif
> + * @lsm_aa_profile : apparmor profile to switch to or NULL
> + * @lsm_se_context : selinux type to switch to or NULL
> */
> enum lxchooks {
> LXCHOOK_PRESTART, LXCHOOK_PREMOUNT, LXCHOOK_MOUNT, LXCHOOK_AUTODEV,
> @@ -285,13 +284,10 @@ struct lxc_conf {
> char *ttydir;
> int close_all_fds;
> struct lxc_list hooks[NUM_LXC_HOOKS];
> -#if HAVE_APPARMOR
> - char *aa_profile;
> -#endif
>
> -#if HAVE_APPARMOR /* || HAVE_SELINUX || HAVE_SMACK */
> + char *lsm_aa_profile;
> + char *lsm_se_context;
> int lsm_umount_proc;
> -#endif
> char *seccomp; // filename with the seccomp rules
> #if HAVE_SCMP_FILTER_CTX
> scmp_filter_ctx *seccomp_ctx;
> diff --git a/src/lxc/confile.c b/src/lxc/confile.c
> index b378c3a..a623d88 100644
> --- a/src/lxc/confile.c
> +++ b/src/lxc/confile.c
> @@ -57,9 +57,8 @@ static int config_pts(const char *, const char *, struct lxc_conf *);
> static int config_tty(const char *, const char *, struct lxc_conf *);
> static int config_ttydir(const char *, const char *, struct lxc_conf *);
> static int config_kmsg(const char *, const char *, struct lxc_conf *);
> -#if HAVE_APPARMOR
> -static int config_aa_profile(const char *, const char *, struct lxc_conf *);
> -#endif
> +static int config_lsm_aa_profile(const char *, const char *, struct lxc_conf *);
> +static int config_lsm_se_context(const char *, const char *, struct lxc_conf *);
> static int config_cgroup(const char *, const char *, struct lxc_conf *);
> static int config_idmap(const char *, const char *, struct lxc_conf *);
> static int config_loglevel(const char *, const char *, struct lxc_conf *);
> @@ -100,9 +99,8 @@ static struct lxc_config_t config[] = {
> { "lxc.tty", config_tty },
> { "lxc.devttydir", config_ttydir },
> { "lxc.kmsg", config_kmsg },
> -#if HAVE_APPARMOR
> - { "lxc.aa_profile", config_aa_profile },
> -#endif
> + { "lxc.aa_profile", config_lsm_aa_profile },
> + { "lxc.se_context", config_lsm_se_context },
> { "lxc.cgroup", config_cgroup },
> { "lxc.id_map", config_idmap },
> { "lxc.loglevel", config_loglevel },
> @@ -967,9 +965,8 @@ static int config_kmsg(const char *key, const char *value,
> return 0;
> }
>
> -#if HAVE_APPARMOR
> -static int config_aa_profile(const char *key, const char *value,
> - struct lxc_conf *lxc_conf)
> +static int config_lsm_aa_profile(const char *key, const char *value,
> + struct lxc_conf *lxc_conf)
> {
> char *path;
>
> @@ -981,13 +978,32 @@ static int config_aa_profile(const char *key, const char *value,
> return -1;
> }
>
> - if (lxc_conf->aa_profile)
> - free(lxc_conf->aa_profile);
> - lxc_conf->aa_profile = path;
> + if (lxc_conf->lsm_aa_profile)
> + free(lxc_conf->lsm_aa_profile);
> + lxc_conf->lsm_aa_profile = path;
> +
> + return 0;
> +}
> +
> +static int config_lsm_se_context(const char *key, const char *value,
> + struct lxc_conf *lxc_conf)
> +{
> + char *path;
> +
> + if (!value || strlen(value) == 0)
> + return 0;
> + path = strdup(value);
> + if (!path) {
> + SYSERROR("failed to strdup '%s': %m", value);
> + return -1;
> + }
> +
> + if (lxc_conf->lsm_se_context)
> + free(lxc_conf->lsm_se_context);
> + lxc_conf->lsm_se_context = path;
>
> return 0;
> }
> -#endif
>
> static int config_logfile(const char *key, const char *value,
> struct lxc_conf *lxc_conf)
> @@ -1913,10 +1929,10 @@ int lxc_get_config_item(struct lxc_conf *c, const char *key, char *retv,
> v = c->ttydir;
> else if (strcmp(key, "lxc.arch") == 0)
> return lxc_get_arch_entry(c, retv, inlen);
> -#if HAVE_APPARMOR
> else if (strcmp(key, "lxc.aa_profile") == 0)
> - v = c->aa_profile;
> -#endif
> + v = c->lsm_aa_profile;
> + else if (strcmp(key, "lxc.se_context") == 0)
> + v = c->lsm_se_context;
> else if (strcmp(key, "lxc.logfile") == 0)
> v = lxc_log_get_file();
> else if (strcmp(key, "lxc.loglevel") == 0)
> @@ -2000,10 +2016,10 @@ void write_config(FILE *fout, struct lxc_conf *c)
> default: break;
> }
> #endif
> -#if HAVE_APPARMOR
> - if (c->aa_profile)
> - fprintf(fout, "lxc.aa_profile = %s\n", c->aa_profile);
> -#endif
> + if (c->lsm_aa_profile)
> + fprintf(fout, "lxc.aa_profile = %s\n", c->lsm_aa_profile);
> + if (c->lsm_se_context)
> + fprintf(fout, "lxc.se_context = %s\n", c->lsm_se_context);
> if (c->loglevel != LXC_LOG_PRIORITY_NOTSET)
> fprintf(fout, "lxc.loglevel = %s\n", lxc_log_priority_to_string(c->loglevel));
> if (c->logfile)
> diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c
> new file mode 100644
> index 0000000..c13613a
> --- /dev/null
> +++ b/src/lxc/lsm/apparmor.c
> @@ -0,0 +1,179 @@
> +/* apparmor
> + *
> + * Copyright © 2012 Serge Hallyn <serge.hallyn at ubuntu.com>.
> + * Copyright © 2012 Canonical Ltd.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> +
> + * This library 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
> + * Lesser General Public License for more details.
> +
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <sys/mount.h>
> +#include <sys/apparmor.h>
> +#include "log.h"
> +#include "lxclock.h"
> +#include "lsm/lsm.h"
> +
> +lxc_log_define(lxc_apparmor, lxc);
> +
> +#define AA_DEF_PROFILE "lxc-container-default"
> +#define AA_MOUNT_RESTR "/sys/kernel/security/apparmor/features/mount/mask"
> +#define AA_ENABLED_FILE "/sys/module/apparmor/parameters/enabled"
> +
> +/* aa_getcon is not working right now. Use our hand-rolled version below */
> +static int apparmor_enabled(void)
> +{
> + struct stat statbuf;
> + FILE *fin;
> + char e;
> + int ret;
> +
> + ret = stat(AA_MOUNT_RESTR, &statbuf);
> + if (ret != 0)
> + return 0;
> + process_lock();
> + fin = fopen(AA_ENABLED_FILE, "r");
> + process_unlock();
> + if (!fin)
> + return 0;
> + ret = fscanf(fin, "%c", &e);
> + process_lock();
> + fclose(fin);
> + process_unlock();
> + if (ret == 1 && e == 'Y')
> + return 1;
> + return 0;
> +}
> +
> +static char *apparmor_process_label_get(pid_t pid)
> +{
> + char path[100], *space;
> + int ret;
> + char *buf = NULL;
> + int sz = 0;
> + FILE *f;
> +
> + ret = snprintf(path, 100, "/proc/%d/attr/current", pid);
> + if (ret < 0 || ret >= 100) {
> + ERROR("path name too long");
> + return NULL;
> + }
> +again:
> + process_lock();
> + f = fopen(path, "r");
> + process_unlock();
> + if (!f) {
> + SYSERROR("opening %s\n", path);
> + if (buf)
> + free(buf);
> + return NULL;
> + }
> + sz += 1024;
> + buf = realloc(buf, sz);
> + if (!buf) {
> + ERROR("out of memory");
> + process_lock();
> + fclose(f);
> + process_unlock();
> + return NULL;
> + }
> + memset(buf, 0, sz);
> + ret = fread(buf, 1, sz - 1, f);
> + process_lock();
> + fclose(f);
> + process_unlock();
> + if (ret < 0) {
> + ERROR("reading %s\n", path);
> + free(buf);
> + return NULL;
> + }
> + if (ret >= sz)
> + goto again;
> + space = index(buf, '\n');
> + if (space)
> + *space = '\0';
> + space = index(buf, ' ');
> + if (space)
> + *space = '\0';
> + return buf;
> +}
> +
> +static int apparmor_am_unconfined(void)
> +{
> + char *p = apparmor_process_label_get(getpid());
> + int ret = 0;
> + if (!p || strcmp(p, "unconfined") == 0)
> + ret = 1;
> + if (p)
> + free(p);
> + return ret;
> +}
> +
> +/*
> + * apparmor_process_label_set: Set AppArmor process profile
> + *
> + * @label : the profile to set
> + * @default : use the default profile if label is NULL
> + *
> + * Returns 0 on success, < 0 on failure
> + *
> + * Notes: This relies on /proc being available. The new context
> + * will take effect immediately.
> + */
> +static int apparmor_process_label_set(const char *label, int use_default)
> +{
> + if (!apparmor_enabled())
> + return 0;
> +
> + if (!label) {
> + if (use_default)
> + label = AA_DEF_PROFILE;
> + else
> + return 0;
> + }
> +
> + if (strcmp(label, "unconfined") == 0 && apparmor_am_unconfined()) {
> + INFO("apparmor profile unchanged");
> + return 0;
> + }
> +
> + /* XXX: instant instead of aa_change_onexec(), may be used by attach
> + * when using a function that doesn't exec
> + */
> + if (aa_change_profile(label) < 0) {
> + SYSERROR("failed to change apparmor profile to %s", label);
> + return -1;
> + }
> +
> + INFO("changed apparmor profile to %s", label);
> + return 0;
> +}
> +
> +static struct lsm_drv apparmor_drv = {
> + .name = "AppArmor",
> + .process_label_get = apparmor_process_label_get,
> + .process_label_set = apparmor_process_label_set,
> +};
> +
> +struct lsm_drv *lsm_apparmor_drv_init(void)
> +{
> + if (!apparmor_enabled())
> + return NULL;
> + return &apparmor_drv;
> +}
> diff --git a/src/lxc/lsm/lsm.c b/src/lxc/lsm/lsm.c
> new file mode 100644
> index 0000000..3974f11
> --- /dev/null
> +++ b/src/lxc/lsm/lsm.c
> @@ -0,0 +1,156 @@
> +/*
> + * lxc: linux Container library
> + *
> + * Authors:
> + * Copyright © 2012 Serge Hallyn <serge.hallyn at ubuntu.com>
> + * Copyright © 2012 Canonical Ltd.
> + * Dwight Engen <dwight.engen at oracle.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#if HAVE_APPARMOR || HAVE_SELINUX
> +
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <unistd.h>
> +#include <sys/mount.h>
> +#include <sys/param.h>
> +
> +#include "conf.h"
> +#include "log.h"
> +#include "lsm/lsm.h"
> +
> +lxc_log_define(lxc_lsm, lxc);
> +
> +static struct lsm_drv *drv = NULL;
> +
> +extern struct lsm_drv *lsm_apparmor_drv_init(void);
> +extern struct lsm_drv *lsm_selinux_drv_init(void);
> +extern struct lsm_drv *lsm_nop_drv_init(void);
> +
> +__attribute__((constructor))
> +void lsm_init(void)
> +{
> + if (drv) {
> + INFO("LSM security driver %s", drv->name);
> + return;
> + }
> +
> + #if HAVE_APPARMOR
> + drv = lsm_apparmor_drv_init();
> + #endif
> + #if HAVE_SELINUX
> + if (!drv)
> + drv = lsm_selinux_drv_init();
> + #endif
> +
> + if (!drv)
> + drv = lsm_nop_drv_init();
> + INFO("Initialized LSM security driver %s", drv->name);
> +}
> +
> +char *lsm_process_label_get(pid_t pid)
> +{
> + if (!drv) {
> + ERROR("LSM driver not inited");
> + return NULL;
> + }
> + return drv->process_label_get(pid);
> +}
> +
> +int lsm_process_label_set(const char *label, int use_default)
> +{
> + if (!drv) {
> + ERROR("LSM driver not inited");
> + return -1;
> + }
> + return drv->process_label_set(label, use_default);
> +}
> +
> +/*
> + * _lsm_mount_proc: Mount /proc inside container to enable
> + * security domain transition
> + *
> + * @rootfs : the rootfs where proc should be mounted
> + *
> + * Returns < 0 on failure, 0 if the correct proc was already mounted
> + * and 1 if a new proc was mounted.
> + */
> +static int _lsm_proc_mount(const char *rootfs)
> +{
> + char path[MAXPATHLEN];
> + char link[20];
> + int linklen, ret;
> +
> + ret = snprintf(path, MAXPATHLEN, "%s/proc/self", rootfs);
> + if (ret < 0 || ret >= MAXPATHLEN) {
> + SYSERROR("proc path name too long");
> + return -1;
> + }
> + memset(link, 0, 20);
> + linklen = readlink(path, link, 20);
> + INFO("I am %d, /proc/self points to '%s'", getpid(), link);
> + ret = snprintf(path, MAXPATHLEN, "%s/proc", rootfs);
> + if (linklen < 0) /* /proc not mounted */
> + goto domount;
> + /* can't be longer than rootfs/proc/1 */
> + if (strncmp(link, "1", linklen) != 0) {
> + /* wrong /procs mounted */
> + umount2(path, MNT_DETACH); /* ignore failure */
> + goto domount;
> + }
> + /* the right proc is already mounted */
> + return 0;
> +
> +domount:
> + if (mount("proc", path, "proc", 0, NULL))
> + return -1;
> + INFO("Mounted /proc in container for security transition");
> + return 1;
> +}
> +
> +int lsm_proc_mount(struct lxc_conf *lxc_conf)
> +{
> + int mounted;
> +
> + if (!drv || strcmp(drv->name, "nop") == 0)
> + return 0;
> +
> + if (lxc_conf->rootfs.path == NULL || strlen(lxc_conf->rootfs.path) == 0) {
> + if (mount("proc", "/proc", "proc", 0, NULL)) {
> + SYSERROR("Failed mounting /proc, proceeding");
> + mounted = 0;
> + } else
> + mounted = 1;
> + } else
> + mounted = _lsm_proc_mount(lxc_conf->rootfs.mount);
> + if (mounted == -1) {
> + SYSERROR("failed to mount /proc in the container.");
> + return -1;
> + } else if (mounted == 1) {
> + lxc_conf->lsm_umount_proc = 1;
> + }
> + return 0;
> +}
> +
> +void lsm_proc_unmount(struct lxc_conf *lxc_conf)
> +{
> + if (lxc_conf->lsm_umount_proc == 1) {
> + umount("/proc");
> + lxc_conf->lsm_umount_proc = 0;
> + }
> +}
> +#endif
> diff --git a/src/lxc/lsm/lsm.h b/src/lxc/lsm/lsm.h
> new file mode 100644
> index 0000000..2a82c66
> --- /dev/null
> +++ b/src/lxc/lsm/lsm.h
> @@ -0,0 +1,52 @@
> +/*
> + * lxc: linux Container library
> + *
> + * Copyright © 2013 Oracle.
> + *
> + * Authors:
> + * Dwight Engen <dwight.engen at oracle.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#ifndef __lxc_lsm_h
> +#define __lxc_lsm_h
> +
> +struct lxc_conf;
> +
> +#include <sys/types.h>
> +
> +struct lsm_drv {
> + const char *name;
> +
> + char *(*process_label_get)(pid_t pid);
> + int (*process_label_set)(const char *label, int use_default);
> +};
> +
> +#if HAVE_APPARMOR || HAVE_SELINUX
> +void lsm_init(void);
> +char *lsm_process_label_get(pid_t pid);
> +int lsm_process_label_set(const char *label, int use_default);
> +int lsm_proc_mount(struct lxc_conf *lxc_conf);
> +void lsm_proc_unmount(struct lxc_conf *lxc_conf);
> +#else
> +static inline void lsm_init(void) { }
> +static inline char *lsm_process_label_get(pid_t pid) { return NULL; }
> +static inline int lsm_process_label_set(char *label, int use_default) { return 0; }
> +static inline int lsm_proc_mount(struct lxc_conf *lxc_conf) { return 0; }
> +static inline void lsm_proc_unmount(struct lxc_conf *lxc_conf) { }
> +#endif
> +
> +#endif
> diff --git a/src/lxc/lsm/nop.c b/src/lxc/lsm/nop.c
> new file mode 100644
> index 0000000..9184e6b
> --- /dev/null
> +++ b/src/lxc/lsm/nop.c
> @@ -0,0 +1,46 @@
> +/*
> + * lxc: linux Container library
> + *
> + * Copyright © 2013 Oracle.
> + *
> + * Authors:
> + * Dwight Engen <dwight.engen at oracle.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library 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
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include <stdlib.h>
> +#include "lsm/lsm.h"
> +
> +static char *nop_process_label_get(pid_t pid)
> +{
> + return NULL;
> +}
> +
> +static int nop_process_label_set(const char *label, int use_default)
> +{
> + return 0;
> +}
> +
> +static struct lsm_drv nop_drv = {
> + .name = "nop",
> + .process_label_get = nop_process_label_get,
> + .process_label_set = nop_process_label_set,
> +};
> +
> +struct lsm_drv *lsm_nop_drv_init(void)
> +{
> + return &nop_drv;
> +}
> diff --git a/src/lxc/lsm/selinux.c b/src/lxc/lsm/selinux.c
> new file mode 100644
> index 0000000..6e44e8b
> --- /dev/null
> +++ b/src/lxc/lsm/selinux.c
> @@ -0,0 +1,101 @@
> +/*
> + * lxc: linux Container library
> + *
> + * Copyright © 2013 Oracle.
> + *
> + * Authors:
> + * Dwight Engen <dwight.engen at oracle.com>
> + *
> + * This library is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2, as
> + * published by the Free Software Foundation.
> + *
> + * This program 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 this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <errno.h>
> +#include <stdlib.h>
> +#include <sys/types.h>
> +#include <unistd.h>
> +#include <selinux/selinux.h>
> +#include "log.h"
> +#include "lsm/lsm.h"
> +
> +#define DEFAULT_LABEL "unconfined_t"
> +
> +lxc_log_define(lxc_lsm_selinux, lxc);
> +
> +/*
> + * selinux_process_label_get: Get SELinux context of a process
> + *
> + * @pid : the pid to get, or 0 for self
> + *
> + * Returns the context of the given pid. The caller must free()
> + * the returned string.
> + *
> + * Note that this relies on /proc being available.
> + */
> +static char *selinux_process_label_get(pid_t pid)
> +{
> + security_context_t ctx;
> + char *label;
> +
> + if (getpidcon_raw(pid, &ctx) < 0) {
> + SYSERROR("failed to get SELinux context for pid %d", pid);
> + return NULL;
> + }
> + label = strdup((char *)ctx);
> + freecon(ctx);
> + return label;
> +}
> +
> +/*
> + * selinux_process_label_set: Set SELinux context of a process
> + *
> + * @label : the context to set
> + * @default : use the default context if label is NULL
> + *
> + * Returns 0 on success, < 0 on failure
> + *
> + * Notes: This relies on /proc being available. The new context
> + * will take effect on the next exec(2).
> + */
> +static int selinux_process_label_set(const char *label, int use_default)
> +{
> + if (!label) {
> + if (use_default)
> + label = DEFAULT_LABEL;
> + else
> + return -1;
> + }
> + if (!strcmp(label, "unconfined_t"))
> + return 0;
> +
> + if (setexeccon_raw((char *)label) < 0) {
> + SYSERROR("failed to set new SELinux context %s", label);
> + return -1;
> + }
> +
> + INFO("changed SELinux context to %s", label);
> + return 0;
> +}
> +
> +static struct lsm_drv selinux_drv = {
> + .name = "SELinux",
> + .process_label_get = selinux_process_label_get,
> + .process_label_set = selinux_process_label_set,
> +};
> +
> +struct lsm_drv *lsm_selinux_drv_init(void)
> +{
> + if (!is_selinux_enabled())
> + return NULL;
> + return &selinux_drv;
> +}
> diff --git a/src/lxc/start.c b/src/lxc/start.c
> index c968bb1..7538403 100644
> --- a/src/lxc/start.c
> +++ b/src/lxc/start.c
> @@ -68,10 +68,10 @@
> #include "console.h"
> #include "sync.h"
> #include "namespace.h"
> -#include "apparmor.h"
> #include "lxcseccomp.h"
> #include "caps.h"
> #include "lxclock.h"
> +#include "lsm/lsm.h"
>
> lxc_log_define(lxc_start, lxc);
>
> @@ -285,7 +285,8 @@ struct lxc_handler *lxc_init(const char *name, struct lxc_conf *conf, const char
> handler->lxcpath = lxcpath;
> handler->pinfd = -1;
>
> - apparmor_handler_init(handler);
> + lsm_init();
> +
> handler->name = strdup(name);
> if (!handler->name) {
> ERROR("failed to allocate memory");
> @@ -555,8 +556,16 @@ static int do_start(void *data)
> if (lxc_sync_barrier_parent(handler, LXC_SYNC_CGROUP))
> return -1;
>
> - if (apparmor_load(handler) < 0)
> + /* XXX: hmm apparmor switches right away since it uses
> + * aa_change_profile() and not aa_change_onexec(). SELinux on the other
> + * hand is going to transition on exec(). Is it bad to run the stuff
> + * between here and exec() in the more privileged context?
> + */
> + if (lsm_process_label_set(handler->conf->lsm_aa_profile ?
> + handler->conf->lsm_aa_profile :
> + handler->conf->lsm_se_context, 1) < 0)
> goto out_warn_father;
> + lsm_proc_unmount(handler->conf);
>
> if (lxc_seccomp_load(handler->conf) != 0)
> goto out_warn_father;
> diff --git a/src/lxc/start.h b/src/lxc/start.h
> index 9bf6024..c35c5c4 100644
> --- a/src/lxc/start.h
> +++ b/src/lxc/start.h
> @@ -50,9 +50,6 @@ struct lxc_handler {
> struct lxc_operations *ops;
> void *data;
> int sv[2];
> -#if HAVE_APPARMOR
> - int aa_enabled;
> -#endif
> int pinfd;
> const char *lxcpath;
> struct cgroup_process_info *cgroup;
> diff --git a/templates/lxc-oracle.in b/templates/lxc-oracle.in
> index 98ea609..c0fcd30 100644
> --- a/templates/lxc-oracle.in
> +++ b/templates/lxc-oracle.in
> @@ -110,10 +110,8 @@ EOF
> # this file has to exist for libvirt/Virtual machine monitor to boot the container
> touch $container_rootfs/etc/mtab
>
> - # don't put devpts in here, it will already be mounted for us by lxc/libvirt
> + # don't put devpts,proc, nor sysfs in here, it will already be mounted for us by lxc/libvirt
> cat <<EOF > $container_rootfs/etc/fstab
> -proc /proc proc nodev,noexec,nosuid 0 0
> -sysfs /sys sysfs defaults 0 0
> EOF
>
> # remove module stuff for iptables it just shows errors that are not
> @@ -404,9 +402,8 @@ lxc.cgroup.devices.allow = c 5:2 rwm # /dev/ptmx pty master
> EOF
>
> cat <<EOF > $cfg_dir/fstab || die "unable to create $cfg_dir/fstab"
> -proc $container_rootfs/proc proc nodev,noexec,nosuid 0 0
> -devpts $container_rootfs/dev/pts devpts defaults 0 0
> -sysfs $container_rootfs/sys sysfs defaults 0 0
> +proc proc proc nodev,noexec,nosuid 0 0
> +sysfs sys sysfs defaults 0 0
> EOF
> }
>
> --
> 1.8.1.4
>
>
> ------------------------------------------------------------------------------
> October Webinars: Code for Performance
> Free Intel webinars can help you accelerate application performance.
> Explore tips for MPI, OpenMP, advanced profiling, and more. Get the most from
> the latest Intel processors and coprocessors. See abstracts and register >
> http://pubads.g.doubleclick.net/gampad/clk?id=60133471&iu=/4140/ostg.clktrk
> _______________________________________________
> Lxc-devel mailing list
> Lxc-devel at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/lxc-devel
More information about the lxc-devel
mailing list