linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: jjohansen@suse.de
To: akpm@linux-foundation.org
Cc: linux-kernel@vger.kernel.org,
	linux-security-module@vger.kernel.org,
	John Johansen <jjohansen@suse.de>,
	Andreas Gruenbacher <agruen@suse.de>
Subject: [AppArmor 38/45] AppArmor: Module and LSM hooks
Date: Thu, 25 Oct 2007 23:41:02 -0700	[thread overview]
Message-ID: <20071026064052.252643074@suse.de> (raw)
In-Reply-To: 20071026064024.243943043@suse.de

[-- Attachment #1: apparmor-lsm.diff --]
[-- Type: text/plain, Size: 21432 bytes --]

Module parameters, LSM hooks, initialization and teardown.

Signed-off-by: John Johansen <jjohansen@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>

---
 security/apparmor/lsm.c |  816 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 816 insertions(+)

--- /dev/null
+++ b/security/apparmor/lsm.c
@@ -0,0 +1,816 @@
+/*
+ *	Copyright (C) 1998-2007 Novell/SUSE
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License as
+ *	published by the Free Software Foundation, version 2 of the
+ *	License.
+ *
+ *	AppArmor LSM interface
+ */
+
+#include <linux/security.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/ctype.h>
+#include <linux/sysctl.h>
+#include <linux/audit.h>
+
+#include "apparmor.h"
+#include "inline.h"
+
+/* Boot time disable flag */
+int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
+
+static int __init apparmor_enabled_setup(char *str)
+{
+	apparmor_enabled = simple_strtol(str, NULL, 0);
+	return 1;
+}
+__setup("apparmor=", apparmor_enabled_setup);
+
+
+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)
+
+static int param_set_aauint(const char *val, struct kernel_param *kp);
+static int param_get_aauint(char *buffer, struct kernel_param *kp);
+#define param_check_aauint(name, p) __param_check(name, p, int)
+
+/* Flag values, also controllable via /sys/module/apparmor/parameters
+ * We define special types as we want to do additional mediation.
+ *
+ * Complain mode -- in complain mode access failures result in auditing only
+ * and task is allowed access.  audit events are processed by userspace to
+ * generate policy.  Default is 'enforce' (0).
+ * Value is also togglable per profile and referenced when global value is
+ * enforce.
+ */
+int apparmor_complain = 0;
+module_param_named(complain, apparmor_complain, aabool, S_IRUSR | S_IWUSR);
+MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode");
+
+/* Debug mode */
+int apparmor_debug = 0;
+module_param_named(debug, apparmor_debug, aabool, S_IRUSR | S_IWUSR);
+MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode");
+
+/* Audit mode */
+int apparmor_audit = 0;
+module_param_named(audit, apparmor_audit, aabool, S_IRUSR | S_IWUSR);
+MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode");
+
+/* Syscall logging mode */
+int apparmor_logsyscall = 0;
+module_param_named(logsyscall, apparmor_logsyscall, aabool, S_IRUSR | S_IWUSR);
+MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode");
+
+/* Maximum pathname length before accesses will start getting rejected */
+unsigned int apparmor_path_max = 2 * PATH_MAX;
+module_param_named(path_max, apparmor_path_max, aauint, S_IRUSR | S_IWUSR);
+MODULE_PARM_DESC(apparmor_path_max, "Maximum pathname length allowed");
+
+static int param_set_aabool(const char *val, struct kernel_param *kp)
+{
+	if (aa_task_context(current))
+		return -EPERM;
+	return param_set_bool(val, kp);
+}
+
+static int param_get_aabool(char *buffer, struct kernel_param *kp)
+{
+	if (aa_task_context(current))
+		return -EPERM;
+	return param_get_bool(buffer, kp);
+}
+
+static int param_set_aauint(const char *val, struct kernel_param *kp)
+{
+	if (aa_task_context(current))
+		return -EPERM;
+	return param_set_uint(val, kp);
+}
+
+static int param_get_aauint(char *buffer, struct kernel_param *kp)
+{
+	if (aa_task_context(current))
+		return -EPERM;
+	return param_get_uint(buffer, kp);
+}
+
+static int aa_reject_syscall(struct task_struct *task, gfp_t flags,
+			     const char *name)
+{
+	struct aa_profile *profile = aa_get_profile(task);
+	int error = 0;
+
+	if (profile) {
+		error = aa_audit_syscallreject(profile, flags, name);
+		aa_put_profile(profile);
+	}
+
+	return error;
+}
+
+static int apparmor_ptrace(struct task_struct *parent,
+			   struct task_struct *child)
+{
+	struct aa_task_context *cxt;
+	int error = 0;
+
+	/*
+	 * parent can ptrace child when
+	 * - parent is unconfined
+	 * - parent & child are in the same namespace &&
+	 *   - parent is in complain mode
+	 *   - parent and child are confined by the same profile
+	 *   - parent profile has CAP_SYS_PTRACE
+	 */
+
+	rcu_read_lock();
+	cxt = aa_task_context(parent);
+	if (cxt) {
+		if (parent->nsproxy != child->nsproxy) {
+			struct aa_audit sa;
+			memset(&sa, 0, sizeof(sa));
+			sa.operation = "ptrace";
+			sa.gfp_mask = GFP_ATOMIC;
+			sa.parent = parent->pid;
+			sa.task = child->pid;
+			sa.info = "different namespaces";
+			aa_audit_reject(cxt->profile, &sa);
+			error = -EPERM;
+		} else {
+			struct aa_task_context *child_cxt =
+				aa_task_context(child);
+
+			error = aa_may_ptrace(cxt, child_cxt ?
+						   child_cxt->profile : NULL);
+			if (PROFILE_COMPLAIN(cxt->profile)) {
+				struct aa_audit sa;
+				memset(&sa, 0, sizeof(sa));
+				sa.operation = "ptrace";
+				sa.gfp_mask = GFP_ATOMIC;
+				sa.parent = parent->pid;
+				sa.task = child->pid;
+				aa_audit_hint(cxt->profile, &sa);
+			}
+		}
+	}
+	rcu_read_unlock();
+
+	return error;
+}
+
+static int apparmor_capable(struct task_struct *task, int cap)
+{
+	int error;
+
+	/* cap_capable returns 0 on success, else -EPERM */
+	error = cap_capable(task, cap);
+
+	if (!error) {
+		struct aa_task_context *cxt;
+
+		rcu_read_lock();
+		cxt = aa_task_context(task);
+		if (cxt)
+			error = aa_capability(cxt, cap);
+		rcu_read_unlock();
+	}
+
+	return error;
+}
+
+static int apparmor_sysctl(struct ctl_table *table, int op)
+{
+	struct aa_profile *profile = aa_get_profile(current);
+	int error = 0;
+
+	if (profile) {
+		char *buffer, *name;
+		int mask;
+
+		mask = 0;
+		if (op & 4)
+			mask |= MAY_READ;
+		if (op & 2)
+			mask |= MAY_WRITE;
+
+		error = -ENOMEM;
+		buffer = (char*)__get_free_page(GFP_KERNEL);
+		if (!buffer)
+			goto out;
+		name = sysctl_pathname(table, buffer, PAGE_SIZE);
+		if (name && name - buffer >= 5) {
+			name -= 5;
+			memcpy(name, "/proc", 5);
+			error = aa_perm_path(profile, "sysctl", name, mask, 0,
+					     0);
+		}
+		free_page((unsigned long)buffer);
+	}
+
+out:
+	return error;
+}
+
+static int apparmor_bprm_set_security(struct linux_binprm *bprm)
+{
+	/* handle capability bits with setuid, etc */
+	cap_bprm_set_security(bprm);
+	/* already set based on script name */
+	if (bprm->sh_bang)
+		return 0;
+	return aa_register(bprm);
+}
+
+static int apparmor_bprm_secureexec(struct linux_binprm *bprm)
+{
+	int ret = cap_bprm_secureexec(bprm);
+
+	if (!ret && (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) {
+		AA_DEBUG("%s: secureexec required for %s\n",
+			 __FUNCTION__, bprm->filename);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type,
+			      unsigned long flags, void *data)
+{
+	return aa_reject_syscall(current, GFP_KERNEL, "mount");
+}
+
+static int apparmor_umount(struct vfsmount *mnt, int flags)
+{
+	return aa_reject_syscall(current, GFP_KERNEL, "umount");
+}
+
+static int apparmor_inode_mkdir(struct inode *dir, struct dentry *dentry,
+				struct vfsmount *mnt, int mask)
+{
+	struct aa_profile *profile;
+	int error = 0;
+
+	if (!mnt || !mediated_filesystem(dir))
+		goto out;
+
+	profile = aa_get_profile(current);
+
+	if (profile)
+		error = aa_perm_dir(profile, "inode_mkdir", dentry, mnt,
+				    MAY_WRITE);
+
+	aa_put_profile(profile);
+
+out:
+	return error;
+}
+
+static int apparmor_inode_rmdir(struct inode *dir, struct dentry *dentry,
+				struct vfsmount *mnt)
+{
+	struct aa_profile *profile;
+	int error = 0;
+
+	if (!mnt || !mediated_filesystem(dir))
+		goto out;
+
+	profile = aa_get_profile(current);
+
+	if (profile)
+		error = aa_perm_dir(profile, "inode_rmdir", dentry, mnt,
+				    MAY_WRITE);
+
+	aa_put_profile(profile);
+
+out:
+	return error;
+}
+
+static int aa_permission(const char *operation, struct inode *inode,
+			 struct dentry *dentry, struct vfsmount *mnt,
+			 int mask, int check)
+{
+	int error = 0;
+
+	if (mnt && mediated_filesystem(inode)) {
+		struct aa_profile *profile;
+
+		profile = aa_get_profile(current);
+		if (profile)
+			error = aa_perm(profile, operation, dentry, mnt, mask,
+					check);
+		aa_put_profile(profile);
+	}
+	return error;
+}
+
+static inline int aa_mask_permissions(int mask)
+{
+	if (mask & MAY_APPEND)
+		mask &= (MAY_READ | MAY_APPEND | MAY_EXEC);
+	else
+		mask &= (MAY_READ | MAY_WRITE | MAY_EXEC);
+	return mask;
+}
+
+static int apparmor_inode_create(struct inode *dir, struct dentry *dentry,
+				 struct vfsmount *mnt, int mask)
+{
+	/* FIXME: may move to MAY_APPEND later */
+	return aa_permission("inode_create", dir, dentry, mnt, MAY_WRITE, 0);
+}
+
+static int apparmor_inode_link(struct dentry *old_dentry,
+			       struct vfsmount *old_mnt, struct inode *dir,
+			       struct dentry *new_dentry,
+			       struct vfsmount *new_mnt)
+{
+	int error = 0;
+	struct aa_profile *profile;
+
+	if (!old_mnt || !new_mnt || !mediated_filesystem(dir))
+		goto out;
+
+	profile = aa_get_profile(current);
+
+	if (profile)
+		error = aa_link(profile, new_dentry, new_mnt,
+				old_dentry, old_mnt);
+
+	aa_put_profile(profile);
+
+out:
+	return error;
+}
+
+static int apparmor_inode_unlink(struct inode *dir, struct dentry *dentry,
+				 struct vfsmount *mnt)
+{
+	int check = 0;
+
+	if (S_ISDIR(dentry->d_inode->i_mode))
+		check |= AA_CHECK_DIR;
+	return aa_permission("inode_unlink", dir, dentry, mnt, MAY_WRITE,
+			     check);
+}
+
+static int apparmor_inode_symlink(struct inode *dir, struct dentry *dentry,
+				  struct vfsmount *mnt, const char *old_name)
+{
+	return aa_permission("inode_symlink", dir, dentry, mnt, MAY_WRITE, 0);
+}
+
+static int apparmor_inode_mknod(struct inode *dir, struct dentry *dentry,
+				struct vfsmount *mnt, int mode, dev_t dev)
+{
+	return aa_permission("inode_mknod", dir, dentry, mnt, MAY_WRITE, 0);
+}
+
+static int apparmor_inode_rename(struct inode *old_dir,
+				 struct dentry *old_dentry,
+				 struct vfsmount *old_mnt,
+				 struct inode *new_dir,
+				 struct dentry *new_dentry,
+				 struct vfsmount *new_mnt)
+{
+	struct aa_profile *profile;
+	int error = 0;
+
+	if ((!old_mnt && !new_mnt) || !mediated_filesystem(old_dir))
+		goto out;
+
+	profile = aa_get_profile(current);
+
+	if (profile) {
+		struct inode *inode = old_dentry->d_inode;
+		int check = 0;
+
+		if (inode && S_ISDIR(inode->i_mode))
+			check |= AA_CHECK_DIR;
+		if (old_mnt)
+			error = aa_perm(profile, "inode_rename", old_dentry,
+					old_mnt, MAY_READ | MAY_WRITE, check);
+
+		if (!error && new_mnt) {
+			error = aa_perm(profile, "inode_rename", new_dentry,
+					new_mnt, MAY_WRITE, check);
+		}
+	}
+
+	aa_put_profile(profile);
+
+out:
+	return error;
+}
+
+static int apparmor_inode_permission(struct inode *inode, int mask,
+				     struct nameidata *nd)
+{
+	int check = 0;
+
+	if (!nd || nd->flags & (LOOKUP_PARENT | LOOKUP_CONTINUE))
+		return 0;
+	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->dentry, nd->mnt,
+			     mask, check);
+}
+
+static int apparmor_inode_setattr(struct dentry *dentry, struct vfsmount *mnt,
+				  struct iattr *iattr)
+{
+	int error = 0;
+
+	if (!mnt)
+		goto out;
+
+	if (mediated_filesystem(dentry->d_inode)) {
+		struct aa_profile *profile;
+
+		profile = aa_get_profile(current);
+		/*
+		 * Mediate any attempt to change attributes of a file
+		 * (chmod, chown, chgrp, etc)
+		 */
+		if (profile)
+			error = aa_attr(profile, dentry, mnt, iattr);
+
+		aa_put_profile(profile);
+	}
+
+out:
+	return error;
+}
+
+static int aa_xattr_permission(struct dentry *dentry, struct vfsmount *mnt,
+			       const char *operation, int mask,
+			       struct file *file)
+{
+	int error = 0;
+
+	if (mnt && mediated_filesystem(dentry->d_inode)) {
+		struct aa_profile *profile = aa_get_profile(current);
+		int check = file ? AA_CHECK_FD : 0;
+
+		if (profile)
+			error = aa_perm_xattr(profile, operation, dentry, mnt,
+					      mask, check);
+		aa_put_profile(profile);
+	}
+
+	return error;
+}
+
+static int apparmor_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt,
+				   char *name, void *value, size_t size,
+				   int flags, struct file *file)
+{
+	return aa_xattr_permission(dentry, mnt, "xattr set", MAY_WRITE, file);
+}
+
+static int apparmor_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt,
+				   char *name, struct file *file)
+{
+	return aa_xattr_permission(dentry, mnt, "xattr get", MAY_READ, file);
+}
+
+static int apparmor_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt,
+				    struct file *file)
+{
+	return aa_xattr_permission(dentry, mnt, "xattr list", MAY_READ, file);
+}
+
+static int apparmor_inode_removexattr(struct dentry *dentry,
+				      struct vfsmount *mnt, char *name,
+				      struct file *file)
+{
+	return aa_xattr_permission(dentry, mnt, "xattr remove", MAY_WRITE,
+				   file);
+}
+
+static int aa_file_permission(const char *op, struct file *file, int mask)
+{
+	struct aa_profile *profile;
+	struct aa_profile *file_profile = (struct aa_profile*)file->f_security;
+	int error = 0;
+
+	if (!file_profile)
+		goto out;
+
+	/*
+	 * If this file was opened under a different profile, we
+	 * revalidate the access against the current profile.
+	 */
+	profile = aa_get_profile(current);
+	if (profile && (file_profile != profile || mask & AA_MAY_LOCK)) {
+		struct dentry *dentry = file->f_dentry;
+		struct vfsmount *mnt = file->f_vfsmnt;
+		struct inode *inode = dentry->d_inode;
+		int check = AA_CHECK_FD;
+
+		/*
+		 * FIXME: We should remember which profiles we revalidated
+		 *	  against.
+		 */
+		if (S_ISDIR(inode->i_mode))
+			check |= AA_CHECK_DIR;
+		error = aa_permission(op, inode, dentry, mnt, mask, check);
+	}
+	aa_put_profile(profile);
+
+out:
+	return error;
+}
+
+static int apparmor_file_permission(struct file *file, int mask)
+{
+	return aa_file_permission("file_permission", file,
+				  aa_mask_permissions(mask));
+}
+
+static inline int apparmor_file_lock (struct file *file, unsigned int cmd)
+{
+	int mask = AA_MAY_LOCK;
+	if (cmd == F_WRLCK)
+		mask |= MAY_WRITE;
+	return aa_file_permission("file_lock", file, mask);
+}
+
+static int apparmor_file_alloc_security(struct file *file)
+{
+	struct aa_profile *profile;
+
+	profile = aa_get_profile(current);
+	if (profile)
+		file->f_security = profile;
+
+	return 0;
+}
+
+static void apparmor_file_free_security(struct file *file)
+{
+	struct aa_profile *file_profile = (struct aa_profile*)file->f_security;
+
+	aa_put_profile(file_profile);
+}
+
+static inline int aa_mmap(struct file *file, const char *operation,
+			  unsigned long prot, unsigned long flags)
+{
+	struct dentry *dentry;
+	int mask = 0;
+
+	if (!file || !file->f_security)
+		return 0;
+
+	if (prot & PROT_READ)
+		mask |= MAY_READ;
+	/* Private mappings don't require write perms since they don't
+	 * write back to the files */
+	if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE))
+		mask |= MAY_WRITE;
+	if (prot & PROT_EXEC)
+		mask |= AA_EXEC_MMAP;
+
+	dentry = file->f_dentry;
+	return aa_permission(operation, dentry->d_inode, dentry,
+			     file->f_vfsmnt, mask, AA_CHECK_FD);
+}
+
+static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
+			      unsigned long prot, unsigned long flags,
+			      unsigned long addr, unsigned long addr_only)
+{
+	return aa_mmap(file, "file_mmap", prot, flags);
+}
+
+static int apparmor_file_mprotect(struct vm_area_struct *vma,
+				  unsigned long reqprot, unsigned long prot)
+{
+	return aa_mmap(vma->vm_file, "file_mprotect", prot,
+		       !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
+}
+
+static int apparmor_task_alloc_security(struct task_struct *task)
+{
+	return aa_clone(task);
+}
+
+/*
+ * Called from IRQ context from RCU callback.
+ */
+static void apparmor_task_free_security(struct task_struct *task)
+{
+	aa_release(task);
+}
+
+static int apparmor_getprocattr(struct task_struct *task, char *name,
+				char **value)
+{
+	unsigned len;
+	int error;
+	struct aa_profile *profile;
+
+	/* AppArmor only supports the "current" process attribute */
+	if (strcmp(name, "current") != 0)
+		return -EINVAL;
+
+	/* must be task querying itself or admin */
+	if (current != task && !capable(CAP_SYS_ADMIN))
+		return -EPERM;
+
+	profile = aa_get_profile(task);
+	error = aa_getprocattr(profile, value, &len);
+	aa_put_profile(profile);
+	if (!error)
+		error = len;
+
+	return error;
+}
+
+static int apparmor_setprocattr(struct task_struct *task, char *name,
+				void *value, size_t size)
+{
+	char *command, *args;
+	int error;
+
+	if (strcmp(name, "current") != 0 || size == 0 || size >= PAGE_SIZE)
+		return -EINVAL;
+	args = value;
+	args[size] = '\0';
+	args = strstrip(args);
+	command = strsep(&args, " ");
+	if (!args)
+		return -EINVAL;
+	while (isspace(*args))
+		args++;
+	if (!*args)
+		return -EINVAL;
+
+	if (strcmp(command, "changehat") == 0) {
+		if (current != task)
+			return -EACCES;
+		error = aa_setprocattr_changehat(args);
+	} else if (strcmp(command, "changeprofile") == 0) {
+		if (current != task)
+			return -EACCES;
+		error = aa_setprocattr_changeprofile(args);
+	} else if (strcmp(command, "setprofile") == 0) {
+		struct aa_profile *profile;
+
+		/* Only an unconfined process with admin capabilities
+		 * may change the profile of another task.
+		 */
+
+		if (!capable(CAP_SYS_ADMIN))
+			return -EACCES;
+
+		profile = aa_get_profile(current);
+		if (profile) {
+			struct aa_audit sa;
+			memset(&sa, 0, sizeof(sa));
+			sa.operation = "profile_set";
+			sa.gfp_mask = GFP_KERNEL;
+			sa.task = task->pid;
+			sa.info = "from confined process";
+			aa_audit_reject(profile, &sa);
+			aa_put_profile(profile);
+			return -EACCES;
+		}
+		error = aa_setprocattr_setprofile(task, args);
+	} else {
+		struct aa_audit sa;
+		memset(&sa, 0, sizeof(sa));
+		sa.operation = "setprocattr";
+		sa.gfp_mask = GFP_KERNEL;
+		sa.info = "invalid command";
+		sa.name = command;
+		sa.task = task->pid;
+		aa_audit_reject(NULL, &sa);
+		return -EINVAL;
+	}
+
+	if (!error)
+		error = size;
+	return error;
+}
+
+struct security_operations apparmor_ops = {
+	.ptrace =			apparmor_ptrace,
+	.capget =			cap_capget,
+	.capset_check =			cap_capset_check,
+	.capset_set =			cap_capset_set,
+	.sysctl =			apparmor_sysctl,
+	.capable =			apparmor_capable,
+	.syslog =			cap_syslog,
+
+	.netlink_send =			cap_netlink_send,
+	.netlink_recv =			cap_netlink_recv,
+
+	.bprm_apply_creds =		cap_bprm_apply_creds,
+	.bprm_set_security =		apparmor_bprm_set_security,
+	.bprm_secureexec =		apparmor_bprm_secureexec,
+
+	.sb_mount =			apparmor_sb_mount,
+	.sb_umount =			apparmor_umount,
+
+	.inode_mkdir =			apparmor_inode_mkdir,
+	.inode_rmdir =			apparmor_inode_rmdir,
+	.inode_create =			apparmor_inode_create,
+	.inode_link =			apparmor_inode_link,
+	.inode_unlink =			apparmor_inode_unlink,
+	.inode_symlink =		apparmor_inode_symlink,
+	.inode_mknod =			apparmor_inode_mknod,
+	.inode_rename =			apparmor_inode_rename,
+	.inode_permission =		apparmor_inode_permission,
+	.inode_setattr =		apparmor_inode_setattr,
+	.inode_setxattr =		apparmor_inode_setxattr,
+	.inode_getxattr =		apparmor_inode_getxattr,
+	.inode_listxattr =		apparmor_inode_listxattr,
+	.inode_removexattr =		apparmor_inode_removexattr,
+	.file_permission =		apparmor_file_permission,
+	.file_alloc_security =		apparmor_file_alloc_security,
+	.file_free_security =		apparmor_file_free_security,
+	.file_mmap =			apparmor_file_mmap,
+	.file_mprotect =		apparmor_file_mprotect,
+	.file_lock =			apparmor_file_lock,
+
+	.task_alloc_security =		apparmor_task_alloc_security,
+	.task_free_security =		apparmor_task_free_security,
+	.task_post_setuid =		cap_task_post_setuid,
+	.task_reparent_to_init =	cap_task_reparent_to_init,
+
+	.getprocattr =			apparmor_getprocattr,
+	.setprocattr =			apparmor_setprocattr,
+};
+
+static void info_message(const char *str)
+{
+	struct aa_audit sa;
+	memset(&sa, 0, sizeof(sa));
+	sa.gfp_mask = GFP_KERNEL;
+	sa.info = str;
+	printk(KERN_INFO "AppArmor: %s", str);
+	aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS);
+}
+
+static int __init apparmor_init(void)
+{
+	int error;
+
+	if (!apparmor_enabled) {
+		info_message("AppArmor disabled by boottime parameter\n");
+		return 0;
+	}
+
+	if ((error = create_apparmorfs())) {
+		AA_ERROR("Unable to activate AppArmor filesystem\n");
+		goto createfs_out;
+	}
+
+	if ((error = alloc_default_namespace())){
+		AA_ERROR("Unable to allocate default profile namespace\n");
+		goto alloc_out;
+	}
+
+ 	if ((error = register_security(&apparmor_ops))) {
+		AA_ERROR("Unable to register AppArmor\n");
+		goto register_security_out;
+	}
+
+	if (apparmor_complain)
+		info_message("AppArmor initialized: complainmode enabled");
+	else
+		info_message("AppArmor initialized");
+
+	return error;
+
+register_security_out:
+	free_default_namespace();
+
+alloc_out:
+ 	destroy_apparmorfs();
+
+createfs_out:
+	return error;
+
+}
+
+module_init(apparmor_init);
+
+MODULE_DESCRIPTION("AppArmor process confinement");
+MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org");
+MODULE_LICENSE("GPL");

-- 


  parent reply	other threads:[~2007-10-26  7:12 UTC|newest]

Thread overview: 92+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-26  6:40 [AppArmor 00/45] AppArmor security module overview jjohansen
2007-10-26  6:40 ` [AppArmor 01/45] Pass struct vfsmount to the inode_create LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 02/45] Pass struct path down to remove_suid and children jjohansen
2007-10-26  6:40 ` [AppArmor 03/45] Add a vfsmount parameter to notify_change() jjohansen
2007-10-26  6:40 ` [AppArmor 04/45] Pass struct vfsmount to the inode_setattr LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 05/45] Add struct vfsmount parameter to vfs_mkdir() jjohansen
2007-10-26  6:40 ` [AppArmor 06/45] Pass struct vfsmount to the inode_mkdir LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 07/45] Add a struct vfsmount parameter to vfs_mknod() jjohansen
2007-10-26  6:40 ` [AppArmor 08/45] Pass struct vfsmount to the inode_mknod LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 09/45] Add a struct vfsmount parameter to vfs_symlink() jjohansen
2007-10-26  6:40 ` [AppArmor 10/45] Pass struct vfsmount to the inode_symlink LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 11/45] Pass struct vfsmount to the inode_readlink " jjohansen
2007-10-26  6:40 ` [AppArmor 12/45] Add struct vfsmount parameters to vfs_link() jjohansen
2007-10-26  6:40 ` [AppArmor 13/45] Pass the struct vfsmounts to the inode_link LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 14/45] Add a struct vfsmount parameter to vfs_rmdir() jjohansen
2007-10-26  6:40 ` [AppArmor 15/45] Pass struct vfsmount to the inode_rmdir LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 16/45] Call lsm hook before unhashing dentry in vfs_rmdir() jjohansen
2007-10-26  6:40 ` [AppArmor 17/45] Add a struct vfsmount parameter to vfs_unlink() jjohansen
2007-10-26  6:40 ` [AppArmor 18/45] Pass struct vfsmount to the inode_unlink LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 19/45] Add struct vfsmount parameters to vfs_rename() jjohansen
2007-10-26  7:37   ` Al Viro
2007-10-26 18:23     ` John Johansen
2007-10-26 20:33       ` Al Viro
2007-10-26  6:40 ` [AppArmor 20/45] Pass struct vfsmount to the inode_rename LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 21/45] Add a struct vfsmount parameter to vfs_setxattr() jjohansen
2007-10-26  6:40 ` [AppArmor 22/45] Pass struct vfsmount to the inode_setxattr LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 23/45] Add a struct vfsmount parameter to vfs_getxattr() jjohansen
2007-10-26  6:40 ` [AppArmor 24/45] Pass struct vfsmount to the inode_getxattr LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 25/45] Add a struct vfsmount parameter to vfs_listxattr() jjohansen
2007-10-26  6:40 ` [AppArmor 26/45] Pass struct vfsmount to the inode_listxattr LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 27/45] Add a struct vfsmount parameter to vfs_removexattr() jjohansen
2007-10-26  6:40 ` [AppArmor 28/45] Pass struct vfsmount to the inode_removexattr LSM hook jjohansen
2007-10-26  6:40 ` [AppArmor 29/45] Fix __d_path() for lazy unmounts and make it unambiguous jjohansen
2007-10-26  6:40 ` [AppArmor 30/45] Make d_path() consistent across mount operations jjohansen
2007-10-26  6:40 ` [AppArmor 31/45] Add d_namespace_path() to compute namespace relative pathnames jjohansen
2007-10-26  6:40 ` [AppArmor 32/45] Enable LSM hooks to distinguish operations on file descriptors from operations on pathnames jjohansen
2007-10-26 11:30   ` Miklos Szeredi
2007-10-26 11:45     ` Miklos Szeredi
2007-10-26 18:49     ` John Johansen
2007-10-26 20:24     ` Andreas Gruenbacher
2007-10-26 20:58       ` Miklos Szeredi
2007-10-26 21:56         ` Andreas Gruenbacher
2007-10-26  6:40 ` [AppArmor 33/45] Pass struct file down the inode_*xattr security LSM hooks jjohansen
2007-10-26  6:40 ` [AppArmor 34/45] Factor out sysctl pathname code jjohansen
2007-10-26  9:24   ` James Morris
2007-10-26  6:40 ` [AppArmor 35/45] Allow permission functions to tell between parent and leaf checks jjohansen
2007-10-26 12:32   ` Stephen Smalley
2007-10-26 18:26     ` John Johansen
2007-10-26  6:41 ` [AppArmor 36/45] Export audit subsystem for use by modules jjohansen
2007-10-26  6:41 ` [AppArmor 37/45] AppArmor: Main Part jjohansen
2007-10-26  6:41 ` jjohansen [this message]
2007-10-26  6:41 ` [AppArmor 39/45] AppArmor: Profile loading and manipulation, pathname matching jjohansen
2007-10-26  6:41 ` [AppArmor 40/45] AppArmor: all the rest jjohansen
2007-10-26  6:41 ` [AppArmor 41/45] add simple network toggles to apparmor jjohansen
2007-10-26  6:41 ` [AppArmor 42/45] Add AppArmor LSM to security/Makefile jjohansen
2007-10-26  6:41 ` [AppArmor 43/45] Switch to vfs_permission() in do_path_lookup() jjohansen
2007-10-26  6:41 ` [AppArmor 44/45] Switch to vfs_permission() in sys_fchdir() jjohansen
2007-10-26  6:41 ` [AppArmor 45/45] Fix file_permission() jjohansen
2007-10-26  7:04 ` [AppArmor 00/45] AppArmor security module overview John Johansen
2007-10-26 14:37 ` Arjan van de Ven
2007-10-26 18:34   ` John Johansen
2007-10-26 20:15     ` Arjan van de Ven
2007-10-26 20:44   ` Andreas Gruenbacher
2007-10-26 21:13     ` Arjan van de Ven
2007-10-26 21:24       ` Andreas Gruenbacher
2007-10-26 22:16       ` Crispin Cowan
2007-10-26 22:23         ` Arjan van de Ven
2007-10-27 20:47   ` Christoph Hellwig
2007-10-28 14:25     ` Andreas Gruenbacher
  -- strict thread matches above, loose matches on Subject: below --
2007-05-14 11:06 jjohansen
2007-05-14 11:06 ` [AppArmor 38/45] AppArmor: Module and LSM hooks jjohansen
2007-05-15  9:14   ` Pavel Machek
2007-05-23 16:16     ` Andreas Gruenbacher
2007-06-04 10:55       ` Pavel Machek
2007-06-04 11:25         ` Andreas Gruenbacher
2007-06-04 11:35           ` Pavel Machek
2007-06-04 11:42             ` Andreas Gruenbacher
2007-06-04 13:12               ` Pavel Machek
2007-06-04 14:30                 ` Andreas Gruenbacher
2007-06-06 13:09                   ` Stephen Smalley
2007-06-10 23:10                     ` Andreas Gruenbacher
2007-06-11 14:33                       ` Stephen Smalley
2007-06-11 15:55                         ` Andreas Gruenbacher
2007-06-11 19:02                           ` Serge E. Hallyn
2007-06-12 13:00                             ` Stephen Smalley
2007-06-12 15:34                               ` Serge E. Hallyn
2007-06-12  5:17                                 ` Karl MacMillan
2007-06-12 19:00                                   ` Serge E. Hallyn
2007-06-12 13:13                           ` Stephen Smalley
2007-06-12 23:50                         ` Andreas Gruenbacher
2007-06-09 12:58                   ` Pavel Machek
2007-06-09 13:44                     ` Andreas Gruenbacher
2007-06-12 13:06                       ` Pavel Machek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071026064052.252643074@suse.de \
    --to=jjohansen@suse.de \
    --cc=agruen@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).