apparmor/kernel-patches/2.6.25/apparmor-stack_secondary.diff
2008-04-19 17:49:10 +00:00

212 lines
6.6 KiB
Diff

From: John Johnansen <jjohansen@suse.de>
Subject: allow apparmor to stack with dazuko
Patch-mainline: no
References: 300965
Allow AppArmor to stack with dazuko so that the clamav virus
scanner can be used on an AppArmored machine.
Signed-off-by: John Johansen <jjohansen@suse.de>
---
security/apparmor/apparmor.h | 2
security/apparmor/apparmorfs.c | 2
security/apparmor/lsm.c | 101 ++++++++++++++++++++++++++++++++++++-----
3 files changed, 92 insertions(+), 13 deletions(-)
--- a/security/apparmor/apparmor.h
+++ b/security/apparmor/apparmor.h
@@ -347,7 +347,7 @@ extern void aa_set_rlimits(struct task_s
/* lsm.c */
extern int apparmor_initialized;
-extern void info_message(const char *str);
+extern void info_message(const char *str, const char *name);
extern void apparmor_disable(void);
/* list.c */
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -266,7 +266,7 @@ int create_apparmorfs(void)
goto error;
/* Report that AppArmor fs is enabled */
- info_message("AppArmor Filesystem Enabled");
+ info_message("AppArmor Filesystem Enabled", "");
return 0;
error:
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -26,6 +26,20 @@
/* Flag indicating whether initialization completed */
int apparmor_initialized = 0;
+/* point to the apparmor module */
+struct module *aa_module = NULL;
+
+/* secondary ops if apparmor is stacked */
+static struct security_operations *aa_secondary_ops = NULL;
+static DEFINE_MUTEX(aa_secondary_lock);
+
+#define AA_SECONDARY(FN, ARGS...) \
+ ({ \
+ struct security_operations *__f1; \
+ __f1 = rcu_dereference(aa_secondary_ops); \
+ (unlikely(__f1) && __f1->FN) ? __f1->FN(ARGS) : 0; \
+ })
+
static int param_set_aabool(const char *val, struct kernel_param *kp);
static int param_get_aabool(char *buffer, struct kernel_param *kp);
#define param_check_aabool(name, p) __param_check(name, p, int)
@@ -452,19 +466,25 @@ out:
static int apparmor_inode_permission(struct inode *inode, int mask,
struct nameidata *nd)
{
- int check = 0;
+ int check = 0, error = 0;
if (!nd || nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE))
- return 0;
+ goto out;
mask = aa_mask_permissions(mask);
if (S_ISDIR(inode->i_mode)) {
check |= AA_CHECK_DIR;
/* allow traverse accesses to directories */
mask &= ~MAY_EXEC;
}
- return aa_permission("inode_permission", inode, nd->path.dentry,
- nd->path.mnt,
- mask, check);
+ error = aa_permission("inode_permission", inode, nd->path.dentry,
+ nd->path.mnt,
+ mask, check);
+
+out:
+ if (!error)
+ error = AA_SECONDARY(inode_permission, inode, mask, nd);
+
+ return error;
}
static int apparmor_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
@@ -882,6 +902,61 @@ static int apparmor_task_setrlimit(unsig
return error;
}
+int apparmor_register_subsecurity(const char *name,
+ struct security_operations *ops)
+{
+ int error = 0;
+
+ if (mutex_lock_interruptible(&aa_secondary_lock))
+ return -ERESTARTSYS;
+
+ /* allow dazuko and capability to stack. The stacking with
+ * capability is not needed since apparmor already composes
+ * capability using common cap.
+ */
+ if (!aa_secondary_ops && (strcmp(name, "dazuko") == 0 ||
+ strcmp(name, "capability") == 0)){
+ /* The apparmor module needs to be pinned while a secondary is
+ * registered
+ */
+ if (try_module_get(aa_module)) {
+ aa_secondary_ops = ops;
+ info_message("Registered secondary security module",
+ name);
+ } else {
+ error = -EINVAL;
+ }
+ } else {
+ info_message("Unable to register %s as a secondary security "
+ "module", name);
+ error = -EPERM;
+ }
+ mutex_unlock(&aa_secondary_lock);
+ return error;
+}
+
+int apparmor_unregister_subsecurity(const char *name,
+ struct security_operations *ops)
+{
+ int error = 0;
+
+ if (mutex_lock_interruptible(&aa_secondary_lock))
+ return -ERESTARTSYS;
+
+ if (aa_secondary_ops && aa_secondary_ops == ops) {
+ rcu_assign_pointer(aa_secondary_ops, NULL);
+ synchronize_rcu();
+ module_put(aa_module);
+ info_message("Unregistered secondary security module", name);
+ } else {
+ info_message("Unable to unregister secondary security module",
+ name);
+ error = -EPERM;
+ }
+ mutex_unlock(&aa_secondary_lock);
+ return error;
+}
+
struct security_operations apparmor_ops = {
.ptrace = apparmor_ptrace,
.capget = cap_capget,
@@ -928,6 +1003,8 @@ struct security_operations apparmor_ops
.getprocattr = apparmor_getprocattr,
.setprocattr = apparmor_setprocattr,
+ .register_security = apparmor_register_subsecurity,
+
.socket_create = apparmor_socket_create,
.socket_post_create = apparmor_socket_post_create,
.socket_bind = apparmor_socket_bind,
@@ -943,13 +1020,14 @@ struct security_operations apparmor_ops
.socket_shutdown = apparmor_socket_shutdown,
};
-void info_message(const char *str)
+void info_message(const char *str, const char *name)
{
struct aa_audit sa;
memset(&sa, 0, sizeof(sa));
sa.gfp_mask = GFP_KERNEL;
sa.info = str;
- printk(KERN_INFO "AppArmor: %s\n", str);
+ sa.name = name;
+ printk(KERN_INFO "AppArmor: %s %s\n", str, name);
if (audit_enabled)
aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS);
}
@@ -959,7 +1037,7 @@ static int __init apparmor_init(void)
int error;
if (!apparmor_enabled) {
- info_message("AppArmor disabled by boottime parameter\n");
+ info_message("AppArmor disabled by boottime parameter", "");
return 0;
}
@@ -981,9 +1059,10 @@ static int __init apparmor_init(void)
/* Report that AppArmor successfully initialized */
apparmor_initialized = 1;
if (apparmor_complain)
- info_message("AppArmor initialized: complainmode enabled");
+ info_message("AppArmor initialized: complainmode enabled",
+ NULL);
else
- info_message("AppArmor initialized");
+ info_message("AppArmor initialized", NULL);
return error;
@@ -1021,7 +1100,7 @@ void apparmor_disable(void)
apparmor_initialized = 0;
- info_message("AppArmor protection removed");
+ info_message("AppArmor protection removed", NULL);
}
MODULE_DESCRIPTION("AppArmor process confinement");