specific changes to system operation when these tweaks are not available
in the core functionality of Linux itself.
-The Linux capabilities modules will always be included. This may be
-followed by any number of "minor" modules and at most one "major" module.
-For more details on capabilities, see ``capabilities(7)`` in the Linux
-man-pages project.
+The Linux capabilities modules will always be included. For more details
+on capabilities, see ``capabilities(7)`` in the Linux man-pages project.
+
+Security modules that do not use the security data blobs maintained
+by the LSM infrastructure are considered "minor" modules. These may be
+included at compile time and stacked explicitly. Security modules that
+use the LSM maintained security blobs are considered "major" modules.
+These may only be stacked if the CONFIG_LSM_STACKED configuration
+option is used. If this is chosen all of the security modules selected
+will be used.
A list of the active security modules can be found by reading
``/sys/kernel/security/lsm``. This is a comma separated list, and
#define __lsm_ro_after_init __ro_after_init
#endif /* CONFIG_SECURITY_WRITABLE_HOOKS */
-extern int __init security_module_enable(const char *module);
+extern bool __init security_module_enable(const char *lsm, const bool stacked);
extern void __init capability_add_hooks(void);
#ifdef CONFIG_SECURITY_YAMA
extern void __init yama_add_hooks(void);
bool
default n
+config SECURITY_STACKING
+ bool "Security module stacking"
+ depends on SECURITY
+ help
+ Allows multiple major security modules to be stacked.
+ Modules are invoked in the order registered with a
+ "bail on fail" policy, in which the infrastructure
+ will stop processing once a denial is detected. Not
+ all modules can be stacked. SELinux and Smack are
+ known to be incompatible. User space components may
+ have trouble identifying the security module providing
+ data in some cases.
+
+ If you select this option you will have to select which
+ of the stackable modules you wish to be active. The
+ "Default security module" will be ignored. The boot line
+ "security=" option can be used to specify that one of
+ the modules identifed for stacking should be used instead
+ of the entire stack.
+
+ If you are unsure how to answer this question, answer N.
+
config SECURITY_LSM_DEBUG
bool "Enable debugging of the LSM infrastructure"
depends on SECURITY
source security/integrity/Kconfig
+menu "Security Module Selection"
+ visible if !SECURITY_STACKING
+
choice
prompt "Default security module"
default DEFAULT_SECURITY_SELINUX if SECURITY_SELINUX
endmenu
+menu "Security Module Stack"
+ visible if SECURITY_STACKING
+
+choice
+ prompt "Stacked 'extreme' security module"
+ default SECURITY_SELINUX_STACKED if SECURITY_SELINUX
+ default SECURITY_SMACK_STACKED if SECURITY_SMACK
+ default SECURITY_APPARMOR_STACKED if SECURITY_APPARMOR
+
+ help
+ Enable an extreme security module. These modules cannot
+ be used at the same time.
+
+ config SECURITY_SELINUX_STACKED
+ bool "SELinux" if SECURITY_SELINUX=y
+ help
+ This option instructs the system to use the SELinux checks.
+ At this time the Smack security module is incompatible with this
+ module.
+ At this time the AppArmor security module is incompatible with this
+ module.
+
+ config SECURITY_SMACK_STACKED
+ bool "Simplified Mandatory Access Control" if SECURITY_SMACK=y
+ help
+ This option instructs the system to use the Smack checks.
+ At this time the SELinux security module is incompatible with this
+ module.
+ At this time the AppArmor security module is incompatible with this
+ module.
+
+ config SECURITY_APPARMOR_STACKED
+ bool "AppArmor" if SECURITY_APPARMOR=y
+ help
+ This option instructs the system to use the AppArmor checks.
+ At this time the SELinux security module is incompatible with this
+ module.
+ At this time the Smack security module is incompatible with this
+ module.
+
+ config SECURITY_NOTHING_STACKED
+ bool "Use no 'extreme' security module"
+ help
+ Use none of the SELinux, Smack or AppArmor security module.
+
+endchoice
+
+config SECURITY_TOMOYO_STACKED
+ bool "TOMOYO support is enabled by default"
+ depends on SECURITY_TOMOYO && SECURITY_STACKING
+ default n
+ help
+ This option instructs the system to use the TOMOYO checks.
+ If not selected the module will not be invoked.
+ Stacked security modules may interact in unexpected ways.
+
+ If you are unsure how to answer this question, answer N.
+
+endmenu
+
+endmenu
int aa_restore_previous_label(u64 cookie);
struct aa_label *aa_get_task_label(struct task_struct *task);
+extern struct lsm_blob_sizes apparmor_blob_sizes;
+
static inline struct aa_task_ctx *apparmor_cred(const struct cred *cred)
{
+#ifdef CONFIG_SECURITY_STACKING
+ return cred->security + apparmor_blob_sizes.lbs_cred;
+#else
return cred->security;
+#endif
}
/**
static inline struct aa_file_ctx *apparmor_file(const struct file *file)
{
+#ifdef CONFIG_SECURITY_STACKING
+ return file->f_security + apparmor_blob_sizes.lbs_file;
+#else
return file->f_security;
+#endif
}
/**
int error;
if (!finish) {
- if (apparmor_enabled && security_module_enable("apparmor"))
+ if (apparmor_enabled &&
+ security_module_enable("apparmor",
+ IS_ENABLED(CONFIG_SECURITY_APPARMOR_STACKED)))
security_add_blobs(&apparmor_blob_sizes);
else
apparmor_enabled = false;
return 0;
}
- if (!apparmor_enabled || !security_module_enable("apparmor")) {
+ if (!apparmor_enabled ||
+ !security_module_enable("apparmor",
+ IS_ENABLED(CONFIG_SECURITY_APPARMOR_STACKED))) {
aa_info_message("AppArmor disabled by boot time parameter");
apparmor_enabled = false;
return 0;
/* Maximum number of letters for an LSM name string */
#define SECURITY_NAME_MAX 10
+#define MODULE_STACK "(stacking)"
struct security_hook_heads security_hook_heads __lsm_ro_after_init;
static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
/* Boot-time LSM user choice */
static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
+#ifdef CONFIG_SECURITY_STACKING
+ MODULE_STACK;
+#else
CONFIG_DEFAULT_SECURITY;
+#endif
static void __init do_security_initcalls(void)
{
/**
* security_module_enable - Load given security module on boot ?
* @module: the name of the module
+ * @stacked: indicates that the module wants to be stacked
*
* Each LSM must pass this method before registering its own operations
* to avoid security registration races. This method may also be used
*
* Otherwise, return false.
*/
-int __init security_module_enable(const char *module)
+bool __init security_module_enable(const char *lsm, const bool stacked)
{
- return !strcmp(module, chosen_lsm);
+#ifdef CONFIG_SECURITY_STACKING
+ /*
+ * Module defined on the command line security=XXXX
+ */
+ if (strcmp(chosen_lsm, MODULE_STACK)) {
+ if (!strcmp(lsm, chosen_lsm)) {
+ pr_info("Command line sets the %s security module.\n",
+ lsm);
+ return true;
+ }
+ return false;
+ }
+ /*
+ * Module configured as stacked.
+ */
+ return stacked;
+#else
+ if (strcmp(lsm, chosen_lsm) == 0)
+ return true;
+ return false;
+#endif
}
/**
{
static int finish;
- if (!security_module_enable("selinux")) {
+ if (!security_module_enable("selinux",
+ IS_ENABLED(CONFIG_SECURITY_SELINUX_STACKED))) {
selinux_enabled = 0;
return 0;
}
static inline struct task_security_struct *selinux_cred(const struct cred *cred)
{
+#ifdef CONFIG_SECURITY_STACKING
+ return cred->security + selinux_blob_sizes.lbs_cred;
+#else
return cred->security;
+#endif
}
static inline struct file_security_struct *selinux_file(const struct file *file)
{
+#ifdef CONFIG_SECURITY_STACKING
+ return file->f_security + selinux_blob_sizes.lbs_file;
+#else
return file->f_security;
+#endif
}
static inline struct inode_security_struct *selinux_inode(
extern struct smack_known *smack_unconfined;
#endif
extern int smack_ptrace_rule;
+extern struct lsm_blob_sizes smack_blob_sizes;
extern struct smack_known smack_known_floor;
extern struct smack_known smack_known_hat;
static inline struct task_smack *smack_cred(const struct cred *cred)
{
+#ifdef CONFIG_SECURITY_STACKING
+ return cred->security + smack_blob_sizes.lbs_cred;
+#else
return cred->security;
+#endif
}
static inline struct smack_known **smack_file(const struct file *file)
{
+#ifdef CONFIG_SECURITY_STACKING
+ return file->f_security + smack_blob_sizes.lbs_file;
+#else
return file->f_security;
+#endif
}
static inline struct inode_smack *smack_inode(const struct inode *inode)
{
struct smack_known *skp = smk_of_task_struct(p);
char *cp;
- int slen;
- if (strcmp(name, "current") != 0)
+ if (strcmp(name, "current") == 0) {
+ cp = kstrdup(skp->smk_known, GFP_KERNEL);
+ if (cp == NULL)
+ return -ENOMEM;
+ } else
return -EINVAL;
- cp = kstrdup(skp->smk_known, GFP_KERNEL);
- if (cp == NULL)
- return -ENOMEM;
-
- slen = strlen(cp);
*value = cp;
- return slen;
+ return strlen(cp);
}
/**
struct cred *cred = (struct cred *) current->cred;
struct task_smack *tsp;
- if (!security_module_enable("smack"))
+ if (!security_module_enable("smack",
+ IS_ENABLED(CONFIG_SECURITY_SMACK_STACKED)))
return 0;
if (!finish) {
extern struct tomoyo_policy_namespace tomoyo_kernel_namespace;
extern unsigned int tomoyo_memory_quota[TOMOYO_MAX_MEMORY_STAT];
extern unsigned int tomoyo_memory_used[TOMOYO_MAX_MEMORY_STAT];
+extern struct lsm_blob_sizes tomoyo_blob_sizes;
/********** Inlined functions. **********/
*/
static inline struct tomoyo_domain_info **tomoyo_cred(const struct cred *cred)
{
+#ifdef CONFIG_SECURITY_STACKING
+ return cred->security + tomoyo_blob_sizes.lbs_cred;
+#else
return cred->security;
+#endif
}
/**
*/
static inline struct tomoyo_domain_info *tomoyo_domain(void)
{
- struct tomoyo_domain_info **blob = tomoyo_cred(current_cred());
+ const struct cred *cred = current_cred();
+ struct tomoyo_domain_info **blob;
+
+ if (cred->security == NULL)
+ return NULL;
+ blob = tomoyo_cred(cred);
return *blob;
}
struct cred *cred = (struct cred *) current_cred();
struct tomoyo_domain_info **blob;
- if (!security_module_enable("tomoyo")) {
+ if (!security_module_enable("tomoyo",
+ IS_ENABLED(CONFIG_SECURITY_TOMOYO_STACKED))) {
tomoyo_enabled = false;
return 0;
}