summaryrefslogtreecommitdiff
path: root/security/security.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/security.c')
-rw-r--r--security/security.c66
1 files changed, 49 insertions, 17 deletions
diff --git a/security/security.c b/security/security.c
index 68f46d849abe..04d173eb93f6 100644
--- a/security/security.c
+++ b/security/security.c
@@ -12,6 +12,8 @@
* (at your option) any later version.
*/
+#define pr_fmt(fmt) "LSM: " fmt
+
#include <linux/bpf.h>
#include <linux/capability.h>
#include <linux/dcache.h>
@@ -30,8 +32,6 @@
#include <linux/string.h>
#include <net/flow.h>
-#include <trace/events/initcall.h>
-
#define MAX_LSM_EVM_XATTR 2
/* Maximum number of letters for an LSM name string */
@@ -45,17 +45,22 @@ char *lsm_names;
static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
CONFIG_DEFAULT_SECURITY;
-static void __init do_security_initcalls(void)
+static __initdata bool debug;
+#define init_debug(...) \
+ do { \
+ if (debug) \
+ pr_info(__VA_ARGS__); \
+ } while (0)
+
+static void __init major_lsm_init(void)
{
+ struct lsm_info *lsm;
int ret;
- initcall_t *call;
- call = __security_initcall_start;
- trace_initcall_level("security");
- while (call < __security_initcall_end) {
- trace_initcall_start((*call));
- ret = (*call) ();
- trace_initcall_finish((*call), ret);
- call++;
+
+ for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
+ init_debug("initializing %s\n", lsm->name);
+ ret = lsm->init();
+ WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
}
}
@@ -69,10 +74,11 @@ int __init security_init(void)
int i;
struct hlist_head *list = (struct hlist_head *) &security_hook_heads;
+ pr_info("Security Framework initializing\n");
+
for (i = 0; i < sizeof(security_hook_heads) / sizeof(struct hlist_head);
i++)
INIT_HLIST_HEAD(&list[i]);
- pr_info("Security Framework initialized\n");
/*
* Load minor LSMs, with the capability module always first.
@@ -84,7 +90,7 @@ int __init security_init(void)
/*
* Load all the remaining security modules.
*/
- do_security_initcalls();
+ major_lsm_init();
return 0;
}
@@ -97,6 +103,14 @@ static int __init choose_lsm(char *str)
}
__setup("security=", choose_lsm);
+/* Enable LSM order debugging. */
+static int __init enable_debug(char *str)
+{
+ debug = true;
+ return 1;
+}
+__setup("lsm.debug", enable_debug);
+
static bool match_last_lsm(const char *list, const char *lsm)
{
const char *last;
@@ -118,6 +132,8 @@ static int lsm_append(char *new, char **result)
if (*result == NULL) {
*result = kstrdup(new, GFP_KERNEL);
+ if (*result == NULL)
+ return -ENOMEM;
} else {
/* Check if it is the last registered name */
if (match_last_lsm(*result, new))
@@ -970,11 +986,11 @@ int security_file_receive(struct file *file)
return call_int_hook(file_receive, 0, file);
}
-int security_file_open(struct file *file, const struct cred *cred)
+int security_file_open(struct file *file)
{
int ret;
- ret = call_int_hook(file_open, 0, file, cred);
+ ret = call_int_hook(file_open, 0, file);
if (ret)
return ret;
@@ -1030,7 +1046,12 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode)
int security_kernel_module_request(char *kmod_name)
{
- return call_int_hook(kernel_module_request, 0, kmod_name);
+ int ret;
+
+ ret = call_int_hook(kernel_module_request, 0, kmod_name);
+ if (ret)
+ return ret;
+ return integrity_kernel_module_request(kmod_name);
}
int security_kernel_read_file(struct file *file, enum kernel_read_file_id id)
@@ -1056,6 +1077,17 @@ int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
}
EXPORT_SYMBOL_GPL(security_kernel_post_read_file);
+int security_kernel_load_data(enum kernel_load_data_id id)
+{
+ int ret;
+
+ ret = call_int_hook(kernel_load_data, 0, id);
+ if (ret)
+ return ret;
+ return ima_load_data(id);
+}
+EXPORT_SYMBOL_GPL(security_kernel_load_data);
+
int security_task_fix_setuid(struct cred *new, const struct cred *old,
int flags)
{
@@ -1126,7 +1158,7 @@ int security_task_movememory(struct task_struct *p)
return call_int_hook(task_movememory, 0, p);
}
-int security_task_kill(struct task_struct *p, struct siginfo *info,
+int security_task_kill(struct task_struct *p, struct kernel_siginfo *info,
int sig, const struct cred *cred)
{
return call_int_hook(task_kill, 0, p, info, sig, cred);