possible to determine what the correct size should be.
This option provides an override for these situations.
+ security= [SECURITY] Choose a security module to enable at boot.
+ If this boot parameter is not specified, only the first
+ security module asking for security registration will be
+ loaded. An invalid security module name will be treated
+ as if no module has been chosen.
+
capability.disable=
[SECURITY] Disable capabilities. This would normally
be used only if an alternative security model is to be
extern unsigned securebits;
+/* Maximum number of letters for an LSM name string */
+#define SECURITY_NAME_MAX 10
+
struct ctl_table;
struct audit_krule;
/**
* struct security_operations - main security structure
*
+ * Security module identifier.
+ *
+ * @name:
+ * A string that acts as a unique identifeir for the LSM with max number
+ * of characters = SECURITY_NAME_MAX.
+ *
* Security hooks for program execution operations.
*
* @bprm_alloc_security:
* This is the main security structure.
*/
struct security_operations {
+ char name[SECURITY_NAME_MAX + 1];
+
int (*ptrace) (struct task_struct * parent, struct task_struct * child);
int (*capget) (struct task_struct * target,
kernel_cap_t * effective,
/* prototypes */
extern int security_init (void);
+extern int security_module_enable(struct security_operations *ops);
extern int register_security (struct security_operations *ops);
extern int mod_reg_security (const char *name, struct security_operations *ops);
extern struct dentry *securityfs_create_file(const char *name, mode_t mode,
#endif /* CONFIG_AUDIT */
-struct security_operations dummy_security_ops;
+struct security_operations dummy_security_ops = {
+ .name = "dummy",
+};
#define set_to_dummy_if_null(ops, function) \
do { \
#include <linux/kernel.h>
#include <linux/security.h>
+/* Boot-time LSM user choice */
+static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1];
/* things that live in dummy.c */
extern struct security_operations dummy_security_ops;
return 0;
}
+/* Save user chosen LSM */
+static int __init choose_lsm(char *str)
+{
+ strncpy(chosen_lsm, str, SECURITY_NAME_MAX);
+ return 1;
+}
+__setup("security=", choose_lsm);
+
+/**
+ * security_module_enable - Load given security module on boot ?
+ * @ops: a pointer to the struct security_operations that is to be checked.
+ *
+ * Each LSM must pass this method before registering its own operations
+ * to avoid security registration races. This method may also be used
+ * to check if your LSM is currently loaded.
+ *
+ * Return true if:
+ * -The passed LSM is the one chosen by user at boot time,
+ * -or user didsn't specify a specific LSM and we're the first to ask
+ * for registeration permissoin,
+ * -or the passed LSM is currently loaded.
+ * Otherwise, return false.
+ */
+int __init security_module_enable(struct security_operations *ops)
+{
+ if (!*chosen_lsm)
+ strncpy(chosen_lsm, ops->name, SECURITY_NAME_MAX);
+ else if (strncmp(ops->name, chosen_lsm, SECURITY_NAME_MAX))
+ return 0;
+
+ return 1;
+}
+
/**
* 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.
+ * value passed to this function. You'll need to check first if your LSM
+ * is allowed to register its @ops by calling security_module_enable(@ops).
*
* If there is already a security module registered with the kernel,
* an error will be returned. Otherwise 0 is returned on success.
#endif
static struct security_operations selinux_ops = {
+ .name = "selinux",
+
.ptrace = selinux_ptrace,
.capget = selinux_capget,
.capset_check = selinux_capset_check,
{
struct task_security_struct *tsec;
+ if (!security_module_enable(&selinux_ops)) {
+ selinux_enabled = 0;
+ return 0;
+ }
+
if (!selinux_enabled) {
printk(KERN_INFO "SELinux: Disabled at boot.\n");
return 0;
#include <linux/capability.h>
#include <linux/spinlock.h>
+#include <linux/security.h>
#include <net/netlabel.h>
/*
extern struct smack_known smack_known_unset;
extern struct smk_list_entry *smack_list;
+extern struct security_operations smack_ops;
/*
* Stricly for CIPSO level manipulation.
{
}
-static struct security_operations smack_ops = {
+struct security_operations smack_ops = {
+ .name = "smack",
+
.ptrace = smack_ptrace,
.capget = cap_capget,
.capset_check = cap_capset_check,
*/
static __init int smack_init(void)
{
+ if (!security_module_enable(&smack_ops))
+ return 0;
+
printk(KERN_INFO "Smack: Initializing.\n");
/*
*
* register the smackfs
*
- * Returns 0 unless the registration fails.
+ * Do not register smackfs if Smack wasn't enabled
+ * on boot. We can not put this method normally under the
+ * smack_init() code path since the security subsystem get
+ * initialized before the vfs caches.
+ *
+ * Returns true if we were not chosen on boot or if
+ * we were chosen and filesystem registration succeeded.
*/
static int __init init_smk_fs(void)
{
int err;
+ if (!security_module_enable(&smack_ops))
+ return 0;
+
err = register_filesystem(&smk_fs_type);
if (!err) {
smackfs_mount = kern_mount(&smk_fs_type);