mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-06 09:21:00 +01:00
212 lines
6.6 KiB
Diff
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");
|