Unverified Commit 76a59906 by Stéphane Graber Committed by GitHub

Merge pull request #3518 from brauner/2020-08-12/fixes

lsm: remove the need for atomic operations
parents b7993256 af04d847
...@@ -93,7 +93,7 @@ static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid) ...@@ -93,7 +93,7 @@ static struct lxc_proc_context_info *lxc_proc_get_context_info(pid_t pid)
info->lsm_ops = lsm_init(); info->lsm_ops = lsm_init();
info->lsm_label = info->lsm_ops->process_label_get(pid); info->lsm_label = info->lsm_ops->process_label_get(info->lsm_ops, pid);
info->ns_inherited = 0; info->ns_inherited = 0;
for (int i = 0; i < LXC_NS_MAX; i++) for (int i = 0; i < LXC_NS_MAX; i++)
info->ns_fd[i] = -EBADF; info->ns_fd[i] = -EBADF;
...@@ -779,7 +779,8 @@ static int attach_child_main(struct attach_clone_payload *payload) ...@@ -779,7 +779,8 @@ static int attach_child_main(struct attach_clone_payload *payload)
/* Change into our new LSM profile. */ /* Change into our new LSM profile. */
on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? true : false; on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? true : false;
ret = init_ctx->lsm_ops->process_label_set_at(lsm_fd, init_ctx->lsm_label, on_exec); ret = init_ctx->lsm_ops->process_label_set_at(init_ctx->lsm_ops, lsm_fd,
init_ctx->lsm_label, on_exec);
close(lsm_fd); close(lsm_fd);
if (ret < 0) if (ret < 0)
goto on_error; goto on_error;
...@@ -1244,7 +1245,8 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, ...@@ -1244,7 +1245,8 @@ int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
ret = -1; ret = -1;
on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? true : false; on_exec = options->attach_flags & LXC_ATTACH_LSM_EXEC ? true : false;
labelfd = init_ctx->lsm_ops->process_label_fd_get(attached_pid, on_exec); labelfd = init_ctx->lsm_ops->process_label_fd_get(init_ctx->lsm_ops,
attached_pid, on_exec);
if (labelfd < 0) if (labelfd < 0)
goto close_mainloop; goto close_mainloop;
......
...@@ -19,7 +19,7 @@ struct lxc_proc_context_info { ...@@ -19,7 +19,7 @@ struct lxc_proc_context_info {
unsigned long long capability_mask; unsigned long long capability_mask;
int ns_inherited; int ns_inherited;
int ns_fd[LXC_NS_MAX]; int ns_fd[LXC_NS_MAX];
const struct lsm_ops *lsm_ops; struct lsm_ops *lsm_ops;
}; };
__hidden extern int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function, __hidden extern int lxc_attach(struct lxc_container *container, lxc_attach_exec_t exec_function,
......
...@@ -3211,15 +3211,15 @@ static int lxc_setup_boot_id(void) ...@@ -3211,15 +3211,15 @@ static int lxc_setup_boot_id(void)
return 0; return 0;
} }
static int lxc_setup_keyring(const struct lsm_ops *lsm_ops, const struct lxc_conf *conf) static int lxc_setup_keyring(struct lsm_ops *lsm_ops, const struct lxc_conf *conf)
{ {
key_serial_t keyring; key_serial_t keyring;
int ret = 0; int ret = 0;
if (conf->lsm_se_keyring_context) if (conf->lsm_se_keyring_context)
ret = lsm_ops->keyring_label_set(conf->lsm_se_keyring_context); ret = lsm_ops->keyring_label_set(lsm_ops, conf->lsm_se_keyring_context);
else if (conf->lsm_se_context) else if (conf->lsm_se_context)
ret = lsm_ops->keyring_label_set(conf->lsm_se_context); ret = lsm_ops->keyring_label_set(lsm_ops, conf->lsm_se_context);
if (ret < 0) if (ret < 0)
return log_error_errno(-1, errno, "Failed to set keyring context"); return log_error_errno(-1, errno, "Failed to set keyring context");
......
...@@ -21,9 +21,9 @@ __hidden extern struct lsm_ops *lsm_apparmor_ops_init(void); ...@@ -21,9 +21,9 @@ __hidden extern struct lsm_ops *lsm_apparmor_ops_init(void);
__hidden extern struct lsm_ops *lsm_selinux_ops_init(void); __hidden extern struct lsm_ops *lsm_selinux_ops_init(void);
__hidden extern struct lsm_ops *lsm_nop_ops_init(void); __hidden extern struct lsm_ops *lsm_nop_ops_init(void);
const struct lsm_ops *lsm_init(void) struct lsm_ops *lsm_init(void)
{ {
const struct lsm_ops *ops = NULL; struct lsm_ops *ops = NULL;
#if HAVE_APPARMOR #if HAVE_APPARMOR
ops = lsm_apparmor_ops_init(); ops = lsm_apparmor_ops_init();
......
...@@ -14,16 +14,25 @@ struct lxc_conf; ...@@ -14,16 +14,25 @@ struct lxc_conf;
struct lsm_ops { struct lsm_ops {
const char *name; const char *name;
int (*enabled)(void); /* AppArmor specific fields. */
char *(*process_label_get)(pid_t pid); int aa_enabled;
int (*process_label_set)(const char *label, struct lxc_conf *conf, bool on_exec); int aa_parser_available;
int (*keyring_label_set)(const char *label); int aa_supports_unix;
int (*prepare)(struct lxc_conf *conf, const char *lxcpath); int aa_can_stack;
void (*cleanup)(struct lxc_conf *conf, const char *lxcpath); int aa_is_stacked;
int (*process_label_fd_get)(pid_t pid, bool on_exec); int aa_admin;
int (*process_label_set_at)(int label_fd, const char *label, bool on_exec); int aa_mount_features_enabled;
int (*enabled)(struct lsm_ops *ops);
char *(*process_label_get)(struct lsm_ops *ops, pid_t pid);
int (*process_label_set)(struct lsm_ops *ops, const char *label, struct lxc_conf *conf, bool on_exec);
int (*keyring_label_set)(struct lsm_ops *ops, const char *label);
int (*prepare)(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath);
void (*cleanup)(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath);
int (*process_label_fd_get)(struct lsm_ops *ops, pid_t pid, bool on_exec);
int (*process_label_set_at)(struct lsm_ops *ops, int label_fd, const char *label, bool on_exec);
}; };
__hidden extern const struct lsm_ops *lsm_init(void); __hidden extern struct lsm_ops *lsm_init(void);
#endif /* __LXC_LSM_H */ #endif /* __LXC_LSM_H */
...@@ -8,59 +8,66 @@ ...@@ -8,59 +8,66 @@
#include "config.h" #include "config.h"
#include "lsm/lsm.h" #include "lsm/lsm.h"
static char *nop_process_label_get(pid_t pid) static char *nop_process_label_get(struct lsm_ops *ops, pid_t pid)
{ {
return NULL; return NULL;
} }
static int nop_process_label_set(const char *label, struct lxc_conf *conf, static int nop_process_label_set(struct lsm_ops *ops, const char *label, struct lxc_conf *conf,
bool on_exec) bool on_exec)
{ {
return 0; return 0;
} }
static int nop_enabled(void) static int nop_enabled(struct lsm_ops *ops)
{ {
return 0; return 0;
} }
static int nop_keyring_label_set(const char *label) static int nop_keyring_label_set(struct lsm_ops *ops, const char *label)
{ {
return 0; return 0;
} }
static int nop_prepare(struct lxc_conf *conf, const char *lxcpath) static int nop_prepare(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath)
{ {
return 0; return 0;
} }
static void nop_cleanup(struct lxc_conf *conf, const char *lxcpath) static void nop_cleanup(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath)
{ {
} }
static int nop_process_label_fd_get(pid_t pid, bool on_exec) static int nop_process_label_fd_get(struct lsm_ops *ops, pid_t pid, bool on_exec)
{ {
return 0; return 0;
} }
static int nop_process_label_set_at(int label_fd, const char *label, bool on_exec) static int nop_process_label_set_at(struct lsm_ops *ops, int label_fd, const char *label, bool on_exec)
{ {
return 0; return 0;
} }
static struct lsm_ops nop_ops = { static struct lsm_ops nop_ops = {
.name = "nop", .name = "nop",
.cleanup = nop_cleanup, .aa_admin = -1,
.enabled = nop_enabled, .aa_can_stack = -1,
.keyring_label_set = nop_keyring_label_set, .aa_enabled = -1,
.prepare = nop_prepare, .aa_is_stacked = -1,
.process_label_fd_get = nop_process_label_fd_get, .aa_mount_features_enabled = -1,
.process_label_get = nop_process_label_get, .aa_parser_available = -1,
.process_label_set = nop_process_label_set, .aa_supports_unix = -1,
.process_label_set_at = nop_process_label_set_at, .cleanup = nop_cleanup,
.enabled = nop_enabled,
.keyring_label_set = nop_keyring_label_set,
.prepare = nop_prepare,
.process_label_fd_get = nop_process_label_fd_get,
.process_label_get = nop_process_label_get,
.process_label_set = nop_process_label_set,
.process_label_set_at = nop_process_label_set_at,
}; };
const struct lsm_ops *lsm_nop_ops_init(void) struct lsm_ops *lsm_nop_ops_init(void)
{ {
return &nop_ops; return &nop_ops;
} }
...@@ -30,7 +30,7 @@ lxc_log_define(selinux, lsm); ...@@ -30,7 +30,7 @@ lxc_log_define(selinux, lsm);
* *
* Note that this relies on /proc being available. * Note that this relies on /proc being available.
*/ */
static char *selinux_process_label_get(pid_t pid) static char *selinux_process_label_get(struct lsm_ops *ops, pid_t pid)
{ {
char *label; char *label;
...@@ -52,8 +52,8 @@ static char *selinux_process_label_get(pid_t pid) ...@@ -52,8 +52,8 @@ 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(struct lsm_ops *ops, const char *inlabel,
bool on_exec) struct lxc_conf *conf, bool on_exec)
{ {
int ret; int ret;
const char *label; const char *label;
...@@ -84,21 +84,21 @@ static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf, ...@@ -84,21 +84,21 @@ static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf,
* *
* Returns 0 on success, < 0 on failure * Returns 0 on success, < 0 on failure
*/ */
static int selinux_keyring_label_set(const char *label) static int selinux_keyring_label_set(struct lsm_ops *ops, const char *label)
{ {
return setkeycreatecon_raw(label); return setkeycreatecon_raw(label);
} }
static int selinux_prepare(struct lxc_conf *conf, const char *lxcpath) static int selinux_prepare(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath)
{ {
return 0; return 0;
} }
static void selinux_cleanup(struct lxc_conf *conf, const char *lxcpath) static void selinux_cleanup(struct lsm_ops *ops, struct lxc_conf *conf, const char *lxcpath)
{ {
} }
static int selinux_process_label_fd_get(pid_t pid, bool on_exec) static int selinux_process_label_fd_get(struct lsm_ops *ops, pid_t pid, bool on_exec)
{ {
int ret = -1; int ret = -1;
int labelfd; int labelfd;
...@@ -118,7 +118,7 @@ static int selinux_process_label_fd_get(pid_t pid, bool on_exec) ...@@ -118,7 +118,7 @@ static int selinux_process_label_fd_get(pid_t pid, bool on_exec)
return labelfd; return labelfd;
} }
static int selinux_process_label_set_at(int label_fd, const char *label, bool on_exec) static int selinux_process_label_set_at(struct lsm_ops *ops, int label_fd, const char *label, bool on_exec)
{ {
int ret; int ret;
...@@ -133,19 +133,31 @@ static int selinux_process_label_set_at(int label_fd, const char *label, bool on ...@@ -133,19 +133,31 @@ static int selinux_process_label_set_at(int label_fd, const char *label, bool on
return 0; return 0;
} }
static int selinux_enabled(struct lsm_ops *ops)
{
return is_selinux_enabled();
}
static struct lsm_ops selinux_ops = { static struct lsm_ops selinux_ops = {
.name = "SELinux", .name = "SELinux",
.cleanup = selinux_cleanup, .aa_admin = -1,
.enabled = is_selinux_enabled, .aa_can_stack = -1,
.keyring_label_set = selinux_keyring_label_set, .aa_enabled = -1,
.prepare = selinux_prepare, .aa_is_stacked = -1,
.process_label_fd_get = selinux_process_label_fd_get, .aa_mount_features_enabled = -1,
.process_label_get = selinux_process_label_get, .aa_parser_available = -1,
.process_label_set = selinux_process_label_set, .aa_supports_unix = -1,
.process_label_set_at = selinux_process_label_set_at, .cleanup = selinux_cleanup,
.enabled = selinux_enabled,
.keyring_label_set = selinux_keyring_label_set,
.prepare = selinux_prepare,
.process_label_fd_get = selinux_process_label_fd_get,
.process_label_get = selinux_process_label_get,
.process_label_set = selinux_process_label_set,
.process_label_set_at = selinux_process_label_set_at,
}; };
const struct lsm_ops *lsm_selinux_ops_init(void) struct lsm_ops *lsm_selinux_ops_init(void)
{ {
if (!is_selinux_enabled()) if (!is_selinux_enabled())
return NULL; return NULL;
......
...@@ -827,7 +827,7 @@ int lxc_init(const char *name, struct lxc_handler *handler) ...@@ -827,7 +827,7 @@ int lxc_init(const char *name, struct lxc_handler *handler)
return log_error(-1, "Failed loading seccomp policy"); return log_error(-1, "Failed loading seccomp policy");
TRACE("Read seccomp policy"); TRACE("Read seccomp policy");
ret = handler->lsm_ops->prepare(conf, handler->lxcpath); ret = handler->lsm_ops->prepare(handler->lsm_ops, conf, handler->lxcpath);
if (ret < 0) { if (ret < 0) {
ERROR("Failed to initialize LSM"); ERROR("Failed to initialize LSM");
goto out_delete_terminal; goto out_delete_terminal;
...@@ -918,7 +918,7 @@ void lxc_end(struct lxc_handler *handler) ...@@ -918,7 +918,7 @@ void lxc_end(struct lxc_handler *handler)
while (namespace_count--) while (namespace_count--)
free(namespaces[namespace_count]); free(namespaces[namespace_count]);
handler->lsm_ops->cleanup(handler->conf, handler->lxcpath); handler->lsm_ops->cleanup(handler->lsm_ops, handler->conf, handler->lxcpath);
if (cgroup_ops) { if (cgroup_ops) {
cgroup_ops->payload_destroy(cgroup_ops, handler); cgroup_ops->payload_destroy(cgroup_ops, handler);
...@@ -1269,7 +1269,7 @@ static int do_start(void *data) ...@@ -1269,7 +1269,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 = handler->lsm_ops->process_label_set(NULL, handler->conf, true); ret = handler->lsm_ops->process_label_set(handler->lsm_ops, NULL, handler->conf, true);
if (ret < 0) if (ret < 0)
goto out_warn_father; goto out_warn_father;
......
...@@ -128,7 +128,8 @@ struct lxc_handler { ...@@ -128,7 +128,8 @@ struct lxc_handler {
/* Internal fds that always need to stay open. */ /* Internal fds that always need to stay open. */
int keep_fds[3]; int keep_fds[3];
const struct lsm_ops *lsm_ops; /* Static memory, don't free. */
struct lsm_ops *lsm_ops;
}; };
struct execute_args { struct execute_args {
......
...@@ -47,11 +47,11 @@ ...@@ -47,11 +47,11 @@
static const char *lsm_config_key = NULL; static const char *lsm_config_key = NULL;
static const char *lsm_label = NULL; static const char *lsm_label = NULL;
const struct lsm_ops *lsm_ops; struct lsm_ops *lsm_ops;
static void test_lsm_detect(void) static void test_lsm_detect(void)
{ {
if (lsm_ops->enabled()) { if (lsm_ops->enabled(lsm_ops)) {
if (!strcmp(lsm_ops->name, "SELinux")) { if (!strcmp(lsm_ops->name, "SELinux")) {
lsm_config_key = "lxc.selinux.context"; lsm_config_key = "lxc.selinux.context";
lsm_label = "unconfined_u:unconfined_r:lxc_t:s0-s0:c0.c1023"; lsm_label = "unconfined_u:unconfined_r:lxc_t:s0-s0:c0.c1023";
...@@ -80,7 +80,7 @@ static void test_attach_lsm_set_config(struct lxc_container *ct) ...@@ -80,7 +80,7 @@ static void test_attach_lsm_set_config(struct lxc_container *ct)
static int test_attach_lsm_func_func(void* payload) static int test_attach_lsm_func_func(void* payload)
{ {
TSTOUT("%s", lsm_ops->process_label_get(syscall(SYS_getpid))); TSTOUT("%s", lsm_ops->process_label_get(lsm_ops, syscall(SYS_getpid)));
return 0; return 0;
} }
...@@ -330,7 +330,7 @@ static struct lxc_container *test_ct_create(const char *lxcpath, ...@@ -330,7 +330,7 @@ static struct lxc_container *test_ct_create(const char *lxcpath,
goto out2; goto out2;
} }
if (lsm_ops->enabled()) if (lsm_ops->enabled(lsm_ops))
test_attach_lsm_set_config(ct); test_attach_lsm_set_config(ct);
ct->want_daemonize(ct, true); ct->want_daemonize(ct, true);
...@@ -370,7 +370,7 @@ static int test_attach(const char *lxcpath, const char *name, const char *templa ...@@ -370,7 +370,7 @@ static int test_attach(const char *lxcpath, const char *name, const char *templa
goto err2; goto err2;
} }
if (lsm_ops->enabled()) { if (lsm_ops->enabled(lsm_ops)) {
ret = test_attach_lsm_cmd(ct); ret = test_attach_lsm_cmd(ct);
if (ret < 0) { if (ret < 0) {
TSTERR("attach lsm cmd test failed"); TSTERR("attach lsm cmd test failed");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment