From: jjohansen@suse.de
To: linux-kernel@vger.kernel.org
Cc: linux-security-module@vger.kernel.org,
linux-fsdevel@vger.kernel.org, John Johansen <jjohansen@suse.de>,
Andreas Gruenbacher <agruen@suse.de>
Subject: [AppArmor 38/45] AppArmor: Module and LSM hooks
Date: Mon, 14 May 2007 04:06:45 -0700 [thread overview]
Message-ID: <20070514110621.316630438@suse.de> (raw)
In-Reply-To: 20070514110607.549397248@suse.de
[-- Attachment #1: apparmor-lsm.diff --]
[-- Type: text/plain, Size: 20806 bytes --]
Module parameters, LSM hooks, initialization and teardown.
Signed-off-by: John Johansen <jjohansen@suse.de>
Signed-off-by: Andreas Gruenbacher <agruen@suse.de>
Index: b/security/apparmor/lsm.c
===================================================================
--- /dev/null
+++ b/security/apparmor/lsm.c
@@ -0,0 +1,790 @@
+/*
+ * 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 "apparmor.h"
+#include "inline.h"
+
+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;
+ struct aa_task_context *child_cxt;
+ struct aa_profile *child_profile;
+ 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);
+ child_cxt = aa_task_context(child);
+ child_profile = child_cxt ? child_cxt->profile : NULL;
+ if (cxt && (parent->nsproxy != child->nsproxy)) {
+ aa_audit_message(NULL, GFP_ATOMIC, "REJECTING ptrace across "
+ "namespace of %d by %d",
+ parent->pid, child->pid);
+ error = -EPERM;
+ } else {
+ error = aa_may_ptrace(cxt, child_profile);
+ if (cxt && PROFILE_COMPLAIN(cxt->profile)) {
+ aa_audit_message(cxt->profile, GFP_ATOMIC,
+ "LOGPROF-HINT ptrace pid=%d child=%d "
+ "(%d profile %s active %s)",
+ current->pid, child->pid, current->pid,
+ cxt->profile->parent->name,
+ cxt->profile->name);
+ }
+ }
+ 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, name, mask);
+ }
+ 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, dentry, mnt, "mkdir", 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, dentry, mnt, "rmdir", MAY_WRITE);
+
+ aa_put_profile(profile);
+
+out:
+ return error;
+}
+
+static int aa_permission(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, dentry, mnt, mask, check);
+ aa_put_profile(profile);
+ }
+ return error;
+}
+
+static int apparmor_inode_create(struct inode *dir, struct dentry *dentry,
+ struct vfsmount *mnt, int mask)
+{
+ return aa_permission(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(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(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(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, old_dentry, old_mnt,
+ MAY_READ | MAY_WRITE, check);
+
+ if (!error && new_mnt) {
+ error = aa_perm(profile, 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 &= (MAY_READ | MAY_WRITE | MAY_EXEC);
+ if (S_ISDIR(inode->i_mode)) {
+ check |= AA_CHECK_DIR;
+ /* allow traverse accesses to directories */
+ mask &= ~MAY_EXEC;
+ }
+ return aa_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, dentry, mnt, operation,
+ 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 apparmor_file_permission(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) {
+ 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;
+ mask &= (MAY_READ | MAY_WRITE | MAY_EXEC);
+ error = aa_permission(inode, dentry, mnt, mask, check);
+ }
+ aa_put_profile(profile);
+
+out:
+ return error;
+}
+
+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, 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(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)
+{
+ return aa_mmap(file, prot, flags);
+}
+
+static int apparmor_file_mprotect(struct vm_area_struct *vma,
+ unsigned long reqprot, unsigned long prot)
+{
+ return aa_mmap(vma->vm_file, 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, "setprofile")) {
+ 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) {
+ aa_put_profile(profile);
+ aa_audit_message(NULL, GFP_KERNEL, "Attempt by "
+ "confined task %d [user %d] to "
+ "assign profile to task %d",
+ current->pid, current->uid,
+ task->pid);
+ return -EACCES;
+ }
+ error = aa_setprocattr_setprofile(task, args);
+ } else {
+ AA_ERROR("Unknown setprocattr command '%.*s' "
+ "by task %d [user %d] for task %d",
+ size < 16 ? (int)size : 16,
+ command,
+ current->pid,
+ current->uid,
+ task->pid);
+ error = -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,
+
+ .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)
+{
+ printk(KERN_INFO "AppArmor: %s", str);
+ aa_audit_message(NULL, GFP_KERNEL, "%s", str);
+}
+
+static int __init apparmor_init(void)
+{
+ int error;
+
+ if ((error = create_apparmorfs())) {
+ AA_ERROR("Unable to activate AppArmor filesystem\n");
+ goto createfs_out;
+ }
+
+ if ((error = alloc_null_complain_profile())){
+ AA_ERROR("Unable to allocate null complain profile\n");
+ goto alloc_out;
+ }
+
+ if ((error = register_security(&apparmor_ops))) {
+ AA_ERROR("Unable to load 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_null_complain_profile();
+
+alloc_out:
+ destroy_apparmorfs();
+
+createfs_out:
+ return error;
+
+}
+
+static void __exit apparmor_exit(void)
+{
+ /* Remove and release all the profiles on the profile list. */
+ mutex_lock(&aa_interface_lock);
+ write_lock(&profile_list_lock);
+ while (!list_empty(&profile_list)) {
+ struct aa_profile *profile =
+ list_entry(profile_list.next, struct aa_profile, list);
+
+ /* Remove the profile from each task context it is on. */
+ lock_profile(profile);
+ profile->isstale = 1;
+ aa_unconfine_tasks(profile);
+ unlock_profile(profile);
+
+ /* Release the profile itself. */
+ list_del_init(&profile->list);
+ aa_put_profile(profile);
+ }
+ write_unlock(&profile_list_lock);
+
+ /* FIXME: cleanup profiles references on files */
+
+ free_null_complain_profile();
+
+ /*
+ * Delay for an rcu cycle to make sure that all active task
+ * context readers have finished, and all profiles have been
+ * freed by their rcu callbacks.
+ */
+ synchronize_rcu();
+
+ destroy_apparmorfs();
+ mutex_unlock(&aa_interface_lock);
+
+ if (unregister_security(&apparmor_ops))
+ info_message("Unable to properly unregister AppArmor");
+
+ info_message("AppArmor protection removed");
+}
+
+module_init(apparmor_init);
+module_exit(apparmor_exit);
+
+MODULE_DESCRIPTION("AppArmor process confinement");
+MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org");
+MODULE_LICENSE("GPL");
--
next prev parent reply other threads:[~2007-05-14 11:51 UTC|newest]
Thread overview: 265+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-14 11:06 [AppArmor 00/45] AppArmor security module overview jjohansen
2007-05-14 11:06 ` [AppArmor 01/45] Pass struct vfsmount to the inode_create LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 02/45] Pass struct path down to remove_suid and children jjohansen
2007-05-14 11:06 ` [AppArmor 03/45] Add a vfsmount parameter to notify_change() jjohansen
2007-05-14 11:06 ` [AppArmor 04/45] Pass struct vfsmount to the inode_setattr LSM hook jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` [AppArmor 05/45] Add struct vfsmount parameter to vfs_mkdir() jjohansen
2007-05-14 11:06 ` [AppArmor 06/45] Pass struct vfsmount to the inode_mkdir LSM hook jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` [AppArmor 07/45] Add a struct vfsmount parameter to vfs_mknod() jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` [AppArmor 08/45] Pass struct vfsmount to the inode_mknod LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 09/45] Add a struct vfsmount parameter to vfs_symlink() jjohansen
2007-05-14 11:06 ` [AppArmor 10/45] Pass struct vfsmount to the inode_symlink LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 11/45] Pass struct vfsmount to the inode_readlink " jjohansen
2007-05-14 11:06 ` [AppArmor 12/45] Add struct vfsmount parameters to vfs_link() jjohansen
2007-05-14 11:06 ` [AppArmor 13/45] Pass the struct vfsmounts to the inode_link LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 14/45] Add a struct vfsmount parameter to vfs_rmdir() jjohansen
2007-05-14 11:06 ` [AppArmor 15/45] Pass struct vfsmount to the inode_rmdir LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 16/45] Call lsm hook before unhashing dentry in vfs_rmdir() jjohansen
2007-05-14 11:06 ` [AppArmor 17/45] Add a struct vfsmount parameter to vfs_unlink() jjohansen
2007-05-14 11:06 ` [AppArmor 18/45] Pass struct vfsmount to the inode_unlink LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 19/45] Add struct vfsmount parameters to vfs_rename() jjohansen
2007-05-14 11:06 ` [AppArmor 20/45] Pass struct vfsmount to the inode_rename LSM hook jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` [AppArmor 21/45] Add a struct vfsmount parameter to vfs_setxattr() jjohansen
2007-05-14 11:06 ` [AppArmor 22/45] Pass struct vfsmount to the inode_setxattr LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 23/45] Add a struct vfsmount parameter to vfs_getxattr() jjohansen
2007-05-14 11:06 ` [AppArmor 24/45] Pass struct vfsmount to the inode_getxattr LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 25/45] Add a struct vfsmount parameter to vfs_listxattr() jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` [AppArmor 26/45] Pass struct vfsmount to the inode_listxattr LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 27/45] Add a struct vfsmount parameter to vfs_removexattr() jjohansen
2007-05-14 11:06 ` [AppArmor 28/45] Pass struct vfsmount to the inode_removexattr LSM hook jjohansen
2007-05-14 11:06 ` [AppArmor 29/45] Fix __d_path() for lazy unmounts and make it unambiguous jjohansen
2007-05-14 11:06 ` [AppArmor 30/45] Make d_path() consistent across mount operations jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` [AppArmor 31/45] Add d_namespace_path() to compute namespace relative pathnames jjohansen
2007-05-14 11:06 ` [AppArmor 32/45] Enable LSM hooks to distinguish operations on file descriptors from operations on pathnames jjohansen
2007-05-14 11:06 ` [AppArmor 33/45] Pass struct file down the inode_*xattr security LSM hooks jjohansen
2007-05-14 11:06 ` [AppArmor 34/45] Factor out sysctl pathname code jjohansen
2007-05-14 11:06 ` [AppArmor 35/45] Allow permission functions to tell between parent and leaf checks jjohansen
2007-05-15 9:08 ` Pavel Machek
2007-05-14 11:06 ` [AppArmor 36/45] Export audit subsystem for use by modules jjohansen
2007-05-14 11:06 ` [AppArmor 37/45] AppArmor: Main Part jjohansen
2007-05-15 9:12 ` Pavel Machek
2007-05-14 11:06 ` jjohansen [this message]
2007-05-15 9:14 ` [AppArmor 38/45] AppArmor: Module and LSM hooks 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
2007-05-14 11:06 ` [AppArmor 39/45] AppArmor: Profile loading and manipulation, pathname matching jjohansen
2007-05-15 9:20 ` Pavel Machek
2007-06-04 21:03 ` Andreas Gruenbacher
2007-06-06 13:26 ` Stephen Smalley
2007-06-06 17:32 ` Greg KH
2007-06-09 23:47 ` Pavel Machek
2007-06-08 22:03 ` Andreas Gruenbacher
2007-06-09 0:17 ` Greg KH
2007-06-09 1:06 ` david
2007-06-09 2:01 ` [AppArmor 39/45] AppArmor: Profile loading and manipulation,pathname matching Tetsuo Handa
2007-06-09 3:25 ` Sean
2007-06-09 4:56 ` david
2007-06-09 5:10 ` Sean
2007-06-09 5:38 ` david
2007-06-09 5:44 ` Sean
2007-06-09 7:04 ` david
2007-06-09 7:28 ` Sean
2007-06-09 8:03 ` david
2007-06-09 8:37 ` Sean
2007-06-14 17:01 ` Pavel Machek
2007-06-09 11:26 ` [AppArmor 39/45] AppArmor: Profile loading andmanipulation,pathname matching Tetsuo Handa
2007-06-09 11:35 ` Sean
2007-06-09 13:41 ` david
2007-06-09 18:37 ` [AppArmor 39/45] AppArmor: Profile loading and manipulation,pathname matching Casey Schaufler
2007-06-15 13:36 ` Pavel Machek
2007-06-10 8:34 ` [AppArmor 39/45] AppArmor: Profile loading and manipulation, pathname matching Pavel Machek
2007-06-10 9:04 ` david
2007-06-10 20:04 ` Casey Schaufler
2007-06-10 20:51 ` Crispin Cowan
2007-06-11 6:45 ` david
2007-06-11 8:29 ` Sean
2007-06-11 9:33 ` david
2007-06-11 11:34 ` Sean
2007-06-11 11:00 ` Pavel Machek
2007-06-10 21:05 ` Pavel Machek
2007-06-11 6:27 ` david
2007-06-14 19:16 ` Jack Stone
2007-06-15 0:18 ` david
2007-06-15 17:01 ` Greg KH
2007-06-12 17:03 ` Lars Marowsky-Bree
2007-06-12 17:03 ` Lars Marowsky-Bree
2007-06-09 5:18 ` david
2007-06-09 5:46 ` Sean
2007-06-09 7:13 ` david
2007-06-09 7:36 ` Sean
2007-06-09 8:06 ` david
2007-06-09 8:10 ` Sean
2007-06-09 15:17 ` Andreas Gruenbacher
2007-06-09 16:36 ` Sean
2007-06-09 15:33 ` Joshua Brindle
2007-06-09 16:18 ` Kyle Moffett
2007-06-09 16:46 ` david
2007-06-09 17:06 ` Kyle Moffett
2007-06-09 17:32 ` david
2007-06-09 19:50 ` Kyle Moffett
2007-06-09 20:43 ` david
2007-06-10 20:54 ` Crispin Cowan
2007-06-10 21:17 ` Joshua Brindle
2007-06-09 15:05 ` Andreas Gruenbacher
2007-06-10 17:09 ` Crispin Cowan
2007-06-15 16:50 ` Greg KH
2007-06-15 18:01 ` Casey Schaufler
2007-06-15 18:15 ` Stephen Smalley
2007-06-15 20:43 ` Casey Schaufler
2007-06-15 21:14 ` Greg KH
2007-06-15 21:28 ` Karl MacMillan
2007-06-15 21:44 ` Greg KH
2007-06-15 22:24 ` Karl MacMillan
2007-06-18 13:33 ` Stephen Smalley
2007-06-21 15:54 ` Andreas Gruenbacher
2007-06-15 22:37 ` Casey Schaufler
2007-06-18 12:47 ` Stephen Smalley
2007-06-15 20:06 ` Pavel Machek
2007-06-15 21:11 ` Greg KH
2007-06-15 21:42 ` James Morris
2007-06-15 23:50 ` Greg KH
2007-06-16 1:21 ` James Morris
2007-06-16 2:57 ` Casey Schaufler
2007-06-16 3:39 ` James Morris
2007-06-18 1:51 ` Casey Schaufler
2007-06-18 11:29 ` Joshua Brindle
2007-06-16 4:23 ` Greg KH
2007-06-15 23:30 ` Crispin Cowan
2007-06-15 23:49 ` Greg KH
2007-06-16 0:01 ` david
2007-06-16 0:20 ` Pavel Machek
2007-06-22 9:59 ` Andreas Gruenbacher
2007-06-16 0:31 ` Greg KH
2007-06-16 8:09 ` david
2007-06-16 16:24 ` Greg KH
2007-06-16 1:41 ` James Morris
2007-06-16 0:18 ` Seth Arnold
2007-06-16 0:29 ` Greg KH
2007-06-16 1:46 ` James Morris
2007-06-16 2:19 ` James Morris
2007-06-18 18:48 ` Crispin Cowan
2007-06-21 16:01 ` Andreas Gruenbacher
2007-06-21 17:59 ` Pavel Machek
2007-06-16 0:02 ` Pavel Machek
2007-06-21 16:08 ` Lars Marowsky-Bree
2007-06-21 16:08 ` Lars Marowsky-Bree
2007-06-21 18:33 ` Pavel Machek
2007-06-21 19:24 ` Lars Marowsky-Bree
2007-06-21 19:24 ` Lars Marowsky-Bree
2007-06-21 19:42 ` James Morris
2007-06-21 19:54 ` Lars Marowsky-Bree
2007-06-21 19:54 ` Lars Marowsky-Bree
2007-06-21 20:59 ` Stephen Smalley
2007-06-21 21:17 ` Lars Marowsky-Bree
2007-06-21 21:17 ` Lars Marowsky-Bree
2007-06-22 0:16 ` Joshua Brindle
2007-06-22 0:19 ` Lars Marowsky-Bree
2007-06-22 0:19 ` Lars Marowsky-Bree
2007-06-22 0:28 ` david
2007-06-22 3:45 ` Joshua Brindle
2007-06-22 5:07 ` david
2007-06-22 10:49 ` Lars Marowsky-Bree
2007-06-22 10:49 ` Lars Marowsky-Bree
2007-06-22 11:19 ` Stephen Smalley
2007-06-22 11:34 ` Neil Brown
2007-06-22 11:48 ` Stephen Smalley
2007-06-22 11:37 ` Lars Marowsky-Bree
2007-06-22 11:37 ` Lars Marowsky-Bree
2007-06-22 12:41 ` Stephen Smalley
2007-06-22 12:54 ` Lars Marowsky-Bree
2007-06-22 12:54 ` Lars Marowsky-Bree
2007-06-22 13:22 ` Stephen Smalley
2007-06-22 14:49 ` Stephen Smalley
2007-06-22 16:06 ` Casey Schaufler
2007-06-22 0:34 ` Chris Mason
2007-06-22 1:06 ` James Morris
2007-06-22 4:17 ` Crispin Cowan
2007-06-22 12:20 ` Stephen Smalley
2007-06-24 20:45 ` David Wagner
2007-06-22 7:40 ` John Johansen
2007-06-22 12:17 ` Chris Mason
2007-06-22 13:48 ` James Morris
2007-06-22 14:02 ` Chris Mason
2007-06-22 14:23 ` James Morris
2007-06-22 17:30 ` Chris Mason
2007-06-23 0:11 ` Chris Wright
2007-06-24 0:10 ` Toshiharu Harada
2007-06-24 0:40 ` Toshiharu Harada
2007-06-26 21:01 ` Crispin Cowan
2007-06-24 20:43 ` Pavel Machek
2007-06-22 18:12 ` david
2007-06-25 15:14 ` Pavel Machek
2007-06-25 21:02 ` david
2007-06-26 8:50 ` Lars Marowsky-Bree
2007-06-26 8:50 ` Lars Marowsky-Bree
2007-06-24 21:16 ` David Wagner
2007-06-24 21:57 ` david
2007-06-28 18:13 ` Pavel Machek
2007-06-28 18:19 ` Pavel Machek
2007-06-24 21:45 ` David Wagner
2007-06-28 18:31 ` Pavel Machek
2007-06-24 21:20 ` David Wagner
2007-06-22 8:06 ` John Johansen
2007-06-22 11:53 ` Stephen Smalley
2007-06-22 12:42 ` Lars Marowsky-Bree
2007-06-22 12:42 ` Lars Marowsky-Bree
2007-06-22 12:46 ` Stephen Smalley
2007-06-22 18:35 ` david
2007-06-24 20:48 ` David Wagner
2007-06-24 20:35 ` David Wagner
2007-06-21 20:07 ` Pavel Machek
2007-06-21 20:21 ` Lars Marowsky-Bree
2007-06-21 20:21 ` Lars Marowsky-Bree
2007-06-21 23:25 ` John Johansen
2007-06-21 19:30 ` david
2007-06-21 19:35 ` Lars Marowsky-Bree
2007-06-21 19:52 ` Pavel Machek
2007-06-16 0:48 ` [AppArmor 39/45] AppArmor: Profile loading and manipulation,pathname matching Tetsuo Handa
2007-06-19 15:25 ` Pavel Machek
2007-06-15 23:33 ` [AppArmor 39/45] AppArmor: Profile loading and manipulation, pathname matching Seth Arnold
2007-06-15 23:39 ` Pavel Machek
2007-06-16 0:07 ` Seth Arnold
2007-06-16 15:44 ` [AppArmor 39/45] AppArmor: Profile loading and manipulation,pathname matching Tetsuo Handa
2007-06-16 16:26 ` Greg KH
2007-06-16 16:45 ` [AppArmor 39/45] AppArmor: Profile loading andmanipulation,pathname matching Tetsuo Handa
2007-06-11 15:16 ` [AppArmor 39/45] AppArmor: Profile loading and manipulation, pathname matching Stephen Smalley
2007-05-14 11:06 ` [AppArmor 40/45] AppArmor: all the rest jjohansen
2007-05-14 11:06 ` [AppArmor 41/45] Add AppArmor LSM to security/Makefile jjohansen
2007-05-14 11:06 ` [AppArmor 42/45] AppArmor: add lock subtyping so lockdep does not report false dependencies jjohansen
2007-05-14 11:06 ` [AppArmor 43/45] Switch to vfs_permission() in do_path_lookup() jjohansen
2007-05-14 11:06 ` [AppArmor 44/45] Switch to vfs_permission() in sys_fchdir() jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 11:06 ` [AppArmor 45/45] Fix file_permission() jjohansen
2007-05-14 11:06 ` jjohansen
2007-05-14 13:50 ` [AppArmor 00/45] AppArmor security module overview John Johansen
-- strict thread matches above, loose matches on Subject: below --
2007-10-26 6:40 jjohansen
2007-10-26 6:41 ` [AppArmor 38/45] AppArmor: Module and LSM hooks jjohansen
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=20070514110621.316630438@suse.de \
--to=jjohansen@suse.de \
--cc=agruen@suse.de \
--cc=linux-fsdevel@vger.kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.