Unverified Commit a8b9febd by Christian Brauner Committed by GitHub

Merge pull request #3260 from blenk92/add-keyring-option

Add keyring option
parents f5a15e1e ad36e96a
...@@ -84,5 +84,8 @@ allow lxc_t self:packet_socket create_socket_perms; ...@@ -84,5 +84,8 @@ allow lxc_t self:packet_socket create_socket_perms;
allow lxc_t self:rawip_socket create_socket_perms; allow lxc_t self:rawip_socket create_socket_perms;
allow lxc_t self:netlink_route_socket create_netlink_socket_perms; allow lxc_t self:netlink_route_socket create_netlink_socket_perms;
# Needed to set label that the keyring will be created with
allow lxc_t self:process { setkeycreate };
dontaudit lxc_t sysctl_kernel_t:file write; dontaudit lxc_t sysctl_kernel_t:file write;
dontaudit lxc_t sysctl_modprobe_t:file write; dontaudit lxc_t sysctl_modprobe_t:file write;
...@@ -1932,6 +1932,44 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ...@@ -1932,6 +1932,44 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
<programlisting>lxc.selinux.context = system_u:system_r:lxc_t:s0:c22</programlisting> <programlisting>lxc.selinux.context = system_u:system_r:lxc_t:s0:c22</programlisting>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<option>lxc.selinux.context.keyring</option>
</term>
<listitem>
<para>
Specify the SELinux context under which the container's keyring
should be created. By default this the same as lxc.selinux.context, or
the the context lxc is executed under if lxc.selinux.context has not been set.
</para>
<programlisting>lxc.selinux.context.keyring = system_u:system_r:lxc_t:s0:c22</programlisting>
</listitem>
</varlistentry>
</variablelist>
</refsect2>
<refsect2>
<title>Kernel Keyring</title>
<para>
The Linux Keyring facility is primarily a way for various
kernel components to retain or cache security data, authentication
keys, encryption keys, and other data in the kernel. By default lxc
will create a new session keyring for the started application.
</para>
<variablelist>
<varlistentry>
<term>
<option>lxc.keyring.session</option>
</term>
<listitem>
<para>
Disable the creation of new session keyring by lxc. The started
application will then inherit the current session keyring.
By default, or when passing the value 1, a new keyring will be created.
</para>
<programlisting>lxc.keyring.session = 0</programlisting>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect2> </refsect2>
......
...@@ -2742,6 +2742,8 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -2742,6 +2742,8 @@ struct lxc_conf *lxc_conf_init(void)
new->lsm_aa_profile = NULL; new->lsm_aa_profile = NULL;
lxc_list_init(&new->lsm_aa_raw); lxc_list_init(&new->lsm_aa_raw);
new->lsm_se_context = NULL; new->lsm_se_context = NULL;
new->lsm_se_keyring_context = NULL;
new->keyring_disable_session = false;
new->tmp_umount_proc = false; new->tmp_umount_proc = false;
new->tmp_umount_proc = 0; new->tmp_umount_proc = 0;
new->shmount.path_host = NULL; new->shmount.path_host = NULL;
...@@ -3533,6 +3535,7 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3533,6 +3535,7 @@ int lxc_setup(struct lxc_handler *handler)
int ret; int ret;
const char *lxcpath = handler->lxcpath, *name = handler->name; const char *lxcpath = handler->lxcpath, *name = handler->name;
struct lxc_conf *lxc_conf = handler->conf; struct lxc_conf *lxc_conf = handler->conf;
char *keyring_context = NULL;
ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath); ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath);
if (ret < 0) { if (ret < 0) {
...@@ -3548,9 +3551,17 @@ int lxc_setup(struct lxc_handler *handler) ...@@ -3548,9 +3551,17 @@ int lxc_setup(struct lxc_handler *handler)
} }
} }
ret = lxc_setup_keyring(); if (!lxc_conf->keyring_disable_session) {
if (lxc_conf->lsm_se_keyring_context) {
keyring_context = lxc_conf->lsm_se_keyring_context;
} else if (lxc_conf->lsm_se_context) {
keyring_context = lxc_conf->lsm_se_context;
}
ret = lxc_setup_keyring(keyring_context);
if (ret < 0) if (ret < 0)
return -1; return -1;
}
if (handler->ns_clone_flags & CLONE_NEWNET) { if (handler->ns_clone_flags & CLONE_NEWNET) {
ret = lxc_setup_network_in_child_namespaces(lxc_conf, ret = lxc_setup_network_in_child_namespaces(lxc_conf,
......
...@@ -298,6 +298,8 @@ struct lxc_conf { ...@@ -298,6 +298,8 @@ struct lxc_conf {
unsigned int lsm_aa_allow_incomplete; unsigned int lsm_aa_allow_incomplete;
struct lxc_list lsm_aa_raw; struct lxc_list lsm_aa_raw;
char *lsm_se_context; char *lsm_se_context;
char *lsm_se_keyring_context;
bool keyring_disable_session;
bool tmp_umount_proc; bool tmp_umount_proc;
struct lxc_seccomp seccomp; struct lxc_seccomp seccomp;
int maincmd_fd; int maincmd_fd;
......
...@@ -89,6 +89,7 @@ lxc_config_define(init_cmd); ...@@ -89,6 +89,7 @@ lxc_config_define(init_cmd);
lxc_config_define(init_cwd); lxc_config_define(init_cwd);
lxc_config_define(init_gid); lxc_config_define(init_gid);
lxc_config_define(init_uid); lxc_config_define(init_uid);
lxc_config_define(keyring_session);
lxc_config_define(log_file); lxc_config_define(log_file);
lxc_config_define(log_level); lxc_config_define(log_level);
lxc_config_define(log_syslog); lxc_config_define(log_syslog);
...@@ -136,6 +137,7 @@ lxc_config_define(seccomp_allow_nesting); ...@@ -136,6 +137,7 @@ lxc_config_define(seccomp_allow_nesting);
lxc_config_define(seccomp_notify_cookie); lxc_config_define(seccomp_notify_cookie);
lxc_config_define(seccomp_notify_proxy); lxc_config_define(seccomp_notify_proxy);
lxc_config_define(selinux_context); lxc_config_define(selinux_context);
lxc_config_define(selinux_context_keyring);
lxc_config_define(signal_halt); lxc_config_define(signal_halt);
lxc_config_define(signal_reboot); lxc_config_define(signal_reboot);
lxc_config_define(signal_stop); lxc_config_define(signal_stop);
...@@ -187,6 +189,7 @@ static struct lxc_config_t config_jump_table[] = { ...@@ -187,6 +189,7 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.init.gid", set_config_init_gid, get_config_init_gid, clr_config_init_gid, }, { "lxc.init.gid", set_config_init_gid, get_config_init_gid, clr_config_init_gid, },
{ "lxc.init.uid", set_config_init_uid, get_config_init_uid, clr_config_init_uid, }, { "lxc.init.uid", set_config_init_uid, get_config_init_uid, clr_config_init_uid, },
{ "lxc.init.cwd", set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, }, { "lxc.init.cwd", set_config_init_cwd, get_config_init_cwd, clr_config_init_cwd, },
{ "lxc.keyring.session", set_config_keyring_session, get_config_keyring_session, clr_config_keyring_session },
{ "lxc.log.file", set_config_log_file, get_config_log_file, clr_config_log_file, }, { "lxc.log.file", set_config_log_file, get_config_log_file, clr_config_log_file, },
{ "lxc.log.level", set_config_log_level, get_config_log_level, clr_config_log_level, }, { "lxc.log.level", set_config_log_level, get_config_log_level, clr_config_log_level, },
{ "lxc.log.syslog", set_config_log_syslog, get_config_log_syslog, clr_config_log_syslog, }, { "lxc.log.syslog", set_config_log_syslog, get_config_log_syslog, clr_config_log_syslog, },
...@@ -233,6 +236,7 @@ static struct lxc_config_t config_jump_table[] = { ...@@ -233,6 +236,7 @@ static struct lxc_config_t config_jump_table[] = {
{ "lxc.seccomp.notify.proxy", set_config_seccomp_notify_proxy, get_config_seccomp_notify_proxy, clr_config_seccomp_notify_proxy, }, { "lxc.seccomp.notify.proxy", set_config_seccomp_notify_proxy, get_config_seccomp_notify_proxy, clr_config_seccomp_notify_proxy, },
{ "lxc.seccomp.profile", set_config_seccomp_profile, get_config_seccomp_profile, clr_config_seccomp_profile, }, { "lxc.seccomp.profile", set_config_seccomp_profile, get_config_seccomp_profile, clr_config_seccomp_profile, },
{ "lxc.selinux.context", set_config_selinux_context, get_config_selinux_context, clr_config_selinux_context, }, { "lxc.selinux.context", set_config_selinux_context, get_config_selinux_context, clr_config_selinux_context, },
{ "lxc.selinux.context.keyring", set_config_selinux_context_keyring, get_config_selinux_context_keyring, clr_config_selinux_context_keyring },
{ "lxc.signal.halt", set_config_signal_halt, get_config_signal_halt, clr_config_signal_halt, }, { "lxc.signal.halt", set_config_signal_halt, get_config_signal_halt, clr_config_signal_halt, },
{ "lxc.signal.reboot", set_config_signal_reboot, get_config_signal_reboot, clr_config_signal_reboot, }, { "lxc.signal.reboot", set_config_signal_reboot, get_config_signal_reboot, clr_config_signal_reboot, },
{ "lxc.signal.stop", set_config_signal_stop, get_config_signal_stop, clr_config_signal_stop, }, { "lxc.signal.stop", set_config_signal_stop, get_config_signal_stop, clr_config_signal_stop, },
...@@ -1469,6 +1473,18 @@ static int set_config_selinux_context(const char *key, const char *value, ...@@ -1469,6 +1473,18 @@ static int set_config_selinux_context(const char *key, const char *value,
return set_config_string_item(&lxc_conf->lsm_se_context, value); return set_config_string_item(&lxc_conf->lsm_se_context, value);
} }
static int set_config_selinux_context_keyring(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
return set_config_string_item(&lxc_conf->lsm_se_keyring_context, value);
}
static int set_config_keyring_session(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data)
{
return set_config_bool_item(&lxc_conf->keyring_disable_session, value, false);
}
static int set_config_log_file(const char *key, const char *value, static int set_config_log_file(const char *key, const char *value,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
...@@ -2539,26 +2555,7 @@ static int set_config_rootfs_path(const char *key, const char *value, ...@@ -2539,26 +2555,7 @@ static int set_config_rootfs_path(const char *key, const char *value,
static int set_config_rootfs_managed(const char *key, const char *value, static int set_config_rootfs_managed(const char *key, const char *value,
struct lxc_conf *lxc_conf, void *data) struct lxc_conf *lxc_conf, void *data)
{ {
unsigned int val = 0; return set_config_bool_item(&lxc_conf->rootfs.managed, value, true);
if (lxc_config_value_empty(value)) {
lxc_conf->rootfs.managed = true;
return 0;
}
if (lxc_safe_uint(value, &val) < 0)
return -EINVAL;
switch (val) {
case 0:
lxc_conf->rootfs.managed = false;
return 0;
case 1:
lxc_conf->rootfs.managed = true;
return 0;
}
return -EINVAL;
} }
static int set_config_rootfs_mount(const char *key, const char *value, static int set_config_rootfs_mount(const char *key, const char *value,
...@@ -3539,6 +3536,19 @@ static int get_config_selinux_context(const char *key, char *retv, int inlen, ...@@ -3539,6 +3536,19 @@ static int get_config_selinux_context(const char *key, char *retv, int inlen,
return lxc_get_conf_str(retv, inlen, c->lsm_se_context); return lxc_get_conf_str(retv, inlen, c->lsm_se_context);
} }
static int get_config_selinux_context_keyring(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return lxc_get_conf_str(retv, inlen, c->lsm_se_keyring_context);
}
static int get_config_keyring_session(const char *key, char *retv, int inlen,
struct lxc_conf *c, void *data)
{
return lxc_get_conf_bool(c, retv, inlen, c->keyring_disable_session);
}
/* If you ask for a specific cgroup value, i.e. lxc.cgroup.devices.list, then /* If you ask for a specific cgroup value, i.e. lxc.cgroup.devices.list, then
* just the value(s) will be printed. Since there still could be more than one, * just the value(s) will be printed. Since there still could be more than one,
* it is newline-separated. * it is newline-separated.
...@@ -4405,6 +4415,21 @@ static inline int clr_config_selinux_context(const char *key, ...@@ -4405,6 +4415,21 @@ static inline int clr_config_selinux_context(const char *key,
return 0; return 0;
} }
static inline int clr_config_selinux_context_keyring(const char *key,
struct lxc_conf *c, void *data)
{
free(c->lsm_se_keyring_context);
c->lsm_se_keyring_context = NULL;
return 0;
}
static inline int clr_config_keyring_session(const char *key,
struct lxc_conf *c, void *data)
{
c->keyring_disable_session = false;
return 0;
}
static inline int clr_config_cgroup_controller(const char *key, static inline int clr_config_cgroup_controller(const char *key,
struct lxc_conf *c, void *data) struct lxc_conf *c, void *data)
{ {
...@@ -5951,6 +5976,7 @@ int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv, ...@@ -5951,6 +5976,7 @@ int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv,
strprint(retv, inlen, "dir\n"); strprint(retv, inlen, "dir\n");
} else if (!strcmp(key, "lxc.selinux")) { } else if (!strcmp(key, "lxc.selinux")) {
strprint(retv, inlen, "context\n"); strprint(retv, inlen, "context\n");
strprint(retv, inlen, "context.keyring\n");
} else if (!strcmp(key, "lxc.mount")) { } else if (!strcmp(key, "lxc.mount")) {
strprint(retv, inlen, "auto\n"); strprint(retv, inlen, "auto\n");
strprint(retv, inlen, "entry\n"); strprint(retv, inlen, "entry\n");
...@@ -5991,6 +6017,8 @@ int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv, ...@@ -5991,6 +6017,8 @@ int lxc_list_subkeys(struct lxc_conf *conf, const char *key, char *retv,
strprint(retv, inlen, "order\n"); strprint(retv, inlen, "order\n");
} else if (!strcmp(key, "lxc.monitor")) { } else if (!strcmp(key, "lxc.monitor")) {
strprint(retv, inlen, "unshare\n"); strprint(retv, inlen, "unshare\n");
} else if (!strcmp(key, "lxc.keyring")) {
strprint(retv, inlen, "session\n");
} else { } else {
fulllen = -1; fulllen = -1;
} }
......
...@@ -649,6 +649,30 @@ int set_config_path_item(char **conf_item, const char *value) ...@@ -649,6 +649,30 @@ int set_config_path_item(char **conf_item, const char *value)
return set_config_string_item_max(conf_item, value, PATH_MAX); return set_config_string_item_max(conf_item, value, PATH_MAX);
} }
int set_config_bool_item(bool *conf_item, const char *value, bool empty_conf_action)
{
unsigned int val = 0;
if (lxc_config_value_empty(value)) {
*conf_item = empty_conf_action;
return 0;
}
if (lxc_safe_uint(value, &val) < 0)
return -EINVAL;
switch (val) {
case 0:
*conf_item = false;
return 0;
case 1:
*conf_item = true;
return 0;
}
return -EINVAL;
}
int config_ip_prefix(struct in_addr *addr) int config_ip_prefix(struct in_addr *addr)
{ {
if (IN_CLASSA(addr->s_addr)) if (IN_CLASSA(addr->s_addr))
......
...@@ -51,6 +51,8 @@ extern int set_config_string_item(char **conf_item, const char *value); ...@@ -51,6 +51,8 @@ extern int set_config_string_item(char **conf_item, const char *value);
extern int set_config_string_item_max(char **conf_item, const char *value, extern int set_config_string_item_max(char **conf_item, const char *value,
size_t max); size_t max);
extern int set_config_path_item(char **conf_item, const char *value); extern int set_config_path_item(char **conf_item, const char *value);
extern int set_config_bool_item(bool *conf_item, const char *value,
bool empty_conf_action);
extern int config_ip_prefix(struct in_addr *addr); extern int config_ip_prefix(struct in_addr *addr);
extern int network_ifname(char *valuep, const char *value, size_t size); extern int network_ifname(char *valuep, const char *value, size_t size);
extern void rand_complete_hwaddr(char *hwaddr); extern void rand_complete_hwaddr(char *hwaddr);
......
...@@ -193,3 +193,16 @@ void lsm_process_cleanup(struct lxc_conf *conf, const char *lxcpath) ...@@ -193,3 +193,16 @@ void lsm_process_cleanup(struct lxc_conf *conf, const char *lxcpath)
drv->cleanup(conf, lxcpath); drv->cleanup(conf, lxcpath);
} }
int lsm_keyring_label_set(char *label) {
if (!drv) {
ERROR("LSM driver not inited");
return -1;
}
if (!drv->keyring_label_set)
return 0;
return drv->keyring_label_set(label);
}
...@@ -17,6 +17,7 @@ struct lsm_drv { ...@@ -17,6 +17,7 @@ struct lsm_drv {
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 on_exec); bool on_exec);
int (*keyring_label_set)(char* label);
int (*prepare)(struct lxc_conf *conf, const char *lxcpath); int (*prepare)(struct lxc_conf *conf, const char *lxcpath);
void (*cleanup)(struct lxc_conf *conf, const char *lxcpath); void (*cleanup)(struct lxc_conf *conf, const char *lxcpath);
}; };
...@@ -32,5 +33,6 @@ extern int lsm_process_label_fd_get(pid_t pid, bool on_exec); ...@@ -32,5 +33,6 @@ 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); extern void lsm_process_cleanup(struct lxc_conf *conf, const char *lxcpath);
extern int lsm_keyring_label_set(char *label);
#endif /* __LXC_LSM_H */ #endif /* __LXC_LSM_H */
...@@ -85,11 +85,24 @@ static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf, ...@@ -85,11 +85,24 @@ static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf,
return 0; return 0;
} }
/*
* selinux_keyring_label_set: Set SELinux context that will be assigned to the keyring
*
* @label : label string
*
* Returns 0 on success, < 0 on failure
*/
static int selinux_keyring_label_set(char *label)
{
return setkeycreatecon_raw(label);
};
static struct lsm_drv selinux_drv = { static struct lsm_drv selinux_drv = {
.name = "SELinux", .name = "SELinux",
.enabled = is_selinux_enabled, .enabled = is_selinux_enabled,
.process_label_get = selinux_process_label_get, .process_label_get = selinux_process_label_get,
.process_label_set = selinux_process_label_set, .process_label_set = selinux_process_label_set,
.keyring_label_set = selinux_keyring_label_set,
}; };
struct lsm_drv *lsm_selinux_drv_init(void) struct lsm_drv *lsm_selinux_drv_init(void)
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "config.h" #include "config.h"
#include "log.h" #include "log.h"
#include "lsm/lsm.h"
#include "lxclock.h" #include "lxclock.h"
#include "memory_utils.h" #include "memory_utils.h"
#include "namespace.h" #include "namespace.h"
...@@ -1835,11 +1836,17 @@ int recursive_destroy(const char *dirname) ...@@ -1835,11 +1836,17 @@ int recursive_destroy(const char *dirname)
return fret; return fret;
} }
int lxc_setup_keyring(void) int lxc_setup_keyring(char *keyring_label)
{ {
key_serial_t keyring; key_serial_t keyring;
int ret = 0; int ret = 0;
if (keyring_label) {
if (lsm_keyring_label_set(keyring_label) < 0) {
ERROR("Couldn't set keyring label");
}
}
/* Try to allocate a new session keyring for the container to prevent /* Try to allocate a new session keyring for the container to prevent
* information leaks. * information leaks.
*/ */
......
...@@ -232,6 +232,6 @@ extern uint64_t lxc_find_next_power2(uint64_t n); ...@@ -232,6 +232,6 @@ extern uint64_t lxc_find_next_power2(uint64_t n);
extern int lxc_set_death_signal(int signal, pid_t parent, int parent_status_fd); extern int lxc_set_death_signal(int signal, pid_t parent, int parent_status_fd);
extern int fd_cloexec(int fd, bool cloexec); extern int fd_cloexec(int fd, bool cloexec);
extern int recursive_destroy(const char *dirname); extern int recursive_destroy(const char *dirname);
extern int lxc_setup_keyring(void); extern int lxc_setup_keyring(char *keyring_label);
#endif /* __LXC_UTILS_H */ #endif /* __LXC_UTILS_H */
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