Hi, I'm wondering what reaction is to the following patch. It adds a struct module to the parameters sent in through mod_reg_security. This is useful for stacker as it allows it to refuse unloading of LSMs. Then, when you echo module_name > /security/stacker/unload, the module is removed from the list of modules, and we module_put(mod), so that now it is possible to unload the module. This should guarantee that none of the lsms's hooks are being called while the module is being deleted. This is a zero performance cost solution to module deletion under stacker. Paul McKenney has suggested an alternative solution which should do worse than this, but better than my previous rcu-refcounting approach. Please let me know if there are comments on this patch. thanks, -serge Signed-off-by: Serge Hallyn <serue@private> -- include/linux/security.h | 9 +++++++-- security/capability.c | 2 +- security/dummy.c | 4 +++- security/root_plug.c | 3 ++- security/seclvl.c | 2 +- security/security.c | 6 ++++-- security/selinux/hooks.c | 4 +++- 7 files changed, 21 insertions(+), 9 deletions(-) Index: linux-2.6.13-rc3/include/linux/security.h =================================================================== --- linux-2.6.13-rc3.orig/include/linux/security.h 2005-06-17 14:48:29.000000000 -0500 +++ linux-2.6.13-rc3/include/linux/security.h 2005-07-15 20:17:14.000000000 -0500 @@ -32,6 +32,7 @@ #include <linux/sched.h> struct ctl_table; +struct module; /* * These functions are in security/capability.c and are used @@ -1019,6 +1020,7 @@ struct swap_info_struct; * allow module stacking. * @name contains the name of the security module being stacked. * @ops contains a pointer to the struct security_operations of the module to stack. + * @owner is a pointer to the owning module, or NULL if built-in. * @unregister_security: * remove a stacked module. * @name contains the name of the security module being unstacked. @@ -1204,7 +1206,8 @@ struct security_operations { /* allow module stacking */ int (*register_security) (const char *name, - struct security_operations *ops); + struct security_operations *ops, + struct module *owner); int (*unregister_security) (const char *name, struct security_operations *ops); @@ -1981,7 +1984,9 @@ static inline int security_netlink_recv( extern int security_init (void); extern int register_security (struct security_operations *ops); extern int unregister_security (struct security_operations *ops); -extern int mod_reg_security (const char *name, struct security_operations *ops); +extern int mod_reg_security (const char *name, + struct security_operations *ops, + struct module *owner); extern int mod_unreg_security (const char *name, struct security_operations *ops); Index: linux-2.6.13-rc3/security/capability.c =================================================================== --- linux-2.6.13-rc3.orig/security/capability.c 2005-06-17 14:48:29.000000000 -0500 +++ linux-2.6.13-rc3/security/capability.c 2005-07-15 20:21:44.000000000 -0500 @@ -67,7 +67,7 @@ static int __init capability_init (void) /* register ourselves with the security framework */ if (register_security (&capability_ops)) { /* try registering with primary module */ - if (mod_reg_security (MY_NAME, &capability_ops)) { + if (mod_reg_security (MY_NAME, &capability_ops, THIS_MODULE)) { printk (KERN_INFO "Failure registering capabilities " "with primary security module.\n"); return -EINVAL; Index: linux-2.6.13-rc3/security/dummy.c =================================================================== --- linux-2.6.13-rc3.orig/security/dummy.c 2005-07-15 19:03:49.000000000 -0500 +++ linux-2.6.13-rc3/security/dummy.c 2005-07-15 20:22:04.000000000 -0500 @@ -811,7 +811,9 @@ static inline void dummy_sk_free_securit } #endif /* CONFIG_SECURITY_NETWORK */ -static int dummy_register_security (const char *name, struct security_operations *ops) +static int dummy_register_security (const char *name, + struct security_operations *ops, + struct module *owner) { return -EINVAL; } Index: linux-2.6.13-rc3/security/root_plug.c =================================================================== --- linux-2.6.13-rc3.orig/security/root_plug.c 2005-06-17 14:48:29.000000000 -0500 +++ linux-2.6.13-rc3/security/root_plug.c 2005-07-15 20:23:45.000000000 -0500 @@ -106,7 +106,8 @@ static int __init rootplug_init (void) printk (KERN_INFO "Failure registering Root Plug module with the kernel\n"); /* try registering with primary module */ - if (mod_reg_security (MY_NAME, &rootplug_security_ops)) { + if (mod_reg_security (MY_NAME, &rootplug_security_ops, + THIS_MODULE)) { printk (KERN_INFO "Failure registering Root Plug " " module with primary security module.\n"); return -EINVAL; Index: linux-2.6.13-rc3/security/seclvl.c =================================================================== --- linux-2.6.13-rc3.orig/security/seclvl.c 2005-07-15 19:03:49.000000000 -0500 +++ linux-2.6.13-rc3/security/seclvl.c 2005-07-15 20:24:08.000000000 -0500 @@ -697,7 +697,7 @@ static int __init seclvl_init(void) "seclvl: Failure registering with the " "kernel.\n"); /* try registering with primary module */ - rc = mod_reg_security(MY_NAME, &seclvl_ops); + rc = mod_reg_security(MY_NAME, &seclvl_ops, THIS_MODULE); if (rc) { seclvl_printk(0, KERN_ERR, "seclvl: Failure " "registering with primary security " Index: linux-2.6.13-rc3/security/security.c =================================================================== --- linux-2.6.13-rc3.orig/security/security.c 2005-06-17 14:48:29.000000000 -0500 +++ linux-2.6.13-rc3/security/security.c 2005-07-15 20:26:40.000000000 -0500 @@ -124,6 +124,7 @@ int unregister_security(struct security_ * 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 + * @owner: a pointer to the module registering. NULL if compiled into the kernel. * * 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 @@ -132,7 +133,8 @@ int unregister_security(struct security_ * 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) +int mod_reg_security(const char *name, struct security_operations *ops, + struct module *owner) { if (verify(ops)) { printk(KERN_INFO "%s could not verify " @@ -146,7 +148,7 @@ int mod_reg_security(const char *name, s return -EINVAL; } - return security_ops->register_security(name, ops); + return security_ops->register_security(name, ops, owner); } /** Index: linux-2.6.13-rc3/security/selinux/hooks.c =================================================================== --- linux-2.6.13-rc3.orig/security/selinux/hooks.c 2005-07-15 19:03:49.000000000 -0500 +++ linux-2.6.13-rc3/security/selinux/hooks.c 2005-07-15 20:28:00.000000000 -0500 @@ -4080,7 +4080,9 @@ static int selinux_ipc_permission(struct } /* module stacking operations */ -static int selinux_register_security (const char *name, struct security_operations *ops) +static int selinux_register_security (const char *name, + struct security_operations *ops, + struct module *owner) { if (secondary_ops != original_ops) { printk(KERN_INFO "%s: There is already a secondary security "
This archive was generated by hypermail 2.1.3 : Sun Jul 17 2005 - 07:34:56 PDT