lkml.org 
[lkml]   [2008]   [Apr]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH 11/12] Security: Introduce security= boot parameter

    --- James Morris <jmorris@namei.org> wrote:

    > From: Ahmed S. Darwish <darwish.07@gmail.com>
    >
    > Add the security= boot parameter. This is done to avoid LSM
    > registration clashes in case of more than one bult-in module.
    >
    > User can choose a security module to enable at boot. If no
    > security= boot parameter is specified, only the first LSM
    > asking for registration will be loaded. An invalid security
    > module name will be treated as if no module has been chosen.
    >
    > LSM modules must check now if they are allowed to register
    > by calling security_module_enable(ops) first. Modify SELinux
    > and SMACK to do so.
    >
    > Do not let SMACK register smackfs if it was not chosen on
    > boot. Smackfs assumes that smack hooks are registered and
    > the initial task security setup (swapper->security) is done.
    >
    > Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
    > Acked-by: James Morris <jmorris@namei.org>

    Acked-by: Casey Schaufler <casey@schaufler-ca.com>

    > ---
    > Documentation/kernel-parameters.txt | 6 +++++
    > include/linux/security.h | 12 +++++++++++
    > security/dummy.c | 4 ++-
    > security/security.c | 38
    > ++++++++++++++++++++++++++++++++++-
    > security/selinux/hooks.c | 7 ++++++
    > security/smack/smack.h | 2 +
    > security/smack/smack_lsm.c | 7 +++++-
    > security/smack/smackfs.c | 11 +++++++++-
    > 8 files changed, 83 insertions(+), 4 deletions(-)
    >
    > diff --git a/Documentation/kernel-parameters.txt
    > b/Documentation/kernel-parameters.txt
    > index dafd001..436790f 100644
    > --- a/Documentation/kernel-parameters.txt
    > +++ b/Documentation/kernel-parameters.txt
    > @@ -366,6 +366,12 @@ and is between 256 and 4096 characters. It is defined in
    > the file
    > 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
    > diff --git a/include/linux/security.h b/include/linux/security.h
    > index 697f228..f4116d6 100644
    > --- a/include/linux/security.h
    > +++ b/include/linux/security.h
    > @@ -36,6 +36,9 @@
    >
    > extern unsigned securebits;
    >
    > +/* Maximum number of letters for an LSM name string */
    > +#define SECURITY_NAME_MAX 10
    > +
    > struct ctl_table;
    > struct audit_krule;
    >
    > @@ -137,6 +140,12 @@ static inline void security_free_mnt_opts(struct
    > security_mnt_opts *opts)
    > /**
    > * 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:
    > @@ -1270,6 +1279,8 @@ static inline void security_free_mnt_opts(struct
    > security_mnt_opts *opts)
    > * 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,
    > @@ -1537,6 +1548,7 @@ struct security_operations {
    >
    > /* 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,
    > diff --git a/security/dummy.c b/security/dummy.c
    > index 1ac9f8e..374d2ae 100644
    > --- a/security/dummy.c
    > +++ b/security/dummy.c
    > @@ -1017,7 +1017,9 @@ static inline void dummy_audit_rule_free(void *lsmrule)
    >
    > #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 { \
    > diff --git a/security/security.c b/security/security.c
    > index bf189d2..2ed153c 100644
    > --- a/security/security.c
    > +++ b/security/security.c
    > @@ -17,6 +17,8 @@
    > #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;
    > @@ -67,13 +69,47 @@ int __init security_init(void)
    > 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.
    > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
    > index afbaa07..44741ac 100644
    > --- a/security/selinux/hooks.c
    > +++ b/security/selinux/hooks.c
    > @@ -5252,6 +5252,8 @@ static int selinux_key_permission(key_ref_t key_ref,
    > #endif
    >
    > static struct security_operations selinux_ops = {
    > + .name = "selinux",
    > +
    > .ptrace = selinux_ptrace,
    > .capget = selinux_capget,
    > .capset_check = selinux_capset_check,
    > @@ -5449,6 +5451,11 @@ static __init int selinux_init(void)
    > {
    > 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;
    > diff --git a/security/smack/smack.h b/security/smack/smack.h
    > index 62c1e98..4a4477f 100644
    > --- a/security/smack/smack.h
    > +++ b/security/smack/smack.h
    > @@ -15,6 +15,7 @@
    >
    > #include <linux/capability.h>
    > #include <linux/spinlock.h>
    > +#include <linux/security.h>
    > #include <net/netlabel.h>
    >
    > /*
    > @@ -187,6 +188,7 @@ extern struct smack_known smack_known_star;
    > 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.
    > diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
    > index 732ba27..904bdc0 100644
    > --- a/security/smack/smack_lsm.c
    > +++ b/security/smack/smack_lsm.c
    > @@ -2424,7 +2424,9 @@ static void smack_release_secctx(char *secdata, u32
    > seclen)
    > {
    > }
    >
    > -static struct security_operations smack_ops = {
    > +struct security_operations smack_ops = {
    > + .name = "smack",
    > +
    > .ptrace = smack_ptrace,
    > .capget = cap_capget,
    > .capset_check = cap_capset_check,
    > @@ -2557,6 +2559,9 @@ static struct security_operations smack_ops = {
    > */
    > static __init int smack_init(void)
    > {
    > + if (!security_module_enable(&smack_ops))
    > + return 0;
    > +
    > printk(KERN_INFO "Smack: Initializing.\n");
    >
    > /*
    > diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
    > index cfae8af..6ba2837 100644
    > --- a/security/smack/smackfs.c
    > +++ b/security/smack/smackfs.c
    > @@ -965,12 +965,21 @@ static struct vfsmount *smackfs_mount;
    > *
    > * 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);
    > --
    > 1.5.4.2
    >
    > --
    > To unsubscribe from this list: send the line "unsubscribe
    > linux-security-module" in
    > the body of a message to majordomo@vger.kernel.org
    > More majordomo info at http://vger.kernel.org/majordomo-info.html
    >
    >
    >


    Casey Schaufler
    casey@schaufler-ca.com


    \
     
     \ /
      Last update: 2008-04-17 17:33    [W:0.041 / U:123.752 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site