LSM: Add /sys/kernel/security/lsm

I am still tired of having to find indirect ways to determine
what security modules are active on a system. I have added
/sys/kernel/security/lsm, which contains a comma separated
list of the active security modules. No more groping around
in /proc/filesystems or other clever hacks.

Unchanged from previous versions except for being updated
to the latest security next branch.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: James Morris <james.l.morris@oracle.com>
This commit is contained in:
Casey Schaufler 2017-01-18 17:09:05 -08:00 коммит произвёл James Morris
Родитель 3ccb76c5df
Коммит d69dece5f5
11 изменённых файлов: 82 добавлений и 17 удалений

Просмотреть файл

@ -22,6 +22,13 @@ system, building their checks on top of the defined capability hooks.
For more details on capabilities, see capabilities(7) in the Linux
man-pages project.
A list of the active security modules can be found by reading
/sys/kernel/security/lsm. This is a comma separated list, and
will always include the capability module. The list reflects the
order in which checks are made. The capability module will always
be first, followed by any "minor" modules (e.g. Yama) and then
the one "major" module (e.g. SELinux) if there is one configured.
Based on https://lkml.org/lkml/2007/10/26/215,
a new LSM is accepted into the kernel when its intent (a description of
what it tries to protect against and in what cases one would expect to

Просмотреть файл

@ -1875,6 +1875,7 @@ struct security_hook_list {
struct list_head list;
struct list_head *head;
union security_list_options hook;
char *lsm;
};
/*
@ -1887,15 +1888,10 @@ struct security_hook_list {
{ .head = &security_hook_heads.HEAD, .hook = { .HEAD = HOOK } }
extern struct security_hook_heads security_hook_heads;
extern char *lsm_names;
static inline void security_add_hooks(struct security_hook_list *hooks,
int count)
{
int i;
for (i = 0; i < count; i++)
list_add_tail_rcu(&hooks[i].list, hooks[i].head);
}
extern void security_add_hooks(struct security_hook_list *hooks, int count,
char *lsm);
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
/*

Просмотреть файл

@ -999,7 +999,8 @@ static int __init apparmor_init(void)
aa_free_root_ns();
goto buffers_out;
}
security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks));
security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks),
"apparmor");
/* Report that AppArmor successfully initialized */
apparmor_initialized = 1;

Просмотреть файл

@ -1093,7 +1093,8 @@ struct security_hook_list capability_hooks[] = {
void __init capability_add_hooks(void)
{
security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks));
security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks),
"capability");
}
#endif /* CONFIG_SECURITY */

Просмотреть файл

@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/namei.h>
#include <linux/security.h>
#include <linux/lsm_hooks.h>
#include <linux/magic.h>
static struct vfsmount *mount;
@ -204,6 +205,21 @@ void securityfs_remove(struct dentry *dentry)
}
EXPORT_SYMBOL_GPL(securityfs_remove);
#ifdef CONFIG_SECURITY
static struct dentry *lsm_dentry;
static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count,
loff_t *ppos)
{
return simple_read_from_buffer(buf, count, ppos, lsm_names,
strlen(lsm_names));
}
static const struct file_operations lsm_ops = {
.read = lsm_read,
.llseek = generic_file_llseek,
};
#endif
static int __init securityfs_init(void)
{
int retval;
@ -213,9 +229,15 @@ static int __init securityfs_init(void)
return retval;
retval = register_filesystem(&fs_type);
if (retval)
if (retval) {
sysfs_remove_mount_point(kernel_kobj, "security");
return retval;
return retval;
}
#ifdef CONFIG_SECURITY
lsm_dentry = securityfs_create_file("lsm", 0444, NULL, NULL,
&lsm_ops);
#endif
return 0;
}
core_initcall(securityfs_init);

Просмотреть файл

@ -182,7 +182,7 @@ static struct security_hook_list loadpin_hooks[] = {
void __init loadpin_add_hooks(void)
{
pr_info("ready to pin (currently %sabled)", enabled ? "en" : "dis");
security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks));
security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin");
}
/* Should not be mutable after boot, so not listed in sysfs (perm == 0). */

Просмотреть файл

@ -32,6 +32,7 @@
/* Maximum number of letters for an LSM name string */
#define SECURITY_NAME_MAX 10
char *lsm_names;
/* Boot-time LSM user choice */
static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
CONFIG_DEFAULT_SECURITY;
@ -78,6 +79,22 @@ static int __init choose_lsm(char *str)
}
__setup("security=", choose_lsm);
static int lsm_append(char *new, char **result)
{
char *cp;
if (*result == NULL) {
*result = kstrdup(new, GFP_KERNEL);
} else {
cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new);
if (cp == NULL)
return -ENOMEM;
kfree(*result);
*result = cp;
}
return 0;
}
/**
* security_module_enable - Load given security module on boot ?
* @module: the name of the module
@ -97,6 +114,27 @@ int __init security_module_enable(const char *module)
return !strcmp(module, chosen_lsm);
}
/**
* security_add_hooks - Add a modules hooks to the hook lists.
* @hooks: the hooks to add
* @count: the number of hooks to add
* @lsm: the name of the security module
*
* Each LSM has to register its hooks with the infrastructure.
*/
void __init security_add_hooks(struct security_hook_list *hooks, int count,
char *lsm)
{
int i;
for (i = 0; i < count; i++) {
hooks[i].lsm = lsm;
list_add_tail_rcu(&hooks[i].list, hooks[i].head);
}
if (lsm_append(lsm, &lsm_names) < 0)
panic("%s - Cannot get early memory.\n", __func__);
}
/*
* Hook list operation macros.
*

Просмотреть файл

@ -6349,7 +6349,7 @@ static __init int selinux_init(void)
0, SLAB_PANIC, NULL);
avc_init();
security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));
security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux");
if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
panic("SELinux: Unable to register AVC netcache callback\n");

Просмотреть файл

@ -4819,7 +4819,7 @@ static __init int smack_init(void)
/*
* Register with LSM
*/
security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks));
security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack");
return 0;
}

Просмотреть файл

@ -542,7 +542,7 @@ static int __init tomoyo_init(void)
if (!security_module_enable("tomoyo"))
return 0;
/* register ourselves with the security framework */
security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks));
security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo");
printk(KERN_INFO "TOMOYO Linux initialized\n");
cred->security = &tomoyo_kernel_domain;
tomoyo_mm_init();

Просмотреть файл

@ -485,6 +485,6 @@ static inline void yama_init_sysctl(void) { }
void __init yama_add_hooks(void)
{
pr_info("Yama: becoming mindful.\n");
security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks));
security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama");
yama_init_sysctl();
}