aboutsummaryrefslogtreecommitdiff
path: root/security/security.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/security.c')
-rw-r--r--security/security.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/security/security.c b/security/security.c
new file mode 100644
index 00000000000..ed5fb80769c
--- /dev/null
+++ b/security/security.c
@@ -0,0 +1,203 @@
+/*
+ * Security plug functions
+ *
+ * Copyright (C) 2001 WireX Communications, Inc <chris@wirex.com>
+ * Copyright (C) 2001-2002 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2001 Networks Associates Technology, Inc <ssmalley@nai.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/security.h>
+
+#define SECURITY_FRAMEWORK_VERSION "1.0.0"
+
+/* things that live in dummy.c */
+extern struct security_operations dummy_security_ops;
+extern void security_fixup_ops(struct security_operations *ops);
+
+struct security_operations *security_ops; /* Initialized to NULL */
+
+static inline int verify(struct security_operations *ops)
+{
+ /* verify the security_operations structure exists */
+ if (!ops)
+ return -EINVAL;
+ security_fixup_ops(ops);
+ return 0;
+}
+
+static void __init do_security_initcalls(void)
+{
+ initcall_t *call;
+ call = __security_initcall_start;
+ while (call < __security_initcall_end) {
+ (*call) ();
+ call++;
+ }
+}
+
+/**
+ * security_init - initializes the security framework
+ *
+ * This should be called early in the kernel initialization sequence.
+ */
+int __init security_init(void)
+{
+ printk(KERN_INFO "Security Framework v" SECURITY_FRAMEWORK_VERSION
+ " initialized\n");
+
+ if (verify(&dummy_security_ops)) {
+ printk(KERN_ERR "%s could not verify "
+ "dummy_security_ops structure.\n", __FUNCTION__);
+ return -EIO;
+ }
+
+ security_ops = &dummy_security_ops;
+ do_security_initcalls();
+
+ return 0;
+}
+
+/**
+ * register_security - registers a security framework with the kernel
+ * @ops: a pointer to the struct security_options that is to be registered
+ *
+ * This function is to allow a security module to register itself with the
+ * kernel security subsystem. Some rudimentary checking is done on the @ops
+ * value passed to this function. A call to unregister_security() should be
+ * done to remove this security_options structure from the kernel.
+ *
+ * If there is already a security module registered with the kernel,
+ * an error will be returned. Otherwise 0 is returned on success.
+ */
+int register_security(struct security_operations *ops)
+{
+ if (verify(ops)) {
+ printk(KERN_DEBUG "%s could not verify "
+ "security_operations structure.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ if (security_ops != &dummy_security_ops)
+ return -EAGAIN;
+
+ security_ops = ops;
+
+ return 0;
+}
+
+/**
+ * unregister_security - unregisters a security framework with the kernel
+ * @ops: a pointer to the struct security_options that is to be registered
+ *
+ * This function removes a struct security_operations variable that had
+ * previously been registered with a successful call to register_security().
+ *
+ * If @ops does not match the valued previously passed to register_security()
+ * an error is returned. Otherwise the default security options is set to the
+ * the dummy_security_ops structure, and 0 is returned.
+ */
+int unregister_security(struct security_operations *ops)
+{
+ if (ops != security_ops) {
+ printk(KERN_INFO "%s: trying to unregister "
+ "a security_opts structure that is not "
+ "registered, failing.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ security_ops = &dummy_security_ops;
+
+ return 0;
+}
+
+/**
+ * mod_reg_security - allows security modules to be "stacked"
+ * @name: a pointer to a string with the name of the security_options to be registered
+ * @ops: a pointer to the struct security_options that is to be registered
+ *
+ * This function allows security modules to be stacked if the currently loaded
+ * security module allows this to happen. It passes the @name and @ops to the
+ * register_security function of the currently loaded security module.
+ *
+ * The return value depends on the currently loaded security module, with 0 as
+ * success.
+ */
+int mod_reg_security(const char *name, struct security_operations *ops)
+{
+ if (verify(ops)) {
+ printk(KERN_INFO "%s could not verify "
+ "security operations.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ if (ops == security_ops) {
+ printk(KERN_INFO "%s security operations "
+ "already registered.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ return security_ops->register_security(name, ops);
+}
+
+/**
+ * mod_unreg_security - allows a security module registered with mod_reg_security() to be unloaded
+ * @name: a pointer to a string with the name of the security_options to be removed
+ * @ops: a pointer to the struct security_options that is to be removed
+ *
+ * This function allows security modules that have been successfully registered
+ * with a call to mod_reg_security() to be unloaded from the system.
+ * This calls the currently loaded security module's unregister_security() call
+ * with the @name and @ops variables.
+ *
+ * The return value depends on the currently loaded security module, with 0 as
+ * success.
+ */
+int mod_unreg_security(const char *name, struct security_operations *ops)
+{
+ if (ops == security_ops) {
+ printk(KERN_INFO "%s invalid attempt to unregister "
+ " primary security ops.\n", __FUNCTION__);
+ return -EINVAL;
+ }
+
+ return security_ops->unregister_security(name, ops);
+}
+
+/**
+ * capable - calls the currently loaded security module's capable() function with the specified capability
+ * @cap: the requested capability level.
+ *
+ * This function calls the currently loaded security module's capable()
+ * function with a pointer to the current task and the specified @cap value.
+ *
+ * This allows the security module to implement the capable function call
+ * however it chooses to.
+ */
+int capable(int cap)
+{
+ if (security_ops->capable(current, cap)) {
+ /* capability denied */
+ return 0;
+ }
+
+ /* capability granted */
+ current->flags |= PF_SUPERPRIV;
+ return 1;
+}
+
+EXPORT_SYMBOL_GPL(register_security);
+EXPORT_SYMBOL_GPL(unregister_security);
+EXPORT_SYMBOL_GPL(mod_reg_security);
+EXPORT_SYMBOL_GPL(mod_unreg_security);
+EXPORT_SYMBOL(capable);
+EXPORT_SYMBOL(security_ops);