[RFC] [PATCH] add struct module to mod_reg_security args

From: serue@private
Date: Sun Jul 17 2005 - 07:33:42 PDT


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