mirror of
git://github.com/lxc/lxc
synced 2025-08-31 14:54:09 +00:00
Merge pull request #2479 from Blub/apparmor-profiles
RFC: Generated Apparmor profiles, namespaces, stacking
This commit is contained in:
@@ -85,7 +85,6 @@
|
|||||||
mount options=(rw, nosuid, nodev, noexec, remount) -> /sys/,
|
mount options=(rw, nosuid, nodev, noexec, remount) -> /sys/,
|
||||||
deny /sys/firmware/efi/efivars/** rwklx,
|
deny /sys/firmware/efi/efivars/** rwklx,
|
||||||
deny /sys/kernel/security/** rwklx,
|
deny /sys/kernel/security/** rwklx,
|
||||||
mount options=(move) /sys/fs/cgroup/cgmanager/ -> /sys/fs/cgroup/cgmanager.lower/,
|
|
||||||
mount options=(ro, nosuid, nodev, noexec, remount, strictatime) -> /sys/fs/cgroup/,
|
mount options=(ro, nosuid, nodev, noexec, remount, strictatime) -> /sys/fs/cgroup/,
|
||||||
|
|
||||||
# deny reads from debugfs
|
# deny reads from debugfs
|
||||||
|
@@ -40,5 +40,6 @@
|
|||||||
pivot_root /usr/lib*/*/lxc/**,
|
pivot_root /usr/lib*/*/lxc/**,
|
||||||
|
|
||||||
change_profile -> lxc-*,
|
change_profile -> lxc-*,
|
||||||
|
change_profile -> lxc-**,
|
||||||
change_profile -> unconfined,
|
change_profile -> unconfined,
|
||||||
change_profile -> :lxc-*:unconfined,
|
change_profile -> :lxc-*:unconfined,
|
||||||
|
@@ -9,4 +9,5 @@ profile lxc-container-default-cgns flags=(attach_disconnected,mediate_deleted) {
|
|||||||
# the newinstance option (but, right now, we don't).
|
# the newinstance option (but, right now, we don't).
|
||||||
deny mount fstype=devpts,
|
deny mount fstype=devpts,
|
||||||
mount fstype=cgroup -> /sys/fs/cgroup/**,
|
mount fstype=cgroup -> /sys/fs/cgroup/**,
|
||||||
|
mount fstype=cgroup2 -> /sys/fs/cgroup/**,
|
||||||
}
|
}
|
||||||
|
@@ -11,4 +11,5 @@ profile lxc-container-default-with-nesting flags=(attach_disconnected,mediate_de
|
|||||||
mount fstype=sysfs -> /var/cache/lxc/**,
|
mount fstype=sysfs -> /var/cache/lxc/**,
|
||||||
mount options=(rw,bind),
|
mount options=(rw,bind),
|
||||||
mount fstype=cgroup -> /sys/fs/cgroup/**,
|
mount fstype=cgroup -> /sys/fs/cgroup/**,
|
||||||
|
mount fstype=cgroup2 -> /sys/fs/cgroup/**,
|
||||||
}
|
}
|
||||||
|
@@ -469,6 +469,13 @@ AC_ARG_WITH([cgroup-pattern],
|
|||||||
[pattern for container cgroups]
|
[pattern for container cgroups]
|
||||||
)], [], [with_cgroup_pattern=['lxc/%n']])
|
)], [], [with_cgroup_pattern=['lxc/%n']])
|
||||||
|
|
||||||
|
# The path for the apparmor_parser's cache for generated apparmor profiles
|
||||||
|
AC_ARG_WITH([apparmor-cache-dir],
|
||||||
|
[AC_HELP_STRING(
|
||||||
|
[--with-apparmor-cache-dir=dir],
|
||||||
|
[path for apparmor_parser cache]
|
||||||
|
)], [], [with_apparmor_cache_dir=['${localstatedir}/cache/lxc/apparmor']])
|
||||||
|
|
||||||
# Container log path. By default, use $lxcpath.
|
# Container log path. By default, use $lxcpath.
|
||||||
AC_MSG_CHECKING([Whether to place logfiles in container config path])
|
AC_MSG_CHECKING([Whether to place logfiles in container config path])
|
||||||
AC_ARG_ENABLE([configpath-log],
|
AC_ARG_ENABLE([configpath-log],
|
||||||
@@ -515,6 +522,7 @@ AS_AC_EXPAND(LXCBINHOOKDIR, "$libexecdir/lxc/hooks")
|
|||||||
AS_AC_EXPAND(LXCINITDIR, "$libexecdir")
|
AS_AC_EXPAND(LXCINITDIR, "$libexecdir")
|
||||||
AS_AC_EXPAND(LOGPATH, "$with_log_path")
|
AS_AC_EXPAND(LOGPATH, "$with_log_path")
|
||||||
AS_AC_EXPAND(RUNTIME_PATH, "$with_runtime_path")
|
AS_AC_EXPAND(RUNTIME_PATH, "$with_runtime_path")
|
||||||
|
AS_AC_EXPAND(APPARMOR_CACHE_DIR, "$with_apparmor_cache_dir")
|
||||||
AC_SUBST(DEFAULT_CGROUP_PATTERN, ["$with_cgroup_pattern"])
|
AC_SUBST(DEFAULT_CGROUP_PATTERN, ["$with_cgroup_pattern"])
|
||||||
|
|
||||||
# We need the install path so criu knows where to reference the hook scripts.
|
# We need the install path so criu knows where to reference the hook scripts.
|
||||||
|
@@ -174,6 +174,7 @@ AM_CFLAGS = -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
|
|||||||
-DDEFAULT_CGROUP_PATTERN=\"$(DEFAULT_CGROUP_PATTERN)\" \
|
-DDEFAULT_CGROUP_PATTERN=\"$(DEFAULT_CGROUP_PATTERN)\" \
|
||||||
-DRUNTIME_PATH=\"$(RUNTIME_PATH)\" \
|
-DRUNTIME_PATH=\"$(RUNTIME_PATH)\" \
|
||||||
-DSBINDIR=\"$(SBINDIR)\" \
|
-DSBINDIR=\"$(SBINDIR)\" \
|
||||||
|
-DAPPARMOR_CACHE_DIR=\"$(APPARMOR_CACHE_DIR)\" \
|
||||||
-I $(top_srcdir)/src \
|
-I $(top_srcdir)/src \
|
||||||
-I $(top_srcdir)/src/lxc \
|
-I $(top_srcdir)/src/lxc \
|
||||||
-I $(top_srcdir)/src/lxc/storage \
|
-I $(top_srcdir)/src/lxc/storage \
|
||||||
|
@@ -2360,7 +2360,23 @@ static int setup_mount(const struct lxc_conf *conf,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *make_anonymous_mount_file(struct lxc_list *mount)
|
/*
|
||||||
|
* In order for nested containers to be able to mount /proc and /sys they need
|
||||||
|
* to see a "pure" proc and sysfs mount points with nothing mounted on top
|
||||||
|
* (like lxcfs).
|
||||||
|
* For this we provide proc and sysfs in /dev/.lxc/{proc,sys} while using an
|
||||||
|
* apparmor rule to deny access to them. This is mostly for convenience: The
|
||||||
|
* container's root user can mount them anyway and thus has access to the two
|
||||||
|
* file systems. But a non-root user in the container should not be allowed to
|
||||||
|
* access them as a side effect without explicitly allowing it.
|
||||||
|
*/
|
||||||
|
static const char nesting_helpers[] =
|
||||||
|
"proc dev/.lxc/proc proc create=dir,optional\n"
|
||||||
|
"sys dev/.lxc/sys sysfs create=dir,optional\n"
|
||||||
|
;
|
||||||
|
|
||||||
|
FILE *make_anonymous_mount_file(struct lxc_list *mount,
|
||||||
|
bool include_nesting_helpers)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char *mount_entry;
|
char *mount_entry;
|
||||||
@@ -2402,6 +2418,13 @@ FILE *make_anonymous_mount_file(struct lxc_list *mount)
|
|||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (include_nesting_helpers) {
|
||||||
|
ret = lxc_write_nointr(fd, nesting_helpers,
|
||||||
|
sizeof(nesting_helpers) - 1);
|
||||||
|
if (ret != sizeof(nesting_helpers) - 1)
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
ret = lseek(fd, 0, SEEK_SET);
|
ret = lseek(fd, 0, SEEK_SET);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
@@ -2422,7 +2445,7 @@ static int setup_mount_entries(const struct lxc_conf *conf,
|
|||||||
int ret;
|
int ret;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
f = make_anonymous_mount_file(mount);
|
f = make_anonymous_mount_file(mount, conf->lsm_aa_allow_nesting);
|
||||||
if (!f)
|
if (!f)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@@ -2738,6 +2761,7 @@ struct lxc_conf *lxc_conf_init(void)
|
|||||||
lxc_list_init(&new->groups);
|
lxc_list_init(&new->groups);
|
||||||
lxc_list_init(&new->state_clients);
|
lxc_list_init(&new->state_clients);
|
||||||
new->lsm_aa_profile = NULL;
|
new->lsm_aa_profile = NULL;
|
||||||
|
lxc_list_init(&new->lsm_aa_raw);
|
||||||
new->lsm_se_context = NULL;
|
new->lsm_se_context = NULL;
|
||||||
new->tmp_umount_proc = false;
|
new->tmp_umount_proc = false;
|
||||||
new->tmp_umount_proc = 0;
|
new->tmp_umount_proc = 0;
|
||||||
@@ -4025,6 +4049,19 @@ void lxc_clear_includes(struct lxc_conf *conf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lxc_clear_apparmor_raw(struct lxc_conf *c)
|
||||||
|
{
|
||||||
|
struct lxc_list *it, *next;
|
||||||
|
|
||||||
|
lxc_list_for_each_safe (it, &c->lsm_aa_raw, next) {
|
||||||
|
lxc_list_del(it);
|
||||||
|
free(it->elem);
|
||||||
|
free(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void lxc_conf_free(struct lxc_conf *conf)
|
void lxc_conf_free(struct lxc_conf *conf)
|
||||||
{
|
{
|
||||||
if (!conf)
|
if (!conf)
|
||||||
@@ -4052,6 +4089,7 @@ void lxc_conf_free(struct lxc_conf *conf)
|
|||||||
free(conf->syslog);
|
free(conf->syslog);
|
||||||
lxc_free_networks(&conf->network);
|
lxc_free_networks(&conf->network);
|
||||||
free(conf->lsm_aa_profile);
|
free(conf->lsm_aa_profile);
|
||||||
|
free(conf->lsm_aa_profile_computed);
|
||||||
free(conf->lsm_se_context);
|
free(conf->lsm_se_context);
|
||||||
lxc_seccomp_free(conf);
|
lxc_seccomp_free(conf);
|
||||||
lxc_clear_config_caps(conf);
|
lxc_clear_config_caps(conf);
|
||||||
@@ -4068,6 +4106,7 @@ void lxc_conf_free(struct lxc_conf *conf)
|
|||||||
lxc_clear_limits(conf, "lxc.prlimit");
|
lxc_clear_limits(conf, "lxc.prlimit");
|
||||||
lxc_clear_sysctls(conf, "lxc.sysctl");
|
lxc_clear_sysctls(conf, "lxc.sysctl");
|
||||||
lxc_clear_procs(conf, "lxc.proc");
|
lxc_clear_procs(conf, "lxc.proc");
|
||||||
|
lxc_clear_apparmor_raw(conf);
|
||||||
free(conf->cgroup_meta.dir);
|
free(conf->cgroup_meta.dir);
|
||||||
free(conf->cgroup_meta.controllers);
|
free(conf->cgroup_meta.controllers);
|
||||||
free(conf->shmount.path_host);
|
free(conf->shmount.path_host);
|
||||||
|
@@ -275,7 +275,11 @@ struct lxc_conf {
|
|||||||
};
|
};
|
||||||
|
|
||||||
char *lsm_aa_profile;
|
char *lsm_aa_profile;
|
||||||
|
char *lsm_aa_profile_computed;
|
||||||
|
bool lsm_aa_profile_created;
|
||||||
|
unsigned int lsm_aa_allow_nesting;
|
||||||
unsigned int lsm_aa_allow_incomplete;
|
unsigned int lsm_aa_allow_incomplete;
|
||||||
|
struct lxc_list lsm_aa_raw;
|
||||||
char *lsm_se_context;
|
char *lsm_se_context;
|
||||||
bool tmp_umount_proc;
|
bool tmp_umount_proc;
|
||||||
char *seccomp; /* filename with the seccomp rules */
|
char *seccomp; /* filename with the seccomp rules */
|
||||||
@@ -427,7 +431,8 @@ extern int parse_mntopts(const char *mntopts, unsigned long *mntflags,
|
|||||||
extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
|
extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
|
||||||
extern void remount_all_slave(void);
|
extern void remount_all_slave(void);
|
||||||
extern void suggest_default_idmap(void);
|
extern void suggest_default_idmap(void);
|
||||||
extern FILE *make_anonymous_mount_file(struct lxc_list *mount);
|
extern FILE *make_anonymous_mount_file(struct lxc_list *mount,
|
||||||
|
bool include_nesting_helpers);
|
||||||
extern struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings);
|
extern struct lxc_list *sort_cgroup_settings(struct lxc_list *cgroup_settings);
|
||||||
extern unsigned long add_required_remount_flags(const char *s, const char *d,
|
extern unsigned long add_required_remount_flags(const char *s, const char *d,
|
||||||
unsigned long flags);
|
unsigned long flags);
|
||||||
@@ -441,5 +446,6 @@ extern int setup_sysctl_parameters(struct lxc_list *sysctls);
|
|||||||
extern int lxc_clear_sysctls(struct lxc_conf *c, const char *key);
|
extern int lxc_clear_sysctls(struct lxc_conf *c, const char *key);
|
||||||
extern int setup_proc_filesystem(struct lxc_list *procs, pid_t pid);
|
extern int setup_proc_filesystem(struct lxc_list *procs, pid_t pid);
|
||||||
extern int lxc_clear_procs(struct lxc_conf *c, const char *key);
|
extern int lxc_clear_procs(struct lxc_conf *c, const char *key);
|
||||||
|
extern int lxc_clear_apparmor_raw(struct lxc_conf *c);
|
||||||
|
|
||||||
#endif /* __LXC_CONF_H */
|
#endif /* __LXC_CONF_H */
|
||||||
|
@@ -84,7 +84,9 @@ lxc_log_define(confile, lxc);
|
|||||||
|
|
||||||
lxc_config_define(autodev);
|
lxc_config_define(autodev);
|
||||||
lxc_config_define(apparmor_allow_incomplete);
|
lxc_config_define(apparmor_allow_incomplete);
|
||||||
|
lxc_config_define(apparmor_allow_nesting);
|
||||||
lxc_config_define(apparmor_profile);
|
lxc_config_define(apparmor_profile);
|
||||||
|
lxc_config_define(apparmor_raw);
|
||||||
lxc_config_define(cap_drop);
|
lxc_config_define(cap_drop);
|
||||||
lxc_config_define(cap_keep);
|
lxc_config_define(cap_keep);
|
||||||
lxc_config_define(cgroup_controller);
|
lxc_config_define(cgroup_controller);
|
||||||
@@ -158,6 +160,8 @@ static struct lxc_config_t config[] = {
|
|||||||
{ "lxc.arch", set_config_personality, get_config_personality, clr_config_personality, },
|
{ "lxc.arch", set_config_personality, get_config_personality, clr_config_personality, },
|
||||||
{ "lxc.apparmor.profile", set_config_apparmor_profile, get_config_apparmor_profile, clr_config_apparmor_profile, },
|
{ "lxc.apparmor.profile", set_config_apparmor_profile, get_config_apparmor_profile, clr_config_apparmor_profile, },
|
||||||
{ "lxc.apparmor.allow_incomplete", set_config_apparmor_allow_incomplete, get_config_apparmor_allow_incomplete, clr_config_apparmor_allow_incomplete, },
|
{ "lxc.apparmor.allow_incomplete", set_config_apparmor_allow_incomplete, get_config_apparmor_allow_incomplete, clr_config_apparmor_allow_incomplete, },
|
||||||
|
{ "lxc.apparmor.allow_nesting", set_config_apparmor_allow_nesting, get_config_apparmor_allow_nesting, clr_config_apparmor_allow_nesting, },
|
||||||
|
{ "lxc.apparmor.raw", set_config_apparmor_raw, get_config_apparmor_raw, clr_config_apparmor_raw, },
|
||||||
{ "lxc.autodev", set_config_autodev, get_config_autodev, clr_config_autodev, },
|
{ "lxc.autodev", set_config_autodev, get_config_autodev, clr_config_autodev, },
|
||||||
{ "lxc.cap.drop", set_config_cap_drop, get_config_cap_drop, clr_config_cap_drop, },
|
{ "lxc.cap.drop", set_config_cap_drop, get_config_cap_drop, clr_config_cap_drop, },
|
||||||
{ "lxc.cap.keep", set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, },
|
{ "lxc.cap.keep", set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, },
|
||||||
@@ -1132,6 +1136,52 @@ static int set_config_apparmor_allow_incomplete(const char *key,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_config_apparmor_allow_nesting(const char *key,
|
||||||
|
const char *value,
|
||||||
|
struct lxc_conf *lxc_conf,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
if (lxc_config_value_empty(value))
|
||||||
|
return clr_config_apparmor_allow_nesting(key, lxc_conf, NULL);
|
||||||
|
|
||||||
|
if (lxc_safe_uint(value, &lxc_conf->lsm_aa_allow_nesting) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (lxc_conf->lsm_aa_allow_nesting > 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_config_apparmor_raw(const char *key,
|
||||||
|
const char *value,
|
||||||
|
struct lxc_conf *lxc_conf,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
char *elem;
|
||||||
|
struct lxc_list *list;
|
||||||
|
|
||||||
|
if (lxc_config_value_empty(value))
|
||||||
|
return lxc_clear_apparmor_raw(lxc_conf);
|
||||||
|
|
||||||
|
list = malloc(sizeof(*list));
|
||||||
|
if (!list) {
|
||||||
|
errno = ENOMEM;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
elem = strdup(value);
|
||||||
|
if (!elem) {
|
||||||
|
free(list);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
list->elem = elem;
|
||||||
|
|
||||||
|
lxc_list_add_tail(&lxc_conf->lsm_aa_raw, list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int set_config_selinux_context(const char *key, const char *value,
|
static int set_config_selinux_context(const char *key, const char *value,
|
||||||
struct lxc_conf *lxc_conf, void *data)
|
struct lxc_conf *lxc_conf, void *data)
|
||||||
{
|
{
|
||||||
@@ -3004,6 +3054,34 @@ static int get_config_apparmor_allow_incomplete(const char *key, char *retv,
|
|||||||
c->lsm_aa_allow_incomplete);
|
c->lsm_aa_allow_incomplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_config_apparmor_allow_nesting(const char *key, char *retv,
|
||||||
|
int inlen, struct lxc_conf *c,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
return lxc_get_conf_int(c, retv, inlen,
|
||||||
|
c->lsm_aa_allow_nesting);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_config_apparmor_raw(const char *key, char *retv,
|
||||||
|
int inlen, struct lxc_conf *c,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
struct lxc_list *it;
|
||||||
|
int fulllen = 0;
|
||||||
|
|
||||||
|
if (!retv)
|
||||||
|
inlen = 0;
|
||||||
|
else
|
||||||
|
memset(retv, 0, inlen);
|
||||||
|
|
||||||
|
lxc_list_for_each(it, &c->lsm_aa_raw) {
|
||||||
|
strprint(retv, inlen, "%s\n", (char *)it->elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fulllen;
|
||||||
|
}
|
||||||
|
|
||||||
static int get_config_selinux_context(const char *key, char *retv, int inlen,
|
static int get_config_selinux_context(const char *key, char *retv, int inlen,
|
||||||
struct lxc_conf *c, void *data)
|
struct lxc_conf *c, void *data)
|
||||||
{
|
{
|
||||||
@@ -3794,6 +3872,21 @@ static inline int clr_config_apparmor_allow_incomplete(const char *key,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int clr_config_apparmor_allow_nesting(const char *key,
|
||||||
|
struct lxc_conf *c,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
c->lsm_aa_allow_nesting = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int clr_config_apparmor_raw(const char *key,
|
||||||
|
struct lxc_conf *c,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
return lxc_clear_apparmor_raw(c);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int clr_config_selinux_context(const char *key,
|
static inline int clr_config_selinux_context(const char *key,
|
||||||
struct lxc_conf *c, void *data)
|
struct lxc_conf *c, void *data)
|
||||||
{
|
{
|
||||||
@@ -4986,7 +5079,9 @@ int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv,
|
|||||||
|
|
||||||
if (!strcmp(key, "lxc.apparmor")) {
|
if (!strcmp(key, "lxc.apparmor")) {
|
||||||
strprint(retv, inlen, "allow_incomplete\n");
|
strprint(retv, inlen, "allow_incomplete\n");
|
||||||
|
strprint(retv, inlen, "allow_nesting\n");
|
||||||
strprint(retv, inlen, "profile\n");
|
strprint(retv, inlen, "profile\n");
|
||||||
|
strprint(retv, inlen, "raw\n");
|
||||||
} else if (!strcmp(key, "lxc.cgroup")) {
|
} else if (!strcmp(key, "lxc.cgroup")) {
|
||||||
strprint(retv, inlen, "dir\n");
|
strprint(retv, inlen, "dir\n");
|
||||||
} else if (!strcmp(key, "lxc.selinux")) {
|
} else if (!strcmp(key, "lxc.selinux")) {
|
||||||
|
@@ -378,7 +378,8 @@ static void exec_criu(struct cgroup_ops *cgroup_ops, struct criu_opts *opts)
|
|||||||
DECLARE_ARG(opts->user->action_script);
|
DECLARE_ARG(opts->user->action_script);
|
||||||
}
|
}
|
||||||
|
|
||||||
mnts = make_anonymous_mount_file(&opts->c->lxc_conf->mount_list);
|
mnts = make_anonymous_mount_file(&opts->c->lxc_conf->mount_list,
|
||||||
|
opts->c->lxc_conf->lsm_aa_allow_nesting);
|
||||||
if (!mnts)
|
if (!mnts)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -142,18 +142,20 @@ int lsm_process_label_set_at(int label_fd, const char *label, bool on_exec)
|
|||||||
|
|
||||||
if (on_exec) {
|
if (on_exec) {
|
||||||
ERROR("Changing AppArmor profile on exec not supported");
|
ERROR("Changing AppArmor profile on exec not supported");
|
||||||
return -EINVAL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(label) + strlen("changeprofile ") + 1;
|
len = strlen(label) + strlen("changeprofile ") + 1;
|
||||||
command = malloc(len);
|
command = malloc(len);
|
||||||
if (!command)
|
if (!command)
|
||||||
return -1;
|
goto on_error;
|
||||||
|
|
||||||
ret = snprintf(command, len, "changeprofile %s", label);
|
ret = snprintf(command, len, "changeprofile %s", label);
|
||||||
if (ret < 0 || (size_t)ret >= len) {
|
if (ret < 0 || (size_t)ret >= len) {
|
||||||
|
int saved_errno = errno;
|
||||||
free(command);
|
free(command);
|
||||||
return -1;
|
errno = saved_errno;
|
||||||
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = lxc_write_nointr(label_fd, command, len - 1);
|
ret = lxc_write_nointr(label_fd, command, len - 1);
|
||||||
@@ -161,9 +163,11 @@ int lsm_process_label_set_at(int label_fd, const char *label, bool on_exec)
|
|||||||
} else if (strcmp(name, "SELinux") == 0) {
|
} else if (strcmp(name, "SELinux") == 0) {
|
||||||
ret = lxc_write_nointr(label_fd, label, strlen(label));
|
ret = lxc_write_nointr(label_fd, label, strlen(label));
|
||||||
} else {
|
} else {
|
||||||
ret = -EINVAL;
|
errno = EINVAL;
|
||||||
|
ret = -1;
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
on_error:
|
||||||
SYSERROR("Failed to set %s label \"%s\"", name, label);
|
SYSERROR("Failed to set %s label \"%s\"", name, label);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -173,11 +177,37 @@ int lsm_process_label_set_at(int label_fd, const char *label, bool on_exec)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lsm_process_label_set(const char *label, struct lxc_conf *conf,
|
int lsm_process_label_set(const char *label, struct lxc_conf *conf,
|
||||||
bool use_default, bool on_exec)
|
bool on_exec)
|
||||||
{
|
{
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
ERROR("LSM driver not inited");
|
ERROR("LSM driver not inited");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return drv->process_label_set(label, conf, use_default, on_exec);
|
return drv->process_label_set(label, conf, on_exec);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lsm_process_prepare(struct lxc_conf *conf, const char *lxcpath)
|
||||||
|
{
|
||||||
|
if (!drv) {
|
||||||
|
ERROR("LSM driver not inited");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!drv->prepare)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return drv->prepare(conf, lxcpath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lsm_process_cleanup(struct lxc_conf *conf, const char *lxcpath)
|
||||||
|
{
|
||||||
|
if (!drv) {
|
||||||
|
ERROR("LSM driver not inited");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!drv->cleanup)
|
||||||
|
return;
|
||||||
|
|
||||||
|
drv->cleanup(conf, lxcpath);
|
||||||
}
|
}
|
||||||
|
@@ -38,17 +38,21 @@ struct lsm_drv {
|
|||||||
int (*enabled)(void);
|
int (*enabled)(void);
|
||||||
char *(*process_label_get)(pid_t pid);
|
char *(*process_label_get)(pid_t pid);
|
||||||
int (*process_label_set)(const char *label, struct lxc_conf *conf,
|
int (*process_label_set)(const char *label, struct lxc_conf *conf,
|
||||||
bool use_default, bool on_exec);
|
bool on_exec);
|
||||||
|
int (*prepare)(struct lxc_conf *conf, const char *lxcpath);
|
||||||
|
void (*cleanup)(struct lxc_conf *conf, const char *lxcpath);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void lsm_init(void);
|
extern void lsm_init(void);
|
||||||
extern int lsm_enabled(void);
|
extern int lsm_enabled(void);
|
||||||
extern const char *lsm_name(void);
|
extern const char *lsm_name(void);
|
||||||
extern char *lsm_process_label_get(pid_t pid);
|
extern char *lsm_process_label_get(pid_t pid);
|
||||||
|
extern int lsm_process_prepare(struct lxc_conf *conf, const char *lxcpath);
|
||||||
extern int lsm_process_label_set(const char *label, struct lxc_conf *conf,
|
extern int lsm_process_label_set(const char *label, struct lxc_conf *conf,
|
||||||
bool use_default, bool on_exec);
|
bool on_exec);
|
||||||
extern int lsm_process_label_fd_get(pid_t pid, bool on_exec);
|
extern int lsm_process_label_fd_get(pid_t pid, bool on_exec);
|
||||||
extern int lsm_process_label_set_at(int label_fd, const char *label,
|
extern int lsm_process_label_set_at(int label_fd, const char *label,
|
||||||
bool on_exec);
|
bool on_exec);
|
||||||
|
extern void lsm_process_cleanup(struct lxc_conf *conf, const char *lxcpath);
|
||||||
|
|
||||||
#endif /* __LXC_LSM_H */
|
#endif /* __LXC_LSM_H */
|
||||||
|
@@ -30,7 +30,7 @@ static char *nop_process_label_get(pid_t pid)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int nop_process_label_set(const char *label, struct lxc_conf *conf,
|
static int nop_process_label_set(const char *label, struct lxc_conf *conf,
|
||||||
bool use_default, bool on_exec)
|
bool on_exec)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -75,15 +75,13 @@ static char *selinux_process_label_get(pid_t pid)
|
|||||||
* Notes: This relies on /proc being available.
|
* Notes: This relies on /proc being available.
|
||||||
*/
|
*/
|
||||||
static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf,
|
static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf,
|
||||||
bool use_default, bool on_exec)
|
bool on_exec)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
const char *label;
|
const char *label;
|
||||||
|
|
||||||
label = inlabel ? inlabel : conf->lsm_se_context;
|
label = inlabel ? inlabel : conf->lsm_se_context;
|
||||||
if (!label) {
|
if (!label) {
|
||||||
if (!use_default)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
label = DEFAULT_LABEL;
|
label = DEFAULT_LABEL;
|
||||||
}
|
}
|
||||||
|
@@ -863,9 +863,19 @@ int lxc_init(const char *name, struct lxc_handler *handler)
|
|||||||
}
|
}
|
||||||
TRACE("Initialized cgroup driver");
|
TRACE("Initialized cgroup driver");
|
||||||
|
|
||||||
|
ret = lsm_process_prepare(conf, handler->lxcpath);
|
||||||
|
if (ret < 0) {
|
||||||
|
ERROR("Failed to initialize LSM");
|
||||||
|
goto out_destroy_cgroups;
|
||||||
|
}
|
||||||
|
TRACE("Initialized LSM");
|
||||||
|
|
||||||
INFO("Container \"%s\" is initialized", name);
|
INFO("Container \"%s\" is initialized", name);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_destroy_cgroups:
|
||||||
|
handler->cgroup_ops->destroy(handler->cgroup_ops, handler);
|
||||||
|
|
||||||
out_delete_terminal:
|
out_delete_terminal:
|
||||||
lxc_terminal_delete(&handler->conf->console);
|
lxc_terminal_delete(&handler->conf->console);
|
||||||
|
|
||||||
@@ -956,6 +966,8 @@ void lxc_fini(const char *name, struct lxc_handler *handler)
|
|||||||
while (namespace_count--)
|
while (namespace_count--)
|
||||||
free(namespaces[namespace_count]);
|
free(namespaces[namespace_count]);
|
||||||
|
|
||||||
|
lsm_process_cleanup(handler->conf, handler->lxcpath);
|
||||||
|
|
||||||
cgroup_ops->destroy(cgroup_ops, handler);
|
cgroup_ops->destroy(cgroup_ops, handler);
|
||||||
cgroup_exit(cgroup_ops);
|
cgroup_exit(cgroup_ops);
|
||||||
|
|
||||||
@@ -1235,7 +1247,7 @@ static int do_start(void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set the label to change to when we exec(2) the container's init. */
|
/* Set the label to change to when we exec(2) the container's init. */
|
||||||
ret = lsm_process_label_set(NULL, handler->conf, 1, 1);
|
ret = lsm_process_label_set(NULL, handler->conf, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto out_warn_father;
|
goto out_warn_father;
|
||||||
|
|
||||||
|
@@ -2433,6 +2433,30 @@ int run_command(char *buf, size_t buf_size, int (*child_fn)(void *), void *args)
|
|||||||
return fret;
|
return fret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *must_concat(const char *first, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
char *cur, *dest;
|
||||||
|
size_t cur_len, it_len;
|
||||||
|
|
||||||
|
dest = must_copy_string(first);
|
||||||
|
cur_len = it_len = strlen(first);
|
||||||
|
|
||||||
|
va_start(args, first);
|
||||||
|
while ((cur = va_arg(args, char *)) != NULL) {
|
||||||
|
it_len = strlen(cur);
|
||||||
|
|
||||||
|
dest = must_realloc(dest, cur_len + it_len + 1);
|
||||||
|
|
||||||
|
(void)memcpy(dest + cur_len, cur, it_len);
|
||||||
|
cur_len += it_len;
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
dest[cur_len] = 0;
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
char *must_make_path(const char *first, ...)
|
char *must_make_path(const char *first, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
|
@@ -568,6 +568,7 @@ extern int run_command(char *buf, size_t buf_size, int (*child_fn)(void *),
|
|||||||
/* Concatenate all passed-in strings into one path. Do not fail. If any piece
|
/* Concatenate all passed-in strings into one path. Do not fail. If any piece
|
||||||
* is not prefixed with '/', add a '/'.
|
* is not prefixed with '/', add a '/'.
|
||||||
*/
|
*/
|
||||||
|
__attribute__((sentinel)) extern char *must_concat(const char *first, ...);
|
||||||
__attribute__((sentinel)) extern char *must_make_path(const char *first, ...);
|
__attribute__((sentinel)) extern char *must_make_path(const char *first, ...);
|
||||||
__attribute__((sentinel)) extern char *must_append_path(char *first, ...);
|
__attribute__((sentinel)) extern char *must_append_path(char *first, ...);
|
||||||
|
|
||||||
|
@@ -81,6 +81,7 @@ if DISTRO_UBUNTU
|
|||||||
bin_SCRIPTS += \
|
bin_SCRIPTS += \
|
||||||
lxc-test-lxc-attach \
|
lxc-test-lxc-attach \
|
||||||
lxc-test-apparmor-mount \
|
lxc-test-apparmor-mount \
|
||||||
|
lxc-test-apparmor-generated \
|
||||||
lxc-test-checkpoint-restore \
|
lxc-test-checkpoint-restore \
|
||||||
lxc-test-snapdeps \
|
lxc-test-snapdeps \
|
||||||
lxc-test-symlink \
|
lxc-test-symlink \
|
||||||
@@ -114,6 +115,7 @@ EXTRA_DIST = \
|
|||||||
lxc-test-rootfs \
|
lxc-test-rootfs \
|
||||||
lxc-test-autostart \
|
lxc-test-autostart \
|
||||||
lxc-test-apparmor-mount \
|
lxc-test-apparmor-mount \
|
||||||
|
lxc-test-apparmor-generated \
|
||||||
lxc-test-checkpoint-restore \
|
lxc-test-checkpoint-restore \
|
||||||
lxc-test-cloneconfig \
|
lxc-test-cloneconfig \
|
||||||
lxc-test-createconfig \
|
lxc-test-createconfig \
|
||||||
|
84
src/tests/lxc-test-apparmor-generated
Executable file
84
src/tests/lxc-test-apparmor-generated
Executable file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# lxc: linux Container library
|
||||||
|
|
||||||
|
# This is a test script for generated apparmor profiles
|
||||||
|
|
||||||
|
# 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 ! which apparmor_parser >/dev/null 2>&1; then
|
||||||
|
echo 'SKIP: test for generated apparmor profiles: apparmor_parser missing'
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
DONE=0
|
||||||
|
KNOWN_RELEASES="precise trusty xenial yakkety zesty"
|
||||||
|
LOGFILE="/tmp/lxc-test-$$.log"
|
||||||
|
cleanup() {
|
||||||
|
lxc-destroy -n $CONTAINER_NAME >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
if [ $DONE -eq 0 ]; then
|
||||||
|
[ -f "$LOGFILE" ] && cat "$LOGFILE" >&2
|
||||||
|
rm -f "$LOGFILE"
|
||||||
|
echo "FAIL"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rm -f "$LOGFILE"
|
||||||
|
echo "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
ARCH=i386
|
||||||
|
if type dpkg >/dev/null 2>&1; then
|
||||||
|
ARCH=$(dpkg --print-architecture)
|
||||||
|
fi
|
||||||
|
|
||||||
|
trap cleanup EXIT HUP INT TERM
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# Create a container
|
||||||
|
CONTAINER_NAME=lxc-test-apparmor-generated
|
||||||
|
|
||||||
|
# default release is trusty, or the systems release if recognized
|
||||||
|
release=trusty
|
||||||
|
if [ -f /etc/lsb-release ]; then
|
||||||
|
. /etc/lsb-release
|
||||||
|
rels=$(ubuntu-distro-info --supported 2>/dev/null) ||
|
||||||
|
rels="$KNOWN_RELEASES"
|
||||||
|
for r in $rels; do
|
||||||
|
[ "$DISTRIB_CODENAME" = "$r" ] && release="$r"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
lxc-create -t download -n $CONTAINER_NAME -B dir -- -d ubuntu -r $release -a $ARCH
|
||||||
|
CONTAINER_PATH=$(dirname $(lxc-info -n $CONTAINER_NAME -c lxc.rootfs.path -H) | sed -e 's/dir://')
|
||||||
|
cp $CONTAINER_PATH/config $CONTAINER_PATH/config.bak
|
||||||
|
|
||||||
|
# Set the profile to be auto-generated
|
||||||
|
echo "lxc.apparmor.profile = generated" >> $CONTAINER_PATH/config
|
||||||
|
|
||||||
|
# Start it
|
||||||
|
lxc-start -n $CONTAINER_NAME -lDEBUG -o "$LOGFILE"
|
||||||
|
lxc-wait -n $CONTAINER_NAME -t 5 -s RUNNING || (echo "Container didn't start" && exit 1)
|
||||||
|
pid=`lxc-info -p -H -n $CONTAINER_NAME`
|
||||||
|
profile=`cat /proc/$pid/attr/current`
|
||||||
|
expected_profile="lxc-${CONTAINER_NAME}_</var/lib/lxc>//&:lxc-${CONTAINER_NAME}_<-var-lib-lxc>:unconfined (enforce)"
|
||||||
|
lxc-stop -n $CONTAINER_NAME -k
|
||||||
|
if [ "x$profile" != "x$expected_profile" ]; then
|
||||||
|
echo "FAIL: container was in profile $profile" >&2
|
||||||
|
echo "expected profile: $expected_profile" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DONE=1
|
@@ -23,6 +23,16 @@
|
|||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
# Only run on a normally configured ubuntu lxc system
|
||||||
|
if [ ! -d /sys/class/net/lxcbr0 ]; then
|
||||||
|
echo "lxcbr0 is not configured."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ "$(id -u)" != "0" ]; then
|
||||||
|
echo "ERROR: Must run as root."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -f /proc/self/ns/cgroup ]; then
|
if [ -f /proc/self/ns/cgroup ]; then
|
||||||
default_profile="lxc-container-default-cgns (enforce)"
|
default_profile="lxc-container-default-cgns (enforce)"
|
||||||
else
|
else
|
||||||
@@ -45,6 +55,7 @@ DONE=0
|
|||||||
KNOWN_RELEASES="precise trusty xenial yakkety zesty"
|
KNOWN_RELEASES="precise trusty xenial yakkety zesty"
|
||||||
MOUNTSR=/sys/kernel/security/apparmor/features/mount
|
MOUNTSR=/sys/kernel/security/apparmor/features/mount
|
||||||
dnam=`mktemp -d`
|
dnam=`mktemp -d`
|
||||||
|
logfile=`mktemp`
|
||||||
cname=`basename $dnam`
|
cname=`basename $dnam`
|
||||||
cleanup() {
|
cleanup() {
|
||||||
run_cmd lxc-destroy -f -n $cname || true
|
run_cmd lxc-destroy -f -n $cname || true
|
||||||
@@ -56,23 +67,24 @@ cleanup() {
|
|||||||
rm -Rf $HDIR /run/user/$(id -u $TUSER)
|
rm -Rf $HDIR /run/user/$(id -u $TUSER)
|
||||||
deluser $TUSER
|
deluser $TUSER
|
||||||
if [ $DONE -eq 0 ]; then
|
if [ $DONE -eq 0 ]; then
|
||||||
|
echo 'Failed container log:' >&2
|
||||||
|
cat "$logfile" >&2
|
||||||
|
echo 'End log' >&2
|
||||||
|
rm -f "$logfile"
|
||||||
echo "FAIL"
|
echo "FAIL"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
rm -f "$logfile"
|
||||||
echo "PASS"
|
echo "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clear_log() {
|
||||||
|
truncate -s0 "$logfile"
|
||||||
|
}
|
||||||
|
|
||||||
trap cleanup exit
|
trap cleanup exit
|
||||||
|
|
||||||
# Only run on a normally configured ubuntu lxc system
|
chmod 0666 "$logfile"
|
||||||
if [ ! -d /sys/class/net/lxcbr0 ]; then
|
|
||||||
echo "lxcbr0 is not configured."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ "$(id -u)" != "0" ]; then
|
|
||||||
echo "ERROR: Must run as root."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# This would be much simpler if we could run it as
|
# This would be much simpler if we could run it as
|
||||||
# root. However, in order to not have the bind mount
|
# root. However, in order to not have the bind mount
|
||||||
@@ -160,7 +172,7 @@ fi
|
|||||||
run_cmd lxc-create -t download -n $cname -- -d ubuntu -r $release -a $ARCH
|
run_cmd lxc-create -t download -n $cname -- -d ubuntu -r $release -a $ARCH
|
||||||
|
|
||||||
echo "test default confined container"
|
echo "test default confined container"
|
||||||
run_cmd lxc-start -n $cname -d
|
run_cmd lxc-start -n $cname -d -lDEBUG -o "$logfile"
|
||||||
run_cmd lxc-wait -n $cname -s RUNNING
|
run_cmd lxc-wait -n $cname -s RUNNING
|
||||||
pid=`run_cmd lxc-info -p -H -n $cname`
|
pid=`run_cmd lxc-info -p -H -n $cname`
|
||||||
profile=`cat /proc/$pid/attr/current`
|
profile=`cat /proc/$pid/attr/current`
|
||||||
@@ -169,10 +181,11 @@ if [ "x$profile" != "x${default_profile}" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
run_cmd lxc-stop -n $cname -k
|
run_cmd lxc-stop -n $cname -k
|
||||||
|
clear_log
|
||||||
|
|
||||||
echo "test regular unconfined container"
|
echo "test regular unconfined container"
|
||||||
echo "lxc.apparmor.profile = unconfined" >> $HDIR/.local/share/lxc/$cname/config
|
echo "lxc.apparmor.profile = unconfined" >> $HDIR/.local/share/lxc/$cname/config
|
||||||
run_cmd lxc-start -n $cname -d
|
run_cmd lxc-start -n $cname -d -lDEBUG -o "$logfile"
|
||||||
run_cmd lxc-wait -n $cname -s RUNNING
|
run_cmd lxc-wait -n $cname -s RUNNING
|
||||||
pid=`run_cmd lxc-info -p -H -n $cname`
|
pid=`run_cmd lxc-info -p -H -n $cname`
|
||||||
profile=`cat /proc/$pid/attr/current`
|
profile=`cat /proc/$pid/attr/current`
|
||||||
@@ -181,6 +194,7 @@ if [ "x$profile" != "xunconfined" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
run_cmd lxc-stop -n $cname -k
|
run_cmd lxc-stop -n $cname -k
|
||||||
|
clear_log
|
||||||
|
|
||||||
echo "masking $MOUNTSR"
|
echo "masking $MOUNTSR"
|
||||||
mount --bind $dnam $MOUNTSR
|
mount --bind $dnam $MOUNTSR
|
||||||
@@ -198,7 +212,7 @@ fi
|
|||||||
|
|
||||||
echo "test regular unconfined container"
|
echo "test regular unconfined container"
|
||||||
echo "lxc.apparmor.profile = unconfined" >> $HDIR/.local/share/lxc/$cname/config
|
echo "lxc.apparmor.profile = unconfined" >> $HDIR/.local/share/lxc/$cname/config
|
||||||
run_cmd lxc-start -n $cname -d
|
run_cmd lxc-start -n $cname -d -lDEBUG -o "$logfile"
|
||||||
run_cmd lxc-wait -n $cname -s RUNNING
|
run_cmd lxc-wait -n $cname -s RUNNING
|
||||||
pid=`run_cmd lxc-info -p -H -n $cname`
|
pid=`run_cmd lxc-info -p -H -n $cname`
|
||||||
if [ "$pid" = "-1" ]; then
|
if [ "$pid" = "-1" ]; then
|
||||||
@@ -211,11 +225,12 @@ if [ "x$profile" != "xunconfined" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
run_cmd lxc-stop -n $cname -k
|
run_cmd lxc-stop -n $cname -k
|
||||||
|
clear_log
|
||||||
|
|
||||||
echo "testing override"
|
echo "testing override"
|
||||||
sed -i '/apparmor.profile/d' $HDIR/.local/share/lxc/$cname/config
|
sed -i '/apparmor.profile/d' $HDIR/.local/share/lxc/$cname/config
|
||||||
echo "lxc.apparmor.allow_incomplete = 1" >> $HDIR/.local/share/lxc/$cname/config
|
echo "lxc.apparmor.allow_incomplete = 1" >> $HDIR/.local/share/lxc/$cname/config
|
||||||
run_cmd lxc-start -n $cname -d
|
run_cmd lxc-start -n $cname -d -lDEBUG -o "$logfile"
|
||||||
run_cmd lxc-wait -n $cname -s RUNNING
|
run_cmd lxc-wait -n $cname -s RUNNING
|
||||||
pid=`run_cmd lxc-info -p -H -n $cname`
|
pid=`run_cmd lxc-info -p -H -n $cname`
|
||||||
if [ "$pid" = "-1" ]; then
|
if [ "$pid" = "-1" ]; then
|
||||||
@@ -228,5 +243,6 @@ if [ "x$profile" != "x${default_profile}" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
run_cmd lxc-stop -n $cname -k
|
run_cmd lxc-stop -n $cname -k
|
||||||
|
clear_log
|
||||||
|
|
||||||
DONE=1
|
DONE=1
|
||||||
|
Reference in New Issue
Block a user