* [RFC][PATCH 0/11] security: AppArmor - Overview
@ 2006-04-19 17:49 Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild Tony Jones
` (13 more replies)
0 siblings, 14 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:49 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
Attached patches to include the AppArmor application security module in
the linux kernel.
An overview of AppArmor is available here
http://en.opensuse.org/Apparmor and a more detailed view here
http://en.opensuse.org/AppArmor_Detail A video of an overview and demo
of AppArmor is available here
ftp://ftp.belnet.be/pub/mirror/FOSDEM/FOSDEM2006-apparmor.avi
Overview
-----------
AppArmor is an LSM security enhancement for the Linux kernel. The
primary goal of AppArmor is to make it easy for a system administrator
to control application behavior, enforcing that the application has
access to only the files and POSIX.1e draft capabilities it requires to
do its job. AppArmor deliberately uses this simple access control model
to make it as easy as possible for the administrator to manage the
policy, because the worst security of all is that which is never
deployed because it was too hard.
AppArmor chooses which security policy to enforce for a process at
exec() time by the executable image's pathname, in conjunction with any
policy enforced for the currently running executable.
AppArmor mediates access to the file system using absolute path names
with shell-syntax wildcards, so that "/srv/htdocs/** r" grants read
access to all files in /srv/htdocs. AppArmor mediates access to POSIX.1e
Capabilities in that the process must both have e.g. "capability
net_bind_service" and intrinsically have that capability (usually by
being root) to be able to bind to privileged network ports. Thus a
confined process can not subvert AppArmor except as permitted by policy,
and can not access the file system except as permitted by the profile.
AppArmor is strictly monotonic to security: it only restricts privilege,
never enhancing privilege. So if you add AppArmor to a system, it only
becomes more secure or stays the same, the security policy will not add
vulnerabilities. Similarly, AppArmor is designed to be highly
transparent to applications: If you add AppArmor to a working system,
you have to develop AppArmor profiles, but you do not have to change
your applications. If you remove AppArmor from a running system, the
system continues to operate exactly as before, but without the AppArmor
security protections.
AppArmor is *not* intended to protect every aspect of the system from
every other aspect of the system: the intended usage is that only a
small fraction of all programs on a Linux system will have AppArmor
profiles. Rather, AppArmor is intended to protect the system against a
particular threat.
For instance, to secure a machine against network attack, all programs
that face the network should be profiled. If all open network ports lead
to AppArmor profiles, then there is no way for the network attacker to
attack the machine, except as controlled by AppArmor policy. As a
convenience, AppArmor includes a netstat wrapper that reports all
programs with open network ports and their AppArmor profile status.
AppArmor includes a training system so that a profile can be built by
exercising a program in "complain" mode where rules are not enforced but
violations are logged. User-level tools can then transform this log of
events into application security profiles by asking the user questions.
The profile generator is intelligent about not asking duplicate
questions, incrementally improving existing profiles, and suggesting
generalized alternatives to specific events, such as inserting * into
path names that appear to be library version numbers.
AppArmor has been split into two modules, the primary apparmor module
and a submodule that implements the necessary pathname matching
functions. The SuSE release of AppArmor uses a sub-module which supports
full shell pathname expansion syntax. This is achieved using a subset of
PCRE and limits on expression complexity at the userside compiler. It is
understood that this approach is not acceptable for mainline inclusion.
The version submitted here uses a simpler matching submodule that
implements literal and tailglob matches only. We plan on developing a
new submodule that will implement the missing functionality of the SuSE
release using the textsearch framework and a new bounded textsearch
algorithm acceptable for subsequent inclusion into the mainline kernel.
The features supported by the matching sub module are exposed into the
apparmor filesystem and read by the userspace parser which will prevent
unsupported policy from being loaded.
Without the use of this extended globbing module, AppArmor supports only
globs in the following form:
/path/to/files**
or:
/path/to/directory/**
Who Needs This?
-------------------
AppArmor is a core part of SUSE Linux. It has also been ported to
Slackware, Ubuntu, Gentoo, Red Hat, and Pardus Linux. AppArmor is not
"needed" but is desirable where ever an application hosted on Linux is
exposed to attack.
Patches
--------
The implementation has been broken down into 11 patches, with brief
descriptions here, and longer descriptions in each of the patch posts
that follow
1. apparmor_build.patch. Integrate into kbuild.
2. apparmor_headers.patch. Core headers.
3. apparmor_lsm.patch. LSM interface implementation.
4. apparmor_mediation.patch. Core access controls.
5. apparmor_fs.patch. AppArmor filesystem.
6. apparmor_interface.patch. Usersapce/kernelspace interface.
7. apparmor_misc.patch. Misc., including Capabilities and data
structure management.
8. apparmor_match.patch. Pathname matching submodule.
9. audit.patch. Integrate into audit subsystem.
10. dpath_flags.patch. Generate absolute path names.
11. namespace_sem.patch. Exports the namespace_sem semaphore.
The patches apply cleanly to 2.6.17-rc1 and -rc2.
Tests
------
The AppArmor team has a suite of functionality and stress tests
http://www.apparmor.org/
Bugs
----
1. The simple tail-glob pattern matching sub-module described above
needs to be replaced with a fully functional pattern matching
module that uses textsearch facilities as soon as possible.
2. AppArmor needs to re-construct the full path name of files to
perform initial validation. Some of the LSM hooks that we mediate
do not have vfsmount/nameidata passed. Our temporary workaround is
to export the namespace_sem semaphore so we can safely walk the
process's namespace to find a vfsmount with a root dentry matching
the dentry we are trying to mediate. We believe a cleaner solution
(such as passing a vfsmount or nameidata to all LSM hooks throughout
the VFS layer) would be useful for audit, other LSMs, and
potentially FUSE. As it is a fair amount of work to pass vfsmount or
nameidata structures throughout the VFS, alternative suggestions
and ideas are welcomed.
Thanks and Acknowledgment:
----------------------------------
1. AppArmor started life as Steve Beattie's thesis topic in 1996 and
has been in continuous development since.
2. Professors Virgil Gligor and Heather Hinton contributed
substantially to the initial design of AppArmor.
3. LSM was built with cooperation from a great many people; the LSM
interface reduced our long-term maintenance costs and helped raise
the visibility of mandatory access control systems among many
users. We wish to thank Stephen Smalley, James Morris, Chris
Wright, and Greg Kroah-Hartman in particular for their work on LSM.
4. The users of Immunix Linux and AppArmor on various Linuxes helped
a lot to improve the system.
5. The SUSE Security Team and the SUSE Kernel Team reviewed the
AppArmor code to help make it more ready for LKML inclusion. Of
course as usual, bugs are our own.
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
@ 2006-04-19 17:49 ` Tony Jones
2006-04-19 17:57 ` Arjan van de Ven
` (2 more replies)
2006-04-19 17:49 ` [RFC][PATCH 2/11] security: AppArmor - Core headers Tony Jones
` (12 subsequent siblings)
13 siblings, 3 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:49 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
This patch glues AppArmor into the security configuration and Makefile.
It also creates the AppArmor configuration and Makefile.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
MAINTAINERS | 7 +++++++
security/Kconfig | 1 +
security/Makefile | 1 +
security/apparmor/Kconfig | 9 +++++++++
security/apparmor/Makefile | 6 ++++++
5 files changed, 24 insertions(+)
--- linux-2.6.17-rc1.orig/MAINTAINERS
+++ linux-2.6.17-rc1/MAINTAINERS
@@ -284,6 +284,13 @@
W: http://www.canb.auug.org.au/~sfr/
S: Supported
+APPARMOR SECURITY MODULE
+P: Tony Jones
+M: tonyj@suse.de
+L: apparmor-dev@forge.novell.com
+W: http://forge.novell.com/modules/xfmod/project/?apparmor
+S: Supported
+
APPLETALK NETWORK LAYER
P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.br
--- linux-2.6.17-rc1.orig/security/Kconfig
+++ linux-2.6.17-rc1/security/Kconfig
@@ -100,6 +100,7 @@
If you are unsure how to answer this question, answer N.
source security/selinux/Kconfig
+source security/apparmor/Kconfig
endmenu
--- linux-2.6.17-rc1.orig/security/Makefile
+++ linux-2.6.17-rc1/security/Makefile
@@ -4,6 +4,7 @@
obj-$(CONFIG_KEYS) += keys/
subdir-$(CONFIG_SECURITY_SELINUX) += selinux
+subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
# if we don't select a security model, use the default capabilities
ifneq ($(CONFIG_SECURITY),y)
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/Kconfig
@@ -0,0 +1,9 @@
+config SECURITY_APPARMOR
+ tristate "AppArmor support"
+ depends on SECURITY!=n
+ help
+ This enables the AppArmor security module.
+ Required userspace tools (if they are not included in your
+ distribution) and further information may be found at
+ <http://forge.novell.com/modules/xfmod/project/?apparmor>
+ If you are unsure how to answer this question, answer N.
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/Makefile
@@ -0,0 +1,6 @@
+# Makefile for AppArmor Linux Security Module
+#
+subdir-$(CONFIG_SECURITY_APPARMOR) += match
+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
+
+apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o capabilities.o module_interface.o
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 2/11] security: AppArmor - Core headers
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild Tony Jones
@ 2006-04-19 17:49 ` Tony Jones
2006-04-19 18:01 ` Arjan van de Ven
2006-04-19 17:49 ` [RFC][PATCH 3/11] security: AppArmor - LSM interface Tony Jones
` (11 subsequent siblings)
13 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:49 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
This patch provides the various common headerfiles used by the AppArmor module.
apparmor.h contains the core data structures.
shared.h contains definitions that are common to the userspace policy loader.
inline.h implements various inline utility functions
Signed-off-by: Tony Jones <tonyj@suse.de>
---
security/apparmor/apparmor.h | 325 +++++++++++++++++++++++++++++++++++++++++
security/apparmor/inline.h | 333 +++++++++++++++++++++++++++++++++++++++++++
security/apparmor/shared.h | 41 +++++
3 files changed, 699 insertions(+)
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/apparmor.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (C) 1998-2005 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 internal prototypes
+ */
+
+#ifndef __SUBDOMAIN_H
+#define __SUBDOMAIN_H
+
+#include <linux/fs.h> /* Include for defn of iattr */
+#include <linux/rcupdate.h>
+
+#include "shared.h"
+
+/* Control parameters (0 or 1), settable thru module/boot flags or
+ * via /sys/kernel/security/apparmor/control */
+extern int apparmor_complain;
+extern int apparmor_debug;
+extern int apparmor_audit;
+extern int apparmor_logsyscall;
+
+/* PIPEFS_MAGIC */
+#include <linux/pipe_fs_i.h>
+/* from net/socket.c */
+#define SOCKFS_MAGIC 0x534F434B
+/* from inotify.c */
+#define INOTIFYFS_MAGIC 0xBAD1DEA
+
+#define VALID_FSTYPE(inode) ((inode)->i_sb->s_magic != PIPEFS_MAGIC && \
+ (inode)->i_sb->s_magic != SOCKFS_MAGIC && \
+ (inode)->i_sb->s_magic != INOTIFYFS_MAGIC)
+
+#define PROFILE_COMPLAIN(_profile) \
+ (apparmor_complain == 1 || ((_profile) && (_profile)->flags.complain))
+
+#define SUBDOMAIN_COMPLAIN(_sd) \
+ (apparmor_complain == 1 || \
+ ((_sd) && (_sd)->active && (_sd)->active->flags.complain))
+
+#define PROFILE_AUDIT(_profile) \
+ (apparmor_audit == 1 || ((_profile) && (_profile)->flags.audit))
+
+#define SUBDOMAIN_AUDIT(_sd) \
+ (apparmor_audit == 1 || \
+ ((_sd) && (_sd)->active && (_sd)->active->flags.audit))
+
+/*
+ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
+ * which is not related to profile accesses.
+ */
+
+#define AA_DEBUG(fmt, args...) \
+ do { \
+ if (apparmor_debug) \
+ printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
+ } while (0)
+#define AA_INFO(fmt, args...) printk(KERN_INFO "AppArmor: " fmt, ##args)
+#define AA_WARN(fmt, args...) printk(KERN_WARNING "AppArmor: " fmt, ##args)
+#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args)
+
+/* basic AppArmor data structures */
+
+struct flagval {
+ int debug;
+ int complain;
+ int audit;
+};
+
+enum entry_match_type {
+ aa_entry_literal,
+ aa_entry_tailglob,
+ aa_entry_pattern,
+ aa_entry_invalid
+};
+
+/* struct aa_entry - file ACL *
+ * @filename: filename controlled by this ACL
+ * @mode: permissions granted by ACL
+ * @type: type of match to perform against @filename
+ * @extradata: any extra data needed by an extended matching type
+ * @list: list the ACL is on
+ * @listp: permission partitioned lists this ACL is on.
+ *
+ * Each entry describes a file and an allowed access mode.
+ */
+struct aa_entry {
+ char *filename;
+ int mode; /* mode is 'or' of READ, WRITE, EXECUTE,
+ * INHERIT, UNCONSTRAINED, and LIBRARY
+ * (meaning don't prefetch). */
+
+ enum entry_match_type type;
+ void *extradata;
+
+ struct list_head list;
+ struct list_head listp[POS_AA_FILE_MAX + 1];
+};
+
+#define AA_EXEC_MODIFIER_MASK(mask) ((mask) & (AA_EXEC_UNCONSTRAINED |\
+ AA_EXEC_INHERIT |\
+ AA_EXEC_PROFILE))
+
+#define AA_EXEC_MASK(mask) ((mask) & (AA_MAY_EXEC |\
+ AA_EXEC_UNCONSTRAINED |\
+ AA_EXEC_INHERIT |\
+ AA_EXEC_PROFILE))
+
+
+/* struct aaprofile - basic confinement data
+ * @parent: non refcounted pointer to parent profile
+ * @name: the profiles name
+ * @file_entry: file ACL
+ * @file_entryp: vector of file ACL by permission granted
+ * @list: list this profile is on
+ * @sub: profiles list of subprofiles (HATS)
+ * @flags: flags controlling profile behavior
+ * @null_profile: if needed per profile learning and null confinement profile
+ * @isstale: flag to indicate the profile is stale
+ * @num_file_entries: number of file entries the profile contains
+ * @num_file_pentries: number of file entries for each partitioned list
+ * @capabilities: capabilities granted by the process
+ * @rcu: rcu head used when freeing the profile
+ * @count: reference count of the profile
+ *
+ * The AppArmor profile contains the basic confinement data. Each profile
+ * has a name and potentially a list of profile entries. The profiles are
+ * connected in a list
+ */
+struct aaprofile {
+ struct aaprofile *parent;
+ char *name;
+
+ struct list_head file_entry;
+ struct list_head file_entryp[POS_AA_FILE_MAX + 1];
+ struct list_head list;
+ struct list_head sub;
+ struct flagval flags;
+ struct aaprofile *null_profile;
+ int isstale;
+
+ int num_file_entries;
+ int num_file_pentries[POS_AA_FILE_MAX + 1];
+
+ kernel_cap_t capabilities;
+
+ struct rcu_head rcu;
+
+ struct kref count;
+};
+
+/**
+ * struct subdomain - primary label for confined tasks
+ * @active: the current active profile
+ * @hat_magic: the magic token controling the ability to leave a hat
+ * @list: list this subdomain is on
+ * @task: task that the subdomain confines
+ *
+ * Contains the tasks current active profile (which could change due to
+ * change_hat). Plus the hat_magic needed during change_hat.
+ *
+ * N.B AppArmor's previous product name SubDomain was derived from the name
+ * of this structure/concept (changehat reducing a task into a sub-domain).
+ */
+struct subdomain {
+ struct aaprofile *active; /* The current active profile */
+ u32 hat_magic; /* used with change_hat */
+ struct list_head list; /* list of subdomains */
+ struct task_struct *task;
+};
+
+typedef int (*aa_iter) (struct subdomain *, void *);
+
+/* aa_path_data
+ * temp (cookie) data used by aa_path_* functions, see inline.h
+ */
+struct aa_path_data {
+ struct dentry *root, *dentry;
+ struct namespace *namespace;
+ struct list_head *head, *pos;
+ int errno;
+};
+
+#define AA_SUBDOMAIN(sec) ((struct subdomain*)(sec))
+#define AA_PROFILE(sec) ((struct aaprofile*)(sec))
+
+/* Lock protecting access to 'struct subdomain' accesses */
+extern spinlock_t sd_lock;
+
+extern struct aaprofile *null_complain_profile;
+
+/* aa_audit - AppArmor auditing structure
+ * Structure is populated by access control code and passed to aa_audit which
+ * provides for a single point of logging.
+ */
+
+struct aa_audit {
+ unsigned short type, flags;
+ unsigned int result;
+ unsigned int gfp_mask;
+ int error_code;
+
+ const char *name;
+ unsigned int ival;
+ union {
+ const void *pval;
+ va_list vaval;
+ };
+};
+
+/* audit types */
+#define AA_AUDITTYPE_FILE 1
+#define AA_AUDITTYPE_DIR 2
+#define AA_AUDITTYPE_ATTR 3
+#define AA_AUDITTYPE_XATTR 4
+#define AA_AUDITTYPE_LINK 5
+#define AA_AUDITTYPE_CAP 6
+#define AA_AUDITTYPE_MSG 7
+#define AA_AUDITTYPE_SYSCALL 8
+#define AA_AUDITTYPE__END 9
+
+/* audit flags */
+#define AA_AUDITFLAG_AUDITSS_SYSCALL 1 /* log syscall context */
+#define AA_AUDITFLAG_LOGERR 2 /* log operations that failed due to
+ non permission errors */
+
+#define HINT_UNKNOWN_HAT "unknown_hat"
+#define HINT_FORK "fork"
+#define HINT_MANDPROF "missing_mandatory_profile"
+#define HINT_CHGPROF "changing_profile"
+
+#define LOG_HINT(p, gfp, hint, fmt, args...) \
+ do {\
+ aa_audit_message(p, gfp, 0, \
+ "LOGPROF-HINT " hint " " fmt, ##args);\
+ } while(0)
+
+/* directory op type, for aa_perm_dir */
+enum aa_diroptype {
+ aa_dir_mkdir,
+ aa_dir_rmdir
+};
+
+/* xattr op type, for aa_xattr */
+enum aa_xattroptype {
+ aa_xattr_get,
+ aa_xattr_set,
+ aa_xattr_list,
+ aa_xattr_remove
+};
+
+#define BASE_PROFILE(p) ((p)->parent ? (p)->parent : (p))
+#define IN_SUBPROFILE(p) ((p)->parent)
+
+/* main.c */
+extern int alloc_null_complain_profile(void);
+extern void free_null_complain_profile(void);
+extern int attach_nullprofile(struct aaprofile *profile);
+extern int aa_audit_message(struct aaprofile *active, unsigned int gfp, int,
+ const char *, ...);
+extern int aa_audit_syscallreject(struct aaprofile *active, unsigned int gfp,
+ const char *);
+extern int aa_audit(struct aaprofile *active, const struct aa_audit *);
+extern char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt);
+
+extern int aa_attr(struct aaprofile *active, struct dentry *dentry,
+ struct iattr *iattr);
+extern int aa_xattr(struct aaprofile *active, struct dentry *dentry,
+ const char *xattr, enum aa_xattroptype xattroptype);
+extern int aa_capability(struct aaprofile *active, int cap);
+extern int aa_perm(struct aaprofile *active, struct dentry *dentry,
+ struct vfsmount *mnt, int mask);
+extern int aa_perm_nameidata(struct aaprofile *active, struct nameidata *nd,
+ int mask);
+extern int aa_perm_dentry(struct aaprofile *active, struct dentry *dentry,
+ int mask);
+extern int aa_perm_dir(struct aaprofile *active, struct dentry *dentry,
+ enum aa_diroptype diroptype);
+extern int aa_link(struct aaprofile *active,
+ struct dentry *link, struct dentry *target);
+extern int aa_fork(struct task_struct *p);
+extern int aa_register(struct file *file);
+extern void aa_release(struct task_struct *p);
+extern int aa_change_hat(const char *id, u32 hat_magic);
+extern int aa_associate_filp(struct file *filp);
+
+/* list.c */
+extern struct aaprofile *aa_profilelist_find(const char *name);
+extern int aa_profilelist_add(struct aaprofile *profile);
+extern struct aaprofile *aa_profilelist_remove(const char *name);
+extern void aa_profilelist_release(void);
+extern struct aaprofile *aa_profilelist_replace(struct aaprofile *profile);
+extern void aa_profile_dump(struct aaprofile *);
+extern void aa_profilelist_dump(void);
+extern void aa_subdomainlist_add(struct subdomain *);
+extern void aa_subdomainlist_remove(struct subdomain *);
+extern void aa_subdomainlist_iterate(aa_iter, void *);
+extern void aa_subdomainlist_iterateremove(aa_iter, void *);
+extern void aa_subdomainlist_release(void);
+
+/* module_interface.c */
+extern ssize_t aa_file_prof_add(void *, size_t);
+extern ssize_t aa_file_prof_repl(void *, size_t);
+extern ssize_t aa_file_prof_remove(const char *, size_t);
+extern void free_aaprofile(struct aaprofile *profile);
+extern void free_aaprofile_kref(struct kref *kref);
+
+/* procattr.c */
+extern size_t aa_getprocattr(struct aaprofile *active, char *str, size_t size);
+extern int aa_setprocattr_changehat(char *hatinfo, size_t infosize);
+extern int aa_setprocattr_setprofile(struct task_struct *p, char *profilename,
+ size_t profilesize);
+
+/* apparmorfs.c */
+extern int create_apparmorfs(void);
+extern void destroy_apparmorfs(void);
+
+/* capabilities.c */
+extern const char *capability_to_name(unsigned int cap);
+
+#endif /* __SUBDOMAIN_H */
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/inline.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright (C) 2005 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.
+ */
+
+#ifndef __INLINE_H
+#define __INLINE_H
+
+#include <linux/namespace.h>
+
+static inline int __aa_is_confined(struct subdomain *sd)
+{
+ return (sd && sd->active);
+}
+
+/**
+ * aa_is_confined
+ * Determine whether current task contains a valid profile (confined).
+ * Return %1 if confined, %0 otherwise.
+ */
+static inline int aa_is_confined(void)
+{
+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
+ return __aa_is_confined(sd);
+}
+
+static inline int __aa_sub_defined(struct subdomain *sd)
+{
+ return __aa_is_confined(sd) && !list_empty(&BASE_PROFILE(sd->active)->sub);
+}
+
+/**
+ * aa_sub_defined - check to see if current task has any subprofiles
+ * Return 1 if true, 0 otherwise
+ */
+static inline int aa_sub_defined(void)
+{
+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
+ return __aa_sub_defined(sd);
+}
+
+/**
+ * get_aaprofile - increment refcount on profile @p
+ * @p: profile
+ */
+static inline struct aaprofile *get_aaprofile(struct aaprofile *p)
+{
+ if (p)
+ kref_get(&(BASE_PROFILE(p)->count));
+
+ return p;
+}
+
+/**
+ * put_aaprofile - decrement refcount on profile @p
+ * @p: profile
+ */
+static inline void put_aaprofile(struct aaprofile *p)
+{
+ if (p)
+ kref_put(&BASE_PROFILE(p)->count, free_aaprofile_kref);
+}
+
+/**
+ * get_task_activeptr_rcu - get pointer to @tsk's active profile.
+ * @tsk: task to get active profile from
+ *
+ * Requires rcu_read_lock is held
+ */
+static inline struct aaprofile *get_task_activeptr_rcu(struct task_struct *tsk)
+{
+ struct subdomain *sd = AA_SUBDOMAIN(tsk->security);
+ struct aaprofile *active = NULL;
+
+ if (sd)
+ active = (struct aaprofile *) rcu_dereference(sd->active);
+
+ return active;
+}
+
+/**
+ * get_activeptr_rcu - get pointer to current task's active profile
+ * Requires rcu_read_lock is held
+ */
+static inline struct aaprofile *get_activeptr_rcu(void)
+{
+ return get_task_activeptr_rcu(current);
+}
+
+/**
+ * get_task_active_aaprofile - get a reference to tsk's active profile.
+ * @tsk: the task to get the active profile reference for
+ */
+static inline struct aaprofile *get_task_active_aaprofile(struct task_struct *tsk)
+{
+ struct aaprofile *active;
+
+ rcu_read_lock();
+ active = get_aaprofile(get_task_activeptr_rcu(tsk));
+ rcu_read_unlock();
+
+ return active;
+}
+
+/**
+ * get_active_aaprofile - get a reference to the current tasks active profile
+ */
+static inline struct aaprofile *get_active_aaprofile(void)
+{
+ return get_task_active_aaprofile(current);
+}
+
+/**
+ * aa_switch - change subdomain to use a new profile
+ * @sd: subdomain to switch the active profile on
+ * @newactive: new active profile
+ *
+ * aa_switch handles the changing of a subdomain's active profile. The
+ * sd_lock must be held to ensure consistency against other writers.
+ * Some write paths (ex. aa_register) require sd->active not to change
+ * over several operations, so the calling function is responsible
+ * for grabing the sd_lock to meet its consistency constraints before
+ * calling aa_switch
+ */
+static inline void aa_switch(struct subdomain *sd, struct aaprofile *newactive)
+{
+ struct aaprofile *oldactive = sd->active;
+
+ /* noop if NULL */
+ rcu_assign_pointer(sd->active, get_aaprofile(newactive));
+ put_aaprofile(oldactive);
+}
+
+/**
+ * aa_switch_unconfined - change subdomain to be unconfined (no profile)
+ * @sd: subdomain to switch
+ *
+ * aa_switch_unconfined handles the removal of a subdomain's active profile.
+ * The sd_lock must be held to ensure consistency against other writers.
+ * Like aa_switch the sd_lock is used to maintain consistency.
+ */
+static inline void aa_switch_unconfined(struct subdomain *sd)
+{
+ aa_switch(sd, NULL);
+
+ /* reset magic in case we were in a subhat before */
+ sd->hat_magic = 0;
+}
+
+/**
+ * alloc_subdomain - allocate a new subdomain
+ * @tsk: task struct
+ *
+ * Allocate a new subdomain including a backpointer to it's referring task.
+ */
+static inline struct subdomain *alloc_subdomain(struct task_struct *tsk)
+{
+ struct subdomain *sd;
+
+ sd = kzalloc(sizeof(struct subdomain), GFP_KERNEL);
+ if (!sd)
+ goto out;
+
+ /* back pointer to task */
+ sd->task = tsk;
+
+ /* any readers of the list must make sure that they can handle
+ * case where sd->active is not yet set (null)
+ */
+ aa_subdomainlist_add(sd);
+
+out:
+ return sd;
+}
+
+/**
+ * free_subdomain - Free a subdomain previously allocated by alloc_subdomain
+ * @sd: subdomain
+ */
+static inline void free_subdomain(struct subdomain *sd)
+{
+ aa_subdomainlist_remove(sd);
+ kfree(sd);
+}
+
+/**
+ * alloc_aaprofile - Allocate, initialize and return a new zeroed profile.
+ * Returns NULL on failure.
+ */
+static inline struct aaprofile *alloc_aaprofile(void)
+{
+ struct aaprofile *profile;
+
+ profile = (struct aaprofile *)kzalloc(sizeof(struct aaprofile),
+ GFP_KERNEL);
+ AA_DEBUG("%s(%p)\n", __FUNCTION__, profile);
+ if (profile) {
+ int i;
+
+ INIT_LIST_HEAD(&profile->list);
+ INIT_LIST_HEAD(&profile->sub);
+ INIT_LIST_HEAD(&profile->file_entry);
+ for (i = 0; i <= POS_AA_FILE_MAX; i++) {
+ INIT_LIST_HEAD(&profile->file_entryp[i]);
+ }
+ INIT_RCU_HEAD(&profile->rcu);
+ kref_init(&profile->count);
+ }
+ return profile;
+}
+
+/**
+ * aa_put_name
+ * @name: name to release.
+ *
+ * Release space (free_page) allocated to hold pathname
+ * name may be NULL (checked for by free_page)
+ */
+static inline void aa_put_name(const char *name)
+{
+ free_page((unsigned long)name);
+}
+
+/** __aa_find_profile
+ * @name: name of profile to find
+ * @head: list to search
+ *
+ * Return reference counted copy of profile. NULL if not found
+ * Caller must hold any necessary locks
+ */
+static inline struct aaprofile *__aa_find_profile(const char *name,
+ struct list_head *head)
+{
+ struct aaprofile *p;
+
+ if (!name || !head)
+ return NULL;
+
+ AA_DEBUG("%s: finding profile %s\n", __FUNCTION__, name);
+ list_for_each_entry(p, head, list) {
+ if (!strcmp(p->name, name)) {
+ /* return refcounted object */
+ p = get_aaprofile(p);
+ return p;
+ } else {
+ AA_DEBUG("%s: skipping %s\n", __FUNCTION__, p->name);
+ }
+ }
+ return NULL;
+}
+
+/** __aa_path_begin
+ * @rdentry: filesystem root dentry (searching for vfsmnts matching this)
+ * @dentry: dentry object to obtain pathname from (relative to matched vfsmnt)
+ *
+ * Setup data for iterating over vfsmounts (in current tasks namespace).
+ */
+static inline void __aa_path_begin(struct dentry *rdentry,
+ struct dentry *dentry,
+ struct aa_path_data *data)
+{
+ data->dentry = dentry;
+ data->root = dget(rdentry->d_sb->s_root);
+ data->namespace = current->namespace;
+ data->head = &data->namespace->list;
+ data->pos = data->head->next;
+ prefetch(data->pos->next);
+ data->errno = 0;
+
+ down_read(&namespace_sem);
+}
+
+/** aa_path_begin
+ * @dentry: filesystem root dentry and object to obtain pathname from
+ *
+ * Utility function for calling _aa_path_begin for when the dentry we are
+ * looking for and the root are the same (this is the usual case).
+ */
+static inline void aa_path_begin(struct dentry *dentry,
+ struct aa_path_data *data)
+{
+ __aa_path_begin(dentry, dentry, data);
+}
+
+/** aa_path_end
+ * @data: data object previously initialized by aa_path_begin
+ *
+ * End iterating over vfsmounts.
+ * If an error occured in begin or get, it is returned. Otherwise 0.
+ */
+static inline int aa_path_end(struct aa_path_data *data)
+{
+ up_read(&namespace_sem);
+ dput(data->root);
+
+ return data->errno;
+}
+
+/** aa_path_getname
+ * @data: data object previously initialized by aa_path_begin
+ *
+ * Return the next mountpoint which has the same root dentry as data->root.
+ * If no more mount points exist (or in case of error) NULL is returned
+ * (caller should call aa_path_end() and inspect return code to differentiate)
+ */
+static inline char *aa_path_getname(struct aa_path_data *data)
+{
+ char *name = NULL;
+ struct vfsmount *mnt;
+
+ while (data->pos != data->head) {
+ mnt = list_entry(data->pos, struct vfsmount, mnt_list);
+
+ /* advance to next -- so that it is done before we break */
+ data->pos = data->pos->next;
+ prefetch(data->pos->next);
+
+ if (mnt->mnt_root == data->root) {
+ name = aa_get_name(data->dentry, mnt);
+ if (!name)
+ data->errno = -ENOMEM;
+ break;
+ }
+ }
+
+ return name;
+}
+
+#endif /* __INLINE_H__ */
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/shared.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2000, 2001, 2004, 2005 Novell/SUSE
+ *
+ * Immunix AppArmor LSM
+ *
+ * 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.
+ */
+
+#ifndef _SHARED_H
+#define _SHARED_H
+
+/* start of system offsets */
+#define POS_AA_FILE_MIN 0
+#define POS_AA_MAY_EXEC POS_AA_FILE_MIN
+#define POS_AA_MAY_WRITE (POS_AA_MAY_EXEC + 1)
+#define POS_AA_MAY_READ (POS_AA_MAY_WRITE + 1)
+#define POS_AA_MAY_APPEND (POS_AA_MAY_READ + 1)
+/* end of system offsets */
+
+#define POS_AA_MAY_LINK (POS_AA_MAY_APPEND + 1)
+#define POS_AA_EXEC_INHERIT (POS_AA_MAY_LINK + 1)
+#define POS_AA_EXEC_UNCONSTRAINED (POS_AA_EXEC_INHERIT + 1)
+#define POS_AA_EXEC_PROFILE (POS_AA_EXEC_UNCONSTRAINED + 1)
+#define POS_AA_FILE_MAX POS_AA_EXEC_PROFILE
+
+/* Modeled after MAY_READ, MAY_WRITE, MAY_EXEC def'ns */
+#define AA_MAY_EXEC (0x01 << POS_AA_MAY_EXEC)
+#define AA_MAY_WRITE (0x01 << POS_AA_MAY_WRITE)
+#define AA_MAY_READ (0x01 << POS_AA_MAY_READ)
+#define AA_MAY_LINK (0x01 << POS_AA_MAY_LINK)
+#define AA_EXEC_INHERIT (0x01 << POS_AA_EXEC_INHERIT)
+#define AA_EXEC_UNCONSTRAINED (0x01 << POS_AA_EXEC_UNCONSTRAINED)
+#define AA_EXEC_PROFILE (0x01 << POS_AA_EXEC_PROFILE)
+#define AA_EXEC_MODIFIERS(X) (X & (AA_EXEC_INHERIT | \
+ A_EXEC_UNCONSTRAINED | \
+ AA_EXEC_PROFILE))
+
+#endif /* _SHARED_H */
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 3/11] security: AppArmor - LSM interface
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 2/11] security: AppArmor - Core headers Tony Jones
@ 2006-04-19 17:49 ` Tony Jones
2006-04-19 18:05 ` Arjan van de Ven
2006-04-19 17:49 ` [RFC][PATCH 4/11] security: AppArmor - Core access controls Tony Jones
` (10 subsequent siblings)
13 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:49 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
Implements the lsm interface used by AppArmor.
The code composes the functionality provided by commoncap therefore there
is no requirement for it to stack with the capability module.
See linux/include/security.h for a full description of all the LSM hooks.
Consistency of the subdomain (task) data is implemented on the reader side
via rcu. Logical consistency across profile replacement/removal and change
hat is provided via the spinlock sd_lock. Since profile manipulation and
change_hat are infrequent, most syscall accesses requires no spin lock.
Certain syscalls are prevented for confined processes. These are:
ptrace
mount
umount
sysctl writes also require CAP_SYS_ADMIN
File access checks are performed when a file is initially opened
(inode_permission) and cached to avoid revalidation unless where necessary
(passing descriptors between tasks confined with differing profiles, and
profile replacement, for example). Further patches are in development
to support caching of multiple profiles against an open file to minimise
the need for subsequent revalidation across profiles.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
security/apparmor/lsm.c | 840 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 840 insertions(+)
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/lsm.c
@@ -0,0 +1,840 @@
+/*
+ * Copyright (C) 2002-2005 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.
+ *
+ * http://forge.novell.com/modules/xfmod/project/?apparmor
+ *
+ * Immunix AppArmor LSM interface
+ */
+
+#include <linux/security.h>
+#include <linux/module.h>
+#include <linux/mman.h>
+
+#include "apparmor.h"
+#include "inline.h"
+
+/* struct subdomain write update lock (read side is RCU). */
+spinlock_t sd_lock = SPIN_LOCK_UNLOCKED;
+
+/* Flag values, also controllable via apparmorfs/control.
+ * We explicitly do not allow these to be modifiable when exported via
+ * /sys/modules/parameters, as we want to do additional mediation and
+ * don't want to add special path code. */
+
+/* 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, int, S_IRUSR);
+MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode");
+
+/* Debug mode */
+int apparmor_debug = 0;
+module_param_named(debug, apparmor_debug, int, S_IRUSR);
+MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode");
+
+/* Audit mode */
+int apparmor_audit = 0;
+module_param_named(audit, apparmor_audit, int, S_IRUSR);
+MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode");
+
+/* Syscall logging mode */
+int apparmor_logsyscall = 0;
+module_param_named(logsyscall, apparmor_logsyscall, int, S_IRUSR);
+MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode");
+
+#ifndef MODULE
+static int __init aa_getopt_complain(char *str)
+{
+ get_option(&str, &apparmor_complain);
+ return 1;
+}
+__setup("apparmor_complain=", aa_getopt_complain);
+
+static int __init aa_getopt_debug(char *str)
+{
+ get_option(&str, &apparmor_debug);
+ return 1;
+}
+__setup("apparmor_debug=", aa_getopt_debug);
+
+static int __init aa_getopt_audit(char *str)
+{
+ get_option(&str, &apparmor_audit);
+ return 1;
+}
+__setup("apparmor_audit=", aa_getopt_audit);
+
+static int __init aa_getopt_logsyscall(char *str)
+{
+ get_option(&str, &apparmor_logsyscall);
+ return 1;
+}
+__setup("apparmor_logsyscall=", aa_getopt_logsyscall);
+#endif
+
+static int apparmor_ptrace(struct task_struct *parent,
+ struct task_struct *child)
+{
+ int error;
+ struct aaprofile *active;
+
+ error = cap_ptrace(parent, child);
+
+ active = get_active_aaprofile();
+
+ if (!error && active) {
+ error = aa_audit_syscallreject(active, GFP_KERNEL, "ptrace");
+ WARN_ON(error != -EPERM);
+ }
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_capget(struct task_struct *target,
+ kernel_cap_t *effective,
+ kernel_cap_t *inheritable,
+ kernel_cap_t *permitted)
+{
+ return cap_capget(target, effective, inheritable, permitted);
+}
+
+static int apparmor_capset_check(struct task_struct *target,
+ kernel_cap_t *effective,
+ kernel_cap_t *inheritable,
+ kernel_cap_t *permitted)
+{
+ return cap_capset_check(target, effective, inheritable, permitted);
+}
+
+static void apparmor_capset_set(struct task_struct *target,
+ kernel_cap_t *effective,
+ kernel_cap_t *inheritable,
+ kernel_cap_t *permitted)
+{
+ cap_capset_set(target, effective, inheritable, permitted);
+ return;
+}
+
+static int apparmor_capable(struct task_struct *tsk, int cap)
+{
+ int error;
+
+ /* cap_capable returns 0 on success, else -EPERM */
+ error = cap_capable(tsk, cap);
+
+ if (error == 0) {
+ struct aaprofile *active;
+
+ active = get_task_active_aaprofile(tsk);
+
+ if (active)
+ error = aa_capability(active, cap);
+
+ put_aaprofile(active);
+ }
+
+ return error;
+}
+
+static int apparmor_sysctl(struct ctl_table *table, int op)
+{
+ int error = 0;
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+
+ if ((op & 002) && active && !capable(CAP_SYS_ADMIN)) {
+ error = aa_audit_syscallreject(active, GFP_KERNEL,
+ "sysctl (write)");
+ WARN_ON(error != -EPERM);
+ }
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_syslog(int type)
+{
+ return cap_syslog(type);
+}
+
+static int apparmor_netlink_send(struct sock *sk, struct sk_buff *skb)
+{
+ return cap_netlink_send(sk, skb);
+}
+
+static int apparmor_netlink_recv(struct sk_buff *skb)
+{
+ return cap_netlink_recv(skb);
+}
+
+static void apparmor_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
+{
+ cap_bprm_apply_creds(bprm, unsafe);
+ return;
+}
+
+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->file);
+}
+
+static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type,
+ unsigned long flags, void *data)
+{
+ int error = 0;
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+
+ if (active) {
+ error = aa_audit_syscallreject(active, GFP_KERNEL, "mount");
+ WARN_ON(error != -EPERM);
+ }
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_umount(struct vfsmount *mnt, int flags)
+{
+ int error = 0;
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+
+ if (active) {
+ error = aa_audit_syscallreject(active, GFP_KERNEL, "umount");
+ WARN_ON(error != -EPERM);
+ }
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_inode_mkdir(struct inode *inode, struct dentry *dentry,
+ int mask)
+{
+ struct aaprofile *active;
+ int error = 0;
+
+ active = get_active_aaprofile();
+
+ if (active)
+ error = aa_perm_dir(active, dentry, aa_dir_mkdir);
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_inode_rmdir(struct inode *inode, struct dentry *dentry)
+{
+ struct aaprofile *active;
+ int error = 0;
+
+ active = get_active_aaprofile();
+
+ if (active)
+ error = aa_perm_dir(active, dentry, aa_dir_rmdir);
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_inode_create(struct inode *inode, struct dentry *dentry,
+ int mask)
+{
+ struct aaprofile *active;
+ int error = 0;
+
+ active = get_active_aaprofile();
+
+ /* At a minimum, need write perm to create */
+ if (active)
+ error = aa_perm_dentry(active, dentry, MAY_WRITE);
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_inode_link(struct dentry *old_dentry, struct inode *inode,
+ struct dentry *new_dentry)
+{
+ int error = 0;
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+
+ if (active)
+ error = aa_link(active, new_dentry, old_dentry);
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_inode_unlink(struct inode *inode, struct dentry *dentry)
+{
+ struct aaprofile *active;
+ int error = 0;
+
+ active = get_active_aaprofile();
+
+ if (active)
+ error = aa_perm_dentry(active, dentry, MAY_WRITE);
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_inode_mknod(struct inode *inode, struct dentry *dentry,
+ int mode, dev_t dev)
+{
+ struct aaprofile *active;
+ int error = 0;
+
+ active = get_active_aaprofile();
+
+ if (active)
+ error = aa_perm_dentry(active, dentry, MAY_WRITE);
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_inode_rename(struct inode *old_inode,
+ struct dentry *old_dentry,
+ struct inode *new_inode,
+ struct dentry *new_dentry)
+{
+ struct aaprofile *active;
+ int error = 0;
+
+ active = get_active_aaprofile();
+
+ if (active) {
+ error = aa_perm_dentry(active, old_dentry, MAY_READ |
+ MAY_WRITE);
+
+ if (!error)
+ error = aa_perm_dentry(active, new_dentry,
+ MAY_WRITE);
+ }
+
+ put_aaprofile(active);
+
+ return error;
+}
+
+static int apparmor_inode_permission(struct inode *inode, int mask,
+ struct nameidata *nd)
+{
+ int error = 0;
+
+ /* Do not perform check on pipes or sockets
+ * Same as apparmor_file_permission
+ */
+ if (VALID_FSTYPE(inode)) {
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+ if (active)
+ error = aa_perm_nameidata(active, nd, mask);
+ put_aaprofile(active);
+ }
+
+ return error;
+}
+
+static int apparmor_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+ int error = 0;
+
+ if (VALID_FSTYPE(dentry->d_inode)) {
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+ /*
+ * Mediate any attempt to change attributes of a file
+ * (chmod, chown, chgrp, etc)
+ */
+ if (active)
+ error = aa_attr(active, dentry, iattr);
+
+ put_aaprofile(active);
+ }
+
+ return error;
+}
+
+static int apparmor_inode_setxattr(struct dentry *dentry, char *name,
+ void *value, size_t size, int flags)
+{
+ int error = 0;
+
+ if (VALID_FSTYPE(dentry->d_inode)) {
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+ if (active)
+ error = aa_xattr(active, dentry, name, aa_xattr_set);
+ put_aaprofile(active);
+ }
+
+ return error;
+}
+
+static int apparmor_inode_getxattr(struct dentry *dentry, char *name)
+{
+ int error = 0;
+
+ if (VALID_FSTYPE(dentry->d_inode)) {
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+ if (active)
+ error = aa_xattr(active, dentry, name, aa_xattr_get);
+ put_aaprofile(active);
+ }
+
+ return error;
+}
+static int apparmor_inode_listxattr(struct dentry *dentry)
+{
+ int error = 0;
+
+ if (VALID_FSTYPE(dentry->d_inode)) {
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+ if (active)
+ error = aa_xattr(active, dentry, NULL, aa_xattr_list);
+ put_aaprofile(active);
+ }
+
+ return error;
+}
+
+static int apparmor_inode_removexattr(struct dentry *dentry, char *name)
+{
+ int error = 0;
+
+ if (VALID_FSTYPE(dentry->d_inode)) {
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+ if (active)
+ error = aa_xattr(active, dentry, name,
+ aa_xattr_remove);
+ put_aaprofile(active);
+ }
+
+ return error;
+}
+
+static int apparmor_file_permission(struct file *file, int mask)
+{
+ struct aaprofile *active;
+ struct aaprofile *f_profile;
+ int error = 0;
+
+ f_profile = AA_PROFILE(file->f_security);
+ /* bail out early if this isn't a mediated file */
+ if (!(f_profile && VALID_FSTYPE(file->f_dentry->d_inode)))
+ goto out;
+
+ active = get_active_aaprofile();
+ if (active && f_profile != active)
+ error = aa_perm(active, file->f_dentry, file->f_vfsmnt,
+ mask & (MAY_EXEC | MAY_WRITE | MAY_READ));
+ put_aaprofile(active);
+
+out:
+ return error;
+}
+
+static int apparmor_file_alloc_security(struct file *file)
+{
+ struct aaprofile *active;
+
+ active = get_active_aaprofile();
+ file->f_security = get_aaprofile(active);
+ put_aaprofile(active);
+
+ return 0;
+}
+
+static void apparmor_file_free_security(struct file *file)
+{
+ struct aaprofile *p = AA_PROFILE(file->f_security);
+ put_aaprofile(p);
+}
+
+static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
+ unsigned long prot, unsigned long flags)
+{
+ int error = 0, mask = 0;
+ struct aaprofile *active;
+
+ if (!file)
+ goto out;
+
+ active = get_active_aaprofile();
+
+ 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 |= MAY_EXEC;
+
+ AA_DEBUG("%s: 0x%x\n", __FUNCTION__, mask);
+
+ error = aa_perm(active, file->f_dentry, file->f_vfsmnt, mask);
+
+ put_aaprofile(active);
+
+out:
+ return error;
+}
+
+static int apparmor_task_alloc_security(struct task_struct *p)
+{
+ return aa_fork(p);
+}
+
+static void apparmor_task_free_security(struct task_struct *p)
+{
+ aa_release(p);
+}
+
+static int apparmor_task_post_setuid(uid_t id0, uid_t id1, uid_t id2,
+ int flags)
+{
+ return cap_task_post_setuid(id0, id1, id2, flags);
+}
+
+static void apparmor_task_reparent_to_init(struct task_struct *p)
+{
+ cap_task_reparent_to_init(p);
+ return;
+}
+
+static int apparmor_getprocattr(struct task_struct *p, char *name, void *value,
+ size_t size)
+{
+ int error;
+ struct aaprofile *active;
+ char *str = value;
+
+ /* Subdomain only supports the "current" process attribute */
+ if (strcmp(name, "current") != 0) {
+ error = -EINVAL;
+ goto out;
+ }
+
+ if (!size) {
+ error = -ERANGE;
+ goto out;
+ }
+
+ /* must be task querying itself or admin */
+ if (current != p && !capable(CAP_SYS_ADMIN)) {
+ error = -EPERM;
+ goto out;
+ }
+
+ active = get_task_active_aaprofile(p);
+ error = aa_getprocattr(active, str, size);
+ put_aaprofile(active);
+
+out:
+ return error;
+}
+
+static int apparmor_setprocattr(struct task_struct *p, char *name, void *value,
+ size_t size)
+{
+ const char *cmd_changehat = "changehat ",
+ *cmd_setprofile = "setprofile ";
+
+ int error = -EACCES; /* default to a perm denied */
+ char *cmd = (char *)value;
+
+ /* only support messages to current */
+ if (strcmp(name, "current") != 0) {
+ error = -EINVAL;
+ goto out;
+ }
+
+ if (!size) {
+ error = -ERANGE;
+ goto out;
+ }
+
+ /* CHANGE HAT -- switch task into a subhat (subprofile) if defined */
+ if (size > strlen(cmd_changehat) &&
+ strncmp(cmd, cmd_changehat, strlen(cmd_changehat)) == 0) {
+ char *hatinfo = cmd + strlen(cmd_changehat);
+ size_t infosize = size - strlen(cmd_changehat);
+
+ /* Only the current process may change it's hat */
+ if (current != p) {
+ AA_WARN("%s: Attempt by foreign task %s(%d) "
+ "[user %d] to changehat of task %s(%d)\n",
+ __FUNCTION__,
+ current->comm,
+ current->pid,
+ current->uid,
+ p->comm,
+ p->pid);
+
+ error = -EACCES;
+ goto out;
+ }
+
+ error = aa_setprocattr_changehat(hatinfo, infosize);
+ if (error == 0)
+ /* success, set return to #bytes in orig request */
+ error = size;
+
+ /* SET NEW PROFILE */
+ } else if (size > strlen(cmd_setprofile) &&
+ strncmp(cmd, cmd_setprofile, strlen(cmd_setprofile)) == 0) {
+ struct aaprofile *active;
+
+ /* only an unconfined process with admin capabilities
+ * may change the profile of another task
+ */
+
+ if (!capable(CAP_SYS_ADMIN)) {
+ AA_WARN("%s: Unprivileged attempt by task %s(%d) "
+ "[user %d] to assign profile to task %s(%d)\n",
+ __FUNCTION__,
+ current->comm,
+ current->pid,
+ current->uid,
+ p->comm,
+ p->pid);
+ error = -EACCES;
+ goto out;
+ }
+
+ active = get_active_aaprofile();
+ if (!active) {
+ char *profile = cmd + strlen(cmd_setprofile);
+ size_t profilesize = size - strlen(cmd_setprofile);
+
+ error = aa_setprocattr_setprofile(p, profile, profilesize);
+ if (error == 0)
+ /* success,
+ * set return to #bytes in orig request
+ */
+ error = size;
+ } else {
+ AA_WARN("%s: Attempt by confined task %s(%d) "
+ "[user %d] to assign profile to task %s(%d)\n",
+ __FUNCTION__,
+ current->comm,
+ current->pid,
+ current->uid,
+ p->comm,
+ p->pid);
+
+ error = -EACCES;
+ }
+ put_aaprofile(active);
+ } else {
+ /* unknown operation */
+ AA_WARN("%s: Unknown setprocattr command '%.*s' by task %s(%d) "
+ "[user %d] for task %s(%d)\n",
+ __FUNCTION__,
+ size < 16 ? (int)size : 16,
+ cmd,
+ current->comm,
+ current->pid,
+ current->uid,
+ p->comm,
+ p->pid);
+
+ error = -EINVAL;
+ }
+
+out:
+ return error;
+}
+
+struct security_operations apparmor_ops = {
+ .ptrace = apparmor_ptrace,
+ .capget = apparmor_capget,
+ .capset_check = apparmor_capset_check,
+ .capset_set = apparmor_capset_set,
+ .sysctl = apparmor_sysctl,
+ .capable = apparmor_capable,
+ .syslog = apparmor_syslog,
+
+ .netlink_send = apparmor_netlink_send,
+ .netlink_recv = apparmor_netlink_recv,
+
+ .bprm_apply_creds = apparmor_bprm_apply_creds,
+ .bprm_set_security = apparmor_bprm_set_security,
+
+ .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_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,
+
+ .task_alloc_security = apparmor_task_alloc_security,
+ .task_free_security = apparmor_task_free_security,
+ .task_post_setuid = apparmor_task_post_setuid,
+ .task_reparent_to_init = apparmor_task_reparent_to_init,
+
+ .getprocattr = apparmor_getprocattr,
+ .setprocattr = apparmor_setprocattr,
+};
+
+static int __init apparmor_init(void)
+{
+ int error;
+ const char *complainmsg = ": complainmode enabled";
+
+ 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;
+ }
+
+ AA_INFO("AppArmor initialized%s\n",
+ apparmor_complain ? complainmsg : "");
+ aa_audit_message(NULL, GFP_KERNEL, 0,
+ "AppArmor initialized%s\n",
+ apparmor_complain ? complainmsg : "");
+
+ return error;
+
+register_security_out:
+ free_null_complain_profile();
+
+alloc_out:
+ (void)destroy_apparmorfs();
+
+createfs_out:
+ return error;
+
+}
+
+static int apparmor_exit_removeall_iter(struct subdomain *sd, void *cookie)
+{
+ /* spin_lock(&sd_lock) held here */
+
+ if (__aa_is_confined(sd)) {
+ AA_DEBUG("%s: Dropping profiles %s(%d) "
+ "profile %s(%p) active %s(%p)\n",
+ __FUNCTION__,
+ sd->task->comm, sd->task->pid,
+ BASE_PROFILE(sd->active)->name,
+ BASE_PROFILE(sd->active),
+ sd->active->name, sd->active);
+ aa_switch_unconfined(sd);
+ }
+
+ return 0;
+}
+
+static void __exit apparmor_exit(void)
+{
+ unsigned long flags;
+
+ /* Remove profiles from the global profile list.
+ * This is just for tidyness as there is no way to reference this
+ * list once the AppArmor lsm hooks are detached (below)
+ */
+ aa_profilelist_release();
+
+ /* Remove profiles from active tasks
+ * If this is not done, if module is reloaded after being removed,
+ * old profiles (still refcounted in memory) will become 'magically'
+ * reattached
+ */
+
+ spin_lock_irqsave(&sd_lock, flags);
+ aa_subdomainlist_iterate(apparmor_exit_removeall_iter, NULL);
+ spin_unlock_irqrestore(&sd_lock, flags);
+
+ /* Free up list of active subdomain */
+ aa_subdomainlist_release();
+
+ free_null_complain_profile();
+
+ destroy_apparmorfs();
+
+ if (unregister_security(&apparmor_ops))
+ AA_WARN("Unable to properly unregister AppArmor\n");
+
+ /* delay for an rcu cycle to make ensure that profiles pending
+ * destruction in the rcu callback are freed.
+ */
+ synchronize_rcu();
+
+ AA_INFO("AppArmor protection removed\n");
+ aa_audit_message(NULL, GFP_KERNEL, 0,
+ "AppArmor protection removed\n");
+}
+
+security_initcall(apparmor_init);
+module_exit(apparmor_exit);
+
+MODULE_DESCRIPTION("AppArmor process confinement");
+MODULE_AUTHOR("Tony Jones <tonyj@suse.de>");
+MODULE_LICENSE("GPL");
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (2 preceding siblings ...)
2006-04-19 17:49 ` [RFC][PATCH 3/11] security: AppArmor - LSM interface Tony Jones
@ 2006-04-19 17:49 ` Tony Jones
2006-04-19 18:10 ` Arjan van de Ven
` (3 more replies)
2006-04-19 17:49 ` [RFC][PATCH 5/11] security: AppArmor - Filesystem Tony Jones
` (9 subsequent siblings)
13 siblings, 4 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:49 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
This patch implements core AppArmor access control (where appropriate using
functionality provided by the sub matching module [apparmor_match]), code to
assign policy (subdomains and by connection profiles) to tasks during task
creation, remove them during task release and for determining appropiate
confinement upon domain changes (exec). It is also responsible for the low
level implementation of change_hat, switching confined tasks between their
primary and child profiles. Finally it implements the interface to the kernel
audit subsystem through which enforcement and learning events are passed to
userspace.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
security/apparmor/main.c | 1618 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 1618 insertions(+)
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/main.c
@@ -0,0 +1,1618 @@
+/*
+ * Copyright (C) 2002-2005 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 Core
+ */
+
+#include <linux/security.h>
+#include <linux/namei.h>
+#include <linux/audit.h>
+
+#include "apparmor.h"
+#include "match/match.h"
+
+#include "inline.h"
+
+/* NULL complain profile
+ *
+ * Used when in complain mode, to emit Permitting messages for non-existant
+ * profiles and hats. This is necessary because of selective mode, in which
+ * case we need a complain null_profile and enforce null_profile
+ *
+ * The null_complain_profile cannot be statically allocated, because it
+ * can be associated to files which keep their reference even if subdomain is
+ * unloaded
+ */
+struct aaprofile *null_complain_profile;
+
+/***************************
+ * Private utility functions
+ **************************/
+
+/**
+ * aa_taskattr_access
+ * @procrelname: name of file to check permission
+ *
+ * Determine if request is for write access to /proc/self/attr/current
+ * This file is the usermode iterface for changing it's hat.
+ */
+static inline int aa_taskattr_access(const char *procrelname)
+{
+ char buf[sizeof("/attr/current") + 10];
+ const int maxbuflen = sizeof(buf);
+ /* assumption, 32bit pid (10 decimal digits incl \0) */
+
+ snprintf(buf, maxbuflen, "%d/attr/current", current->pid);
+ buf[maxbuflen - 1] = 0;
+
+ return strcmp(buf, procrelname) == 0;
+}
+
+/**
+ * aa_file_mode - get full mode for file entry from profile
+ * @profile: profile
+ * @name: filename
+ */
+static inline int aa_file_mode(struct aaprofile *profile, const char *name)
+{
+ struct aa_entry *entry;
+ int mode = 0;
+
+ AA_DEBUG("%s: %s\n", __FUNCTION__, name);
+ if (!name) {
+ AA_DEBUG("%s: no name\n", __FUNCTION__);
+ goto out;
+ }
+
+ if (!profile) {
+ AA_DEBUG("%s: no profile\n", __FUNCTION__);
+ goto out;
+ }
+ list_for_each_entry(entry, &profile->file_entry, list) {
+ if (aamatch_match(name, entry->filename,
+ entry->type, entry->extradata))
+ mode |= entry->mode;
+ }
+out:
+ return mode;
+}
+
+/**
+ * aa_get_execmode - calculate what qualifier to apply to an exec
+ * @active: profile to search
+ * @name: name of file to exec
+ * @xmod: pointer to a execution mode bit for the rule that was matched
+ * if the rule has no execuition qualifier {pui} then
+ * %AA_MAY_EXEC is returned indicating a naked x
+ * if the has an exec qualifier then only the qualifier bit {pui}
+ * is returned (%AA_MAY_EXEC) is not set.
+ *
+ * Returns %0 (false):
+ * if unable to find profile or there are conflicting pattern matches.
+ * *xmod - is not modified
+ *
+ * Returns %1 (true):
+ * if not confined
+ * *xmod = %AA_MAY_EXEC
+ * if exec rule matched
+ * if the rule has an execution mode qualifier {pui} then
+ * *xmod = the execution qualifier of the rule {pui}
+ * else
+ * *xmod = %AA_MAY_EXEC
+ */
+static inline int aa_get_execmode(struct aaprofile *active, const char *name,
+ int *xmod)
+{
+ struct aa_entry *entry;
+ struct aa_entry *match = NULL;
+
+ int pattern_match_invalid = 0, rc = 0;
+
+ /* search list of profiles with 'x' permission
+ * this will also include entries with 'p', 'u' and 'i'
+ * qualifiers.
+ *
+ * If we find a pattern match we will keep looking for an exact match
+ * If we find conflicting pattern matches we will flag (while still
+ * looking for an exact match). If all we have is a conflict, FALSE
+ * is returned.
+ */
+
+ list_for_each_entry(entry, &active->file_entryp[POS_AA_MAY_EXEC],
+ listp[POS_AA_MAY_EXEC]) {
+ if (!pattern_match_invalid &&
+ entry->type == aa_entry_pattern &&
+ aamatch_match(name, entry->filename,
+ entry->type, entry->extradata)) {
+ if (match &&
+ AA_EXEC_MASK(entry->mode) !=
+ AA_EXEC_MASK(match->mode))
+ pattern_match_invalid = 1;
+ else
+ /* keep searching for an exact match */
+ match = entry;
+ } else if ((entry->type == aa_entry_literal ||
+ (!pattern_match_invalid &&
+ entry->type == aa_entry_tailglob)) &&
+ aamatch_match(name, entry->filename,
+ entry->type,
+ entry->extradata)) {
+ if (entry->type == aa_entry_literal) {
+ /* got an exact match -- there can be only
+ * one, asserted at profile load time
+ */
+ match = entry;
+ pattern_match_invalid = 0;
+ break;
+ } else {
+ if (match &&
+ AA_EXEC_MASK(entry->mode) !=
+ AA_EXEC_MASK(match->mode))
+ pattern_match_invalid = 1;
+ else
+ /* got a tailglob match, keep searching
+ * for an exact match
+ */
+ match = entry;
+ }
+ }
+
+ }
+
+ rc = match && !pattern_match_invalid;
+
+ if (rc) {
+ int mode = AA_EXEC_MASK(match->mode);
+
+ /* check for qualifiers, if present
+ * we just return the qualifier
+ */
+ if (mode & ~AA_MAY_EXEC)
+ mode = mode & ~AA_MAY_EXEC;
+
+ *xmod = mode;
+ } else if (!match) {
+ AA_DEBUG("%s: Unable to find execute entry in profile "
+ "for image '%s'\n",
+ __FUNCTION__,
+ name);
+ } else if (pattern_match_invalid) {
+ AA_WARN("%s: Inconsistency in profile %s. "
+ "Two (or more) patterns specify conflicting exec "
+ "qualifiers ('u', 'i' or 'p') for image %s\n",
+ __FUNCTION__,
+ active->name,
+ name);
+ }
+
+ return rc;
+
+ *xmod = AA_MAY_EXEC;
+ return 1;
+}
+
+/**
+ * aa_filter_mask
+ * @mask: requested mask
+ * @inode: potential directory inode
+ *
+ * This fn performs pre-verification of the requested mask
+ * We ignore append. Previously we required 'w' on a dir to add a file.
+ * No longer. Now we require 'w' on just the file itself. Traversal 'x' is
+ * also ignored for directories.
+ *
+ * Returned value of %0 indicates no need to perform a perm check.
+ */
+static inline int aa_filter_mask(int mask, struct inode *inode)
+{
+ if (mask) {
+ int elim = MAY_APPEND;
+
+ if (inode && S_ISDIR(inode->i_mode))
+ elim |= (MAY_EXEC | MAY_WRITE);
+
+ mask &= ~elim;
+ }
+
+ return mask;
+}
+
+static inline void aa_permerror2result(int perm_result, struct aa_audit *sa)
+{
+ if (perm_result == 0) { /* success */
+ sa->result = 1;
+ sa->error_code = 0;
+ } else { /* -ve internal error code or +ve mask of denied perms */
+ sa->result = 0;
+ sa->error_code = perm_result;
+ }
+}
+
+/*************************
+ * Main internal functions
+ ************************/
+
+/**
+ * aa_file_perm - calculate access mode for file
+ * @active: profile to check against
+ * @name: name of file to calculate mode for
+ * @mask: permission mask requested for file
+ *
+ * Search the aa_entry list in @active.
+ * Search looking to verify all permissions passed in mask.
+ * Perform the search by looking at the partitioned list of entries, one
+ * partition per permission bit.
+ *
+ * Return %0 on success, else mask of non-allowed permissions
+ */
+static unsigned int aa_file_perm(struct aaprofile *active, const char *name,
+ int mask)
+{
+ int i, error = 0, mode;
+
+#define PROCPFX "/proc/"
+#define PROCLEN sizeof(PROCPFX) - 1
+
+ AA_DEBUG("%s: %s 0x%x\n", __FUNCTION__, name, mask);
+
+ /* should not enter with other than R/W/X/L */
+ WARN_ON(mask &
+ ~(AA_MAY_READ | AA_MAY_WRITE | AA_MAY_EXEC | AA_MAY_LINK));
+
+ /* Special case access to /proc/self/attr/current
+ * Currently we only allow access if opened O_WRONLY
+ */
+ if (mask == MAY_WRITE && strncmp(PROCPFX, name, PROCLEN) == 0 &&
+ (!list_empty(&BASE_PROFILE(active)->sub) ||
+ PROFILE_COMPLAIN(active)) && aa_taskattr_access(name + PROCLEN))
+ goto done;
+
+ mode = 0;
+
+ /* iterate over partition, one permission bit at a time */
+ for (i = 0; i <= POS_AA_FILE_MAX; i++) {
+ struct aa_entry *entry;
+
+ /* do we have to accumulate this bit?
+ * or have we already accumulated it (shortcut below)? */
+ if (!(mask & (1 << i)) || mode & (1 << i))
+ continue;
+
+ list_for_each_entry(entry, &active->file_entryp[i],
+ listp[i]) {
+ if (aamatch_match(name, entry->filename,
+ entry->type, entry->extradata)) {
+ /* Shortcut, accumulate all bits present */
+ mode |= entry->mode;
+
+ /* Mask bits are overloaded
+ * MAY_{EXEC,WRITE,READ,APPEND} are used by
+ * kernel, other values are used locally only.
+ */
+ if ((mode & mask) == mask) {
+ AA_DEBUG("MATCH! %s=0x%x [total mode=0x%x]\n",
+ name, mask, mode);
+
+ goto done;
+ }
+ }
+ }
+ }
+
+ /* return permissions not satisfied */
+ error = mask & ~mode;
+
+done:
+ return error;
+}
+
+/**
+ * aa_link_perm - test permission to link to a file
+ * @active: profile to check against
+ * @link: name of link being created
+ * @target: name of target to be linked to
+ *
+ * Look up permission mode on both @link and @target. @link must have same
+ * permission mode as @target. At least @link must have the link bit enabled.
+ * Return %0 on success, error otherwise.
+ */
+static int aa_link_perm(struct aaprofile *active,
+ const char *link, const char *target)
+{
+ int l_mode, t_mode, ret;
+
+ l_mode = aa_file_mode(active, link);
+ if (l_mode & AA_MAY_LINK) {
+ /* mask off link bit */
+ l_mode &= ~AA_MAY_LINK;
+
+ t_mode = aa_file_mode(active, target);
+ t_mode &= ~AA_MAY_LINK;
+
+ ret = (l_mode == t_mode);
+ } else {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/**
+ * _aa_perm_dentry
+ * @active: profile to check against
+ * @dentry: requested dentry
+ * @mask: mask of requested operations
+ * @pname: pointer to hold matched pathname (if any)
+ *
+ * Helper function. Obtain pathname for specified dentry. Verify if profile
+ * authorizes mask operations on pathname (due to lack of vfsmnt it is sadly
+ * necessary to search mountpoints in namespace -- when nameidata is passed
+ * more fully, this code can go away). If more than one mountpoint matches
+ * but none satisfy the profile, only the first pathname (mountpoint) is
+ * returned for subsequent logging.
+ *
+ * Return %0 (success), +ve (mask of permissions not satisfied) or -ve (system
+ * error, most likely -%ENOMEM).
+ */
+static int _aa_perm_dentry(struct aaprofile *active, struct dentry *dentry,
+ int mask, const char **pname)
+{
+ char *name = NULL, *failed_name = NULL;
+ struct aa_path_data data;
+ int error = 0, failed_error = 0, path_error,
+ complain = PROFILE_COMPLAIN(active);
+
+ /* search all paths to dentry */
+
+ aa_path_begin(dentry, &data);
+ do {
+ name = aa_path_getname(&data);
+ if (name) {
+ /* error here is 0 (success) or +ve (mask of perms) */
+ error = aa_file_perm(active, name, mask);
+
+ /* access via any path is enough */
+ if (complain || error == 0)
+ break; /* Caller must free name */
+
+ /* Already have an path that failed? */
+ if (failed_name) {
+ aa_put_name(name);
+ } else {
+ failed_name = name;
+ failed_error = error;
+ }
+ }
+ } while (name);
+
+ if ((path_error = aa_path_end(&data)) != 0) {
+ AA_ERROR("%s: An error occured while translating dentry %p "
+ "inode# %lu to a pathname. Error %d\n",
+ __FUNCTION__,
+ dentry,
+ dentry->d_inode->i_ino,
+ path_error);
+
+ WARN_ON(name); /* name should not be set if error */
+ error = path_error;
+ name = NULL;
+ } else if (name) {
+ if (failed_name)
+ aa_put_name(failed_name);
+ } else {
+ name = failed_name;
+ error = failed_error;
+ }
+
+ *pname = name;
+
+ return error;
+}
+
+/**************************
+ * Global utility functions
+ *************************/
+
+/**
+ * attach_nullprofile - allocate and attach a null_profile hat to profile
+ * @profile: profile to attach a null_profile hat to.
+ *
+ * Return %0 (success) or error (-%ENOMEM)
+ */
+int attach_nullprofile(struct aaprofile *profile)
+{
+ struct aaprofile *hat = NULL;
+ char *hatname = NULL;
+
+ hat = alloc_aaprofile();
+ if (!hat)
+ goto fail;
+ if (profile->flags.complain)
+ hatname = kstrdup("null-complain-profile", GFP_KERNEL);
+ else
+ hatname = kstrdup("null-profile", GFP_KERNEL);
+ if (!hatname)
+ goto fail;
+
+ hat->flags.complain = profile->flags.complain;
+ hat->name = hatname;
+ hat->parent = profile;
+
+ profile->null_profile = hat;
+
+ return 0;
+
+fail:
+ kfree(hatname);
+ free_aaprofile(hat);
+
+ return -ENOMEM;
+}
+
+
+/**
+ * alloc_null_complain_profile - Allocate the global null_complain_profile.
+ *
+ * Return %0 (success) or error (-%ENOMEM)
+ */
+int alloc_null_complain_profile(void)
+{
+ null_complain_profile = alloc_aaprofile();
+ if (!null_complain_profile)
+ goto fail;
+
+ null_complain_profile->name =
+ kstrdup("null-complain-profile", GFP_KERNEL);
+
+ if (!null_complain_profile->name)
+ goto fail;
+
+ null_complain_profile->flags.complain = 1;
+ if (attach_nullprofile(null_complain_profile))
+ goto fail;
+
+ return 0;
+
+fail:
+ /* free_aaprofile is safe for freeing partially constructed objects */
+ free_aaprofile(null_complain_profile);
+ null_complain_profile = NULL;
+
+ return -ENOMEM;
+}
+
+/**
+ * free_null_complain_profile - Free null profiles
+ */
+void free_null_complain_profile(void)
+{
+ put_aaprofile(null_complain_profile);
+ null_complain_profile = NULL;
+}
+
+/**
+ * aa_audit_message - Log a message to the audit subsystem
+ * @active: profile to check against
+ * @gfp: allocation flags
+ * @flags: audit flags
+ * @fmt: varargs fmt
+ */
+int aa_audit_message(struct aaprofile *active, unsigned int gfp, int flags,
+ const char *fmt, ...)
+{
+ int ret;
+ struct aa_audit sa;
+
+ sa.type = AA_AUDITTYPE_MSG;
+ sa.name = fmt;
+ va_start(sa.vaval, fmt);
+ sa.flags = flags;
+ sa.gfp_mask = gfp;
+ sa.error_code = 0;
+ sa.result = 0; /* fake failure: force message to be logged */
+
+ ret = aa_audit(active, &sa);
+
+ va_end(sa.vaval);
+
+ return ret;
+}
+
+/**
+ * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem
+ * @active: profile to check against
+ * @msg: string describing syscall being rejected
+ * @gfp: memory allocation flags
+ */
+int aa_audit_syscallreject(struct aaprofile *active, unsigned int gfp,
+ const char *msg)
+{
+ struct aa_audit sa;
+
+ sa.type = AA_AUDITTYPE_SYSCALL;
+ sa.name = msg;
+ sa.flags = 0;
+ sa.gfp_mask = gfp;
+ sa.error_code = 0;
+ sa.result = 0; /* failure */
+
+ return aa_audit(active, &sa);
+}
+
+/**
+ * aa_audit - Log an audit event to the audit subsystem
+ * @active: profile to check against
+ * @sa: audit event
+ */
+int aa_audit(struct aaprofile *active, const struct aa_audit *sa)
+{
+ struct audit_buffer *ab = NULL;
+ struct audit_context *ctx;
+
+ const char *logcls;
+ unsigned int flags;
+ int audit = 0,
+ complain = 0,
+ error = -EINVAL,
+ opspec_error = -EACCES;
+
+ const unsigned int gfp_mask = sa->gfp_mask;
+
+ WARN_ON(sa->type >= AA_AUDITTYPE__END);
+
+ /*
+ * sa->result: 1 success, 0 failure
+ * sa->error_code: success: 0
+ * failure: +ve mask of failed permissions or -ve
+ * system error
+ */
+
+ if (likely(sa->result)) {
+ if (likely(!PROFILE_AUDIT(active))) {
+ /* nothing to log */
+ error = 0;
+ goto out;
+ } else {
+ audit = 1;
+ logcls = "AUDITING";
+ }
+ } else if (sa->error_code < 0) {
+ audit_log(current->audit_context, gfp_mask, AUDIT_AA,
+ "Internal error auditing event type %d (error %d)",
+ sa->type, sa->error_code);
+ AA_ERROR("Internal error auditing event type %d (error %d)\n",
+ sa->type, sa->error_code);
+ error = sa->error_code;
+ goto out;
+ } else if (sa->type == AA_AUDITTYPE_SYSCALL) {
+ /* Currently AA_AUDITTYPE_SYSCALL is for rejects only.
+ * Values set by aa_audit_syscallreject will get us here.
+ */
+ logcls = "REJECTING";
+ } else {
+ complain = PROFILE_COMPLAIN(active);
+ logcls = complain ? "PERMITTING" : "REJECTING";
+ }
+
+ /* In future extend w/ per-profile flags
+ * (flags |= sa->active->flags)
+ */
+ flags = sa->flags;
+ if (apparmor_logsyscall)
+ flags |= AA_AUDITFLAG_AUDITSS_SYSCALL;
+
+
+ /* Force full audit syscall logging regardless of global setting if
+ * we are rejecting a syscall
+ */
+ if (sa->type == AA_AUDITTYPE_SYSCALL) {
+ ctx = current->audit_context;
+ } else {
+ ctx = (flags & AA_AUDITFLAG_AUDITSS_SYSCALL) ?
+ current->audit_context : NULL;
+ }
+
+ ab = audit_log_start(ctx, gfp_mask, AUDIT_AA);
+
+ if (!ab) {
+ AA_ERROR("Unable to log event (%d) to audit subsys\n",
+ sa->type);
+ if (complain)
+ error = 0;
+ goto out;
+ }
+
+ /* messages get special handling */
+ if (sa->type == AA_AUDITTYPE_MSG) {
+ audit_log_vformat(ab, sa->name, sa->vaval);
+ audit_log_end(ab);
+ error = 0;
+ goto out;
+ }
+
+ /* log operation */
+
+ audit_log_format(ab, "%s ", logcls); /* REJECTING/ALLOWING/etc */
+
+ if (sa->type == AA_AUDITTYPE_FILE) {
+ int perm = audit ? sa->ival : sa->error_code;
+
+ audit_log_format(ab, "%s%s%s%s access to %s ",
+ perm & AA_MAY_READ ? "r" : "",
+ perm & AA_MAY_WRITE ? "w" : "",
+ perm & AA_MAY_EXEC ? "x" : "",
+ perm & AA_MAY_LINK ? "l" : "",
+ sa->name);
+
+ opspec_error = -EPERM;
+
+ } else if (sa->type == AA_AUDITTYPE_DIR) {
+ audit_log_format(ab, "%s on %s ",
+ sa->ival == aa_dir_mkdir ? "mkdir" : "rmdir",
+ sa->name);
+
+ } else if (sa->type == AA_AUDITTYPE_ATTR) {
+ struct iattr *iattr = (struct iattr*)sa->pval;
+
+ audit_log_format(ab,
+ "attribute (%s%s%s%s%s%s%s) change to %s ",
+ iattr->ia_valid & ATTR_MODE ? "mode," : "",
+ iattr->ia_valid & ATTR_UID ? "uid," : "",
+ iattr->ia_valid & ATTR_GID ? "gid," : "",
+ iattr->ia_valid & ATTR_SIZE ? "size," : "",
+ ((iattr->ia_valid & ATTR_ATIME_SET) ||
+ (iattr->ia_valid & ATTR_ATIME)) ? "atime," : "",
+ ((iattr->ia_valid & ATTR_MTIME_SET) ||
+ (iattr->ia_valid & ATTR_MTIME)) ? "mtime," : "",
+ iattr->ia_valid & ATTR_CTIME ? "ctime," : "",
+ sa->name);
+
+ } else if (sa->type == AA_AUDITTYPE_XATTR) {
+ const char *fmt;
+ switch (sa->ival) {
+ case aa_xattr_get:
+ fmt = "xattr get";
+ break;
+ case aa_xattr_set:
+ fmt = "xattr set";
+ break;
+ case aa_xattr_list:
+ fmt = "xattr list";
+ break;
+ case aa_xattr_remove:
+ fmt = "xattr remove";
+ break;
+ default:
+ fmt = "xattr <unknown>";
+ break;
+ }
+
+ audit_log_format(ab, "%s on %s ", fmt, sa->name);
+
+ } else if (sa->type == AA_AUDITTYPE_LINK) {
+ audit_log_format(ab,
+ "link access from %s to %s ",
+ sa->name,
+ (char*)sa->pval);
+
+ } else if (sa->type == AA_AUDITTYPE_CAP) {
+ audit_log_format(ab,
+ "access to capability '%s' ",
+ capability_to_name(sa->ival));
+
+ opspec_error = -EPERM;
+ } else if (sa->type == AA_AUDITTYPE_SYSCALL) {
+ audit_log_format(ab, "access to syscall '%s' ", sa->name);
+
+ opspec_error = -EPERM;
+ } else {
+ /* -EINVAL -- will WARN_ON above */
+ goto out;
+ }
+
+ audit_log_format(ab, "(%s(%d) ", current->comm, current->pid);
+
+ if (0)
+ audit_log_format(ab, "[global deny])");
+ else
+ audit_log_format(ab, "profile %s active %s)",
+ BASE_PROFILE(active)->name,
+ active->name);
+
+ audit_log_end(ab);
+
+ if (complain)
+ error = 0;
+ else
+ error = sa->result ? 0 : opspec_error;
+
+out:
+ return error;
+}
+
+/**
+ * aa_get_name - retrieve fully qualified path name
+ * @dentry: relative path element
+ * @mnt: where in tree
+ *
+ * Returns fully qualified path name on sucess, NULL on failure.
+ * aa_put_name must be used to free allocated buffer.
+ */
+char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt)
+{
+ char *page, *name = NULL;
+
+ page = (char *)__get_free_page(GFP_KERNEL);
+ if (!page)
+ goto out;
+
+ name = d_path_flags(dentry, mnt, page, PAGE_SIZE,
+ DPATH_SYSROOT|DPATH_NODELETED);
+
+ AA_DEBUG("%s: full_path=%s\n", __FUNCTION__, name);
+out:
+ return name;
+}
+
+/***********************************
+ * Global permission check functions
+ ***********************************/
+
+/**
+ * aa_attr - check whether attribute change allowed
+ * @active: profile to check against
+ * @dentry: file to check
+ * @iattr: attribute changes requested
+ */
+int aa_attr(struct aaprofile *active, struct dentry *dentry,
+ struct iattr *iattr)
+{
+ int error = 0, permerror;
+ struct aa_audit sa;
+
+ sa.type = AA_AUDITTYPE_ATTR;
+ sa.pval = iattr;
+ sa.flags = 0;
+ sa.gfp_mask = GFP_KERNEL;
+
+ permerror = _aa_perm_dentry(active, dentry, MAY_WRITE, &sa.name);
+ aa_permerror2result(permerror, &sa);
+
+ error = aa_audit(active, &sa);
+
+ aa_put_name(sa.name);
+
+ return error;
+}
+
+/**
+ * aa_xattr - check whether xattr attribute change allowed
+ * @active: profile to check against
+ * @dentry: file to check
+ * @xattr: xattr to check
+ * @xattroptype: type of xattr operation
+ */
+int aa_xattr(struct aaprofile *active, struct dentry *dentry,
+ const char *xattr, enum aa_xattroptype xattroptype)
+{
+ int error = 0, permerror, mask = 0;
+ struct aa_audit sa;
+
+ /* if not confined or empty mask permission granted */
+ if (!active)
+ goto out;
+
+ if (xattroptype == aa_xattr_get || xattroptype == aa_xattr_list)
+ mask = MAY_READ;
+ else if (xattroptype == aa_xattr_set || xattroptype == aa_xattr_remove)
+ mask = MAY_WRITE;
+
+ sa.type = AA_AUDITTYPE_XATTR;
+ sa.ival = xattroptype;
+ sa.pval = xattr;
+ sa.flags = 0;
+ sa.gfp_mask = GFP_KERNEL;
+
+ permerror = _aa_perm_dentry(active, dentry, mask, &sa.name);
+ aa_permerror2result(permerror, &sa);
+
+ error = aa_audit(active, &sa);
+
+ aa_put_name(sa.name);
+
+out:
+ return error;
+}
+
+/**
+ * aa_perm - basic subdomain permissions check
+ * @active: profile to check against
+ * @dentry: dentry
+ * @mnt: mountpoint
+ * @mask: access mode requested
+ *
+ * Determine if access (mask) for dentry is authorized by subdomain active
+ * profile. Result, %0 (success), -ve (error)
+ */
+int aa_perm(struct aaprofile *active, struct dentry *dentry,
+ struct vfsmount *mnt, int mask)
+{
+ int error = 0, permerror;
+ struct aa_audit sa;
+
+ if (!active)
+ goto out;
+
+ if ((mask = aa_filter_mask(mask, dentry->d_inode)) == 0)
+ goto out;
+
+ sa.type = AA_AUDITTYPE_FILE;
+ sa.name = aa_get_name(dentry, mnt);
+ sa.ival = mask;
+ sa.flags = 0;
+ sa.gfp_mask = GFP_KERNEL;
+
+ permerror = (sa.name ? aa_file_perm(active, sa.name, mask) : -ENOMEM);
+
+ aa_permerror2result(permerror, &sa);
+
+ error = aa_audit(active, &sa);
+
+ aa_put_name(sa.name);
+
+out:
+ return error;
+}
+
+/**
+ * aa_perm_nameidata: interface to sd_perm accepting nameidata
+ * @active: profile to check against
+ * @nd: namespace data (for vfsmnt and dentry)
+ * @mask: access mode requested
+ */
+int aa_perm_nameidata(struct aaprofile *active, struct nameidata *nd, int mask)
+{
+ int error = 0;
+
+ if (nd)
+ error = aa_perm(active, nd->dentry, nd->mnt, mask);
+
+ return error;
+}
+
+/**
+ * aa_perm_dentry - file permissions interface when no vfsmnt available
+ * @active: profile to check against
+ * @dentry: requested dentry
+ * @mask: access mode requested
+ *
+ * Determine if access (mask) for dentry is authorized by active profile.
+ * Result, %0 (success), -ve (error)
+ */
+int aa_perm_dentry(struct aaprofile *active, struct dentry *dentry, int mask)
+{
+ int error = 0, permerror;
+ struct aa_audit sa;
+
+ if (!active)
+ goto out;
+
+ if ((mask = aa_filter_mask(mask, dentry->d_inode)) == 0)
+ goto out;
+
+ sa.type = AA_AUDITTYPE_FILE;
+ sa.ival = mask;
+ sa.flags = 0;
+ sa.gfp_mask = GFP_KERNEL;
+
+ permerror = _aa_perm_dentry(active, dentry, mask, &sa.name);
+ aa_permerror2result(permerror, &sa);
+
+ error = aa_audit(active, &sa);
+
+ aa_put_name(sa.name);
+
+out:
+ return error;
+}
+
+/**
+ * aa_perm_dir
+ * @active: profile to check against
+ * @dentry: requested dentry
+ * @diroptype: aa_dir_mkdir or aa_dir_rmdir
+ *
+ * Determine if directory operation (make/remove) for dentry is authorized
+ * by @active profile.
+ * Result, %0 (success), -ve (error)
+ */
+int aa_perm_dir(struct aaprofile *active, struct dentry *dentry,
+ enum aa_diroptype diroptype)
+{
+ int error = 0, permerror, mask;
+ struct aa_audit sa;
+
+ WARN_ON(diroptype != aa_dir_mkdir && diroptype != aa_dir_rmdir);
+
+ if (!active)
+ goto out;
+
+ mask = MAY_WRITE;
+
+ sa.type = AA_AUDITTYPE_DIR;
+ sa.ival = diroptype;
+ sa.flags = 0;
+ sa.gfp_mask = GFP_KERNEL;
+
+ permerror = _aa_perm_dentry(active, dentry, mask, &sa.name);
+ aa_permerror2result(permerror, &sa);
+
+ error = aa_audit(active, &sa);
+
+ aa_put_name(sa.name);
+
+out:
+ return error;
+}
+
+/**
+ * aa_capability - test permission to use capability
+ * @active: profile to check against
+ * @cap: capability to be tested
+ *
+ * Look up capability in active profile capability set.
+ * Return %0 (success), -%EPERM (error)
+ */
+int aa_capability(struct aaprofile *active, int cap)
+{
+ int error = 0;
+
+ struct aa_audit sa;
+
+ sa.type = AA_AUDITTYPE_CAP;
+ sa.name = NULL;
+ sa.ival = cap;
+ sa.flags = 0;
+ sa.error_code = 0;
+ sa.result = cap_raised(active->capabilities, cap);
+ sa.gfp_mask = GFP_ATOMIC;
+
+ error = aa_audit(active, &sa);
+
+ return error;
+}
+
+/**
+ * aa_link - hard link check
+ * @active: profile to check against
+ * @link: dentry for link being created
+ * @target: dentry for link target
+ *
+ * Checks link permissions for all possible name combinations. This is
+ * particularly ugly. Returns %0 on sucess, error otherwise.
+ */
+int aa_link(struct aaprofile *active, struct dentry *link,
+ struct dentry *target)
+{
+ char *iname = NULL, *oname = NULL,
+ *failed_iname = NULL, *failed_oname = NULL;
+ unsigned int result = 0;
+ int error, path_error, error_code = 0, match = 0,
+ complain = PROFILE_COMPLAIN(active);
+ struct aa_path_data idata, odata;
+ struct aa_audit sa;
+
+ if (!active)
+ return 0;
+
+ /* Perform nested lookup for names.
+ * This is necessary in the case where /dev/block is mounted
+ * multiple times, i.e /dev/block->/a and /dev/block->/b
+ * This allows us to detect links where src/dest are on different
+ * mounts. N.B no support yet for links across bind mounts of
+ * the form mount -bind /mnt/subpath /mnt2
+ *
+ * Getting direct access to vfsmounts (via nameidata) for link and
+ * target would allow all this uglyness to go away.
+ *
+ * If more than one mountpoint matches but none satisfy the profile,
+ * only the first pathname (mountpoint) is logged.
+ */
+
+ __aa_path_begin(target, link, &odata);
+ do {
+ oname = aa_path_getname(&odata);
+ if (oname) {
+ aa_path_begin(target, &idata);
+ do {
+ iname = aa_path_getname(&idata);
+ if (iname) {
+ result = aa_link_perm(active, oname,
+ iname);
+
+ /* access via any path is enough */
+ if (result || complain) {
+ match = 1;
+ break;
+ }
+
+ /* Already have an path that failed? */
+ if (failed_iname) {
+ aa_put_name(iname);
+ } else {
+ failed_iname = iname;
+ failed_oname = oname;
+ }
+ }
+ } while (iname && !match);
+
+ /* should not be possible if we matched */
+ if ((path_error = aa_path_end(&idata)) != 0) {
+ AA_ERROR("%s: An error occured while "
+ "translating inner dentry %p "
+ "inode %lu to a pathname. Error %d\n",
+ __FUNCTION__,
+ target,
+ target->d_inode->i_ino,
+ path_error);
+
+ /* name should not be set if error */
+ WARN_ON(iname);
+
+ error_code = path_error;
+ }
+
+ /* don't release if we're saving it */
+ if (!match && failed_oname != oname)
+ aa_put_name(oname);
+ }
+ } while (oname && !match);
+
+ if (error_code != 0) {
+ /* inner error */
+ (void)aa_path_end(&odata);
+ } else if ((path_error = aa_path_end(&odata)) != 0) {
+ AA_ERROR("%s: An error occured while translating outer "
+ "dentry %p inode %lu to a pathname. Error %d\n",
+ __FUNCTION__,
+ link,
+ link->d_inode->i_ino,
+ path_error);
+
+ error_code = path_error;
+ }
+
+ if (error_code != 0) {
+ /* inner or outer error */
+ result = 0;
+ } else if (match) {
+ result = 1;
+ } else {
+ /* failed to match */
+ WARN_ON(iname);
+ WARN_ON(oname);
+
+ result = 0;
+ iname = failed_iname;
+ oname = failed_oname;
+ }
+
+ sa.type = AA_AUDITTYPE_LINK;
+ sa.name = oname; /* link */
+ sa.pval = iname; /* target */
+ sa.flags = 0;
+ sa.error_code = error_code;
+ sa.result = result;
+ sa.gfp_mask = GFP_KERNEL;
+
+ error = aa_audit(active, &sa);
+
+ if (failed_oname != oname)
+ aa_put_name(failed_oname);
+ if (failed_iname != iname)
+ aa_put_name(failed_iname);
+
+ aa_put_name(oname);
+ aa_put_name(iname);
+
+ return error;
+}
+
+/*******************************
+ * Global task related functions
+ *******************************/
+
+/**
+ * aa_fork - create a new subdomain
+ * @p: new process
+ *
+ * Create a new subdomain struct for the newly created process @p.
+ * Copy parent info to child. If parent has no subdomain, child
+ * will get one with %NULL values. Return %0 on sucess.
+ *
+ * The sd_lock is used to maintain consistency against profile
+ * replacement/removal.
+ */
+
+int aa_fork(struct task_struct *p)
+{
+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
+ struct subdomain *newsd = alloc_subdomain(p);
+
+ AA_DEBUG("%s\n", __FUNCTION__);
+
+ if (!newsd)
+ return -ENOMEM;
+
+ if (sd) {
+ unsigned long flags;
+
+ /* Use locking here instead of getting the reference
+ * because we need both the old reference and the
+ * new reference to be consistent.
+ */
+ spin_lock_irqsave(&sd_lock, flags);
+ aa_switch(newsd, sd->active);
+ newsd->hat_magic = sd->hat_magic;
+ spin_unlock_irqrestore(&sd_lock, flags);
+
+ if (SUBDOMAIN_COMPLAIN(sd) &&
+ sd->active == null_complain_profile)
+ LOG_HINT(sd->active, GFP_KERNEL, HINT_FORK,
+ "pid=%d child=%d\n",
+ current->pid, p->pid);
+ }
+ p->security = newsd;
+ return 0;
+}
+
+/**
+ * aa_register - register a new program
+ * @filp: file of program being registered
+ *
+ * Try to register a new program during execve(). This should give the
+ * new program a valid subdomain.
+ */
+int aa_register(struct file *filp)
+{
+ char *filename;
+ struct subdomain *sd;
+ struct aaprofile *active;
+ struct aaprofile *newprofile = NULL, unconstrained_flag;
+ int error = -ENOMEM,
+ exec_mode = 0,
+ find_profile = 0,
+ find_profile_mandatory = 0,
+ complain = 0;
+
+ AA_DEBUG("%s\n", __FUNCTION__);
+
+ sd = AA_SUBDOMAIN(current->security);
+
+ if (sd) {
+ complain = SUBDOMAIN_COMPLAIN(sd);
+ } else {
+ /* task has no subdomain. This can happen when a task is
+ * created when subdomain is not loaded. Allocate and
+ * attach a subdomain to the task
+ */
+ sd = alloc_subdomain(current);
+ if (!sd) {
+ AA_WARN("%s: Failed to allocate subdomain\n",
+ __FUNCTION__);
+ goto out;
+ }
+
+ current->security = sd;
+ }
+
+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt);
+ if (!filename) {
+ AA_WARN("%s: Failed to get filename\n", __FUNCTION__);
+ goto out;
+ }
+
+ error = 0;
+
+ active = get_active_aaprofile();
+
+ if (!active) {
+ /* Unconfined task, load profile if it exists */
+ find_profile = 1;
+ goto find_profile;
+ }
+
+ /* Confined task, determine what mode inherit, unconstrained or
+ * mandatory to load new profile
+ */
+ if (aa_get_execmode(active, filename, &exec_mode)) {
+ switch (exec_mode) {
+ case AA_EXEC_INHERIT:
+ /* do nothing - setting of profile
+ * already handed in aa_fork
+ */
+ AA_DEBUG("%s: INHERIT %s\n",
+ __FUNCTION__,
+ filename);
+ break;
+
+ case AA_EXEC_UNCONSTRAINED:
+ AA_DEBUG("%s: UNCONSTRAINED %s\n",
+ __FUNCTION__,
+ filename);
+
+ /* unload profile */
+ newprofile = &unconstrained_flag;
+ break;
+
+ case AA_EXEC_PROFILE:
+ AA_DEBUG("%s: PROFILE %s\n",
+ __FUNCTION__,
+ filename);
+
+ find_profile = 1;
+ find_profile_mandatory = 1;
+ break;
+
+ case AA_MAY_EXEC:
+ /* this should not happen, entries
+ * with just EXEC only should be
+ * rejected at profile load time
+ */
+ AA_ERROR("%s: Rejecting exec(2) of image '%s'. "
+ "AA_MAY_EXEC without exec qualifier invalid "
+ "(%s(%d) profile %s active %s\n",
+ __FUNCTION__,
+ filename,
+ current->comm, current->pid,
+ BASE_PROFILE(active)->name, active->name);
+ error = -EPERM;
+ break;
+
+ default:
+ AA_ERROR("%s: Rejecting exec(2) of image '%s'. "
+ "Unknown exec qualifier %x "
+ "(%s (pid %d) profile %s active %s)\n",
+ __FUNCTION__,
+ filename,
+ exec_mode,
+ current->comm, current->pid,
+ BASE_PROFILE(active)->name, sd->active->name);
+ error = -EPERM;
+ break;
+ }
+
+ } else if (complain) {
+ /* There was no entry in calling profile
+ * describing mode to execute image in.
+ * Drop into null-profile
+ */
+ newprofile = get_aaprofile(null_complain_profile);
+ } else {
+ AA_WARN("%s: Rejecting exec(2) of image '%s'. "
+ "Unable to determine exec qualifier "
+ "(%s (pid %d) profile %s active %s)\n",
+ __FUNCTION__,
+ filename,
+ current->comm, current->pid,
+ BASE_PROFILE(active)->name, active->name);
+ error = -EPERM;
+ }
+
+
+find_profile:
+ if (!find_profile)
+ goto apply_profile;
+
+ /* Locate new profile */
+ newprofile = aa_profilelist_find(filename);
+ if (newprofile) {
+ AA_DEBUG("%s: setting profile %s\n",
+ __FUNCTION__, newprofile->name);
+ } else if (find_profile_mandatory) {
+ /* Profile (mandatory) could not be found */
+
+ if (complain) {
+ LOG_HINT(active, GFP_KERNEL, HINT_MANDPROF,
+ "image=%s pid=%d profile=%s active=%s\n",
+ filename,
+ current->pid,
+ BASE_PROFILE(active)->name, active->name);
+
+ newprofile = get_aaprofile(null_complain_profile);
+ } else {
+ AA_WARN("REJECTING exec(2) of image '%s'. "
+ "Profile mandatory and not found "
+ "(%s(%d) profile %s active %s)\n",
+ filename,
+ current->comm, current->pid,
+ BASE_PROFILE(active)->name, active->name);
+ error = -EPERM;
+ }
+ } else {
+ /* Profile (non-mandatory) could not be found */
+
+ /* Only way we can get into this code is if task
+ * is unconstrained.
+ */
+
+ WARN_ON(active);
+
+ AA_DEBUG("%s: No profile found for exec image %s\n",
+ __FUNCTION__,
+ filename);
+ } /* newprofile */
+
+
+apply_profile:
+ /* Apply profile if necessary */
+ if (newprofile) {
+ unsigned long flags;
+
+ if (newprofile == &unconstrained_flag)
+ newprofile = NULL;
+
+ /* grab a lock - this is to guarentee consistency against
+ * other writers of subdomain (replacement/removal)
+ *
+ * Several things may have changed since the code above
+ *
+ * - If we are a confined process, active is a refcounted copy
+ * of the profile that was on the subdomain at entry.
+ * This allows us to not have to hold a lock around
+ * all this code. If profile replacement has taken place
+ * our sd->active may not equal sd->active any more.
+ * This is okay since the operation is treated as if
+ * the transition occured before replacement.
+ *
+ * - If newprofile points to an actual profile (result of
+ * aa_profilelist_find above), this profile may have been
+ * replaced. We need to fix it up. Doing this to avoid
+ * having to hold a lock around all this code.
+ */
+
+ spin_lock_irqsave(&sd_lock, flags);
+
+ /* Determine if profile we found earlier is stale.
+ * If so, reobtain it. N.B stale flag should never be
+ * set on null_complain profile.
+ */
+ if (newprofile && unlikely(newprofile->isstale)) {
+ WARN_ON(newprofile == null_complain_profile);
+
+ /* drop refcnt obtained from earlier get_aaprofile */
+ put_aaprofile(newprofile);
+
+ newprofile = aa_profilelist_find(filename);
+
+ if (!newprofile) {
+ /* Race, profile was removed, not replaced.
+ * Redo with error checking
+ */
+ spin_unlock_irqrestore(&sd_lock, flags);
+ goto find_profile;
+ }
+ }
+
+ aa_switch(sd, newprofile);
+ put_aaprofile(newprofile);
+
+ if (complain && newprofile == null_complain_profile)
+ LOG_HINT(newprofile, GFP_ATOMIC, HINT_CHGPROF,
+ "pid=%d\n",
+ current->pid);
+
+ spin_unlock_irqrestore(&sd_lock, flags);
+ }
+
+ aa_put_name(filename);
+
+ put_aaprofile(active);
+
+out:
+ return error;
+}
+
+/**
+ * aa_release - release the task's subdomain
+ * @p: task being released
+ *
+ * This is called after a task has exited and the parent has reaped it.
+ * @p->security blob is freed.
+ *
+ * This is the one case where we don't need to hold the sd_lock before
+ * removing a profile from a subdomain. Once the subdomain has been
+ * removed from the subdomain_list, we are no longer racing other writers.
+ * There may still be other readers so we must still use aa_switch
+ * to put the subdomain's reference safely.
+ */
+void aa_release(struct task_struct *p)
+{
+ struct subdomain *sd = AA_SUBDOMAIN(p->security);
+ if (sd) {
+ p->security = NULL;
+
+ aa_subdomainlist_remove(sd);
+
+ aa_switch_unconfined(sd);
+
+ kfree(sd);
+ }
+}
+
+/*****************************
+ * global subprofile functions
+ ****************************/
+
+/**
+ * do_change_hat - actually switch hats
+ * @hat_name: name of hat to swtich to
+ * @sd: current subdomain
+ *
+ * Switch to a new hat. Return %0 on success, error otherwise.
+ */
+static inline int do_change_hat(const char *hat_name, struct subdomain *sd)
+{
+ struct aaprofile *sub;
+ int error = 0;
+
+ sub = __aa_find_profile(hat_name, &BASE_PROFILE(sd->active)->sub);
+
+ if (sub) {
+ /* change hat */
+ aa_switch(sd, sub);
+ put_aaprofile(sub);
+ } else {
+ /* There is no such subprofile change to a NULL profile.
+ * The NULL profile grants no file access.
+ *
+ * This feature is used by changehat_apache.
+ *
+ * N.B from the null-profile the task can still changehat back
+ * out to the parent profile (assuming magic != NULL)
+ */
+ if (SUBDOMAIN_COMPLAIN(sd)) {
+ LOG_HINT(sd->active, GFP_ATOMIC, HINT_UNKNOWN_HAT,
+ "%s pid=%d "
+ "profile=%s active=%s\n",
+ hat_name,
+ current->pid,
+ BASE_PROFILE(sd->active)->name,
+ sd->active->name);
+ } else {
+ AA_DEBUG("%s: Unknown hatname '%s'. "
+ "Changing to NULL profile "
+ "(%s(%d) profile %s active %s)\n",
+ __FUNCTION__,
+ hat_name,
+ current->comm, current->pid,
+ BASE_PROFILE(sd->active)->name,
+ sd->active->name);
+ error = -EACCES;
+ }
+ aa_switch(sd, sd->active->null_profile);
+ }
+
+ return error;
+}
+
+/**
+ * aa_change_hat - change hat to/from subprofile
+ * @hat_name: specifies hat to change to
+ * @hat_magic: token to validate hat change
+ *
+ * Change to new @hat_name when current hat is top level profile, and store
+ * the @hat_magic in the current subdomain. If the new @hat_name is
+ * %NULL, and the @hat_magic matches that stored in the current subdomain
+ * return to original top level profile. Returns %0 on success, error
+ * otherwise.
+ */
+int aa_change_hat(const char *hat_name, u32 hat_magic)
+{
+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
+ int error = 0;
+
+ AA_DEBUG("%s: %p, 0x%x (pid %d)\n",
+ __FUNCTION__,
+ hat_name, hat_magic,
+ current->pid);
+
+ /* Dump out above debugging in WARN mode if we are in AUDIT mode */
+ if (SUBDOMAIN_AUDIT(sd)) {
+ AA_WARN("%s: %s, 0x%x (pid %d)\n",
+ __FUNCTION__, hat_name ? hat_name : "NULL",
+ hat_magic, current->pid);
+ }
+
+ /* check to see if an unconfined process is doing a changehat. */
+ if (!__aa_is_confined(sd)) {
+ error = -EACCES;
+ goto out;
+ }
+
+ /* Check whether current domain is parent
+ * or one of the sibling children
+ */
+ if (!IN_SUBPROFILE(sd->active)) {
+ /*
+ * parent
+ */
+ if (hat_name) {
+ AA_DEBUG("%s: switching to %s, 0x%x\n",
+ __FUNCTION__,
+ hat_name,
+ hat_magic);
+
+ /*
+ * N.B hat_magic == 0 has a special meaning
+ * this indicates that the task may never changehat
+ * back to it's parent, it will stay in this subhat
+ * (or null-profile, if the hat doesn't exist) until
+ * the task terminates
+ */
+ sd->hat_magic = hat_magic;
+ error = do_change_hat(hat_name, sd);
+ } else {
+ /* Got here via changehat(NULL, magic)
+ *
+ * We used to simply update the magic cookie.
+ * That's an odd behaviour, so just do nothing.
+ */
+ }
+ } else {
+ /*
+ * child -- check to make sure magic is same as what was
+ * passed when we switched into this profile,
+ * Handle special casing of NULL magic which confines task
+ * to subprofile and prohibits further changehats
+ */
+ if (hat_magic == sd->hat_magic && sd->hat_magic) {
+ if (!hat_name) {
+ /*
+ * Got here via changehat(NULL, magic)
+ * Return from subprofile, back to parent
+ */
+ aa_switch(sd, sd->active->parent);
+
+ /* Reset hat_magic to zero.
+ * New value will be passed on next changehat
+ */
+ sd->hat_magic = 0;
+ } else {
+ /* change to another (sibling) profile */
+ error = do_change_hat(hat_name, sd);
+ }
+ } else if (sd->hat_magic) {
+ AA_ERROR("KILLING process %s(%d) "
+ "Invalid change_hat() magic# 0x%x "
+ "(hatname %s profile %s active %s)\n",
+ current->comm, current->pid,
+ hat_magic,
+ hat_name ? hat_name : "NULL",
+ BASE_PROFILE(sd->active)->name,
+ sd->active->name);
+
+ /* terminate current process */
+ (void)send_sig_info(SIGKILL, NULL, current);
+ } else { /* sd->hat_magic == NULL */
+ AA_ERROR("KILLING process %s(%d) "
+ "Task was confined to current subprofile "
+ "(profile %s active %s)\n",
+ current->comm, current->pid,
+ BASE_PROFILE(sd->active)->name,
+ sd->active->name);
+
+ /* terminate current process */
+ (void)send_sig_info(SIGKILL, NULL, current);
+ }
+
+ }
+
+out:
+ return error;
+}
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 5/11] security: AppArmor - Filesystem
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (3 preceding siblings ...)
2006-04-19 17:49 ` [RFC][PATCH 4/11] security: AppArmor - Core access controls Tony Jones
@ 2006-04-19 17:49 ` Tony Jones
2006-04-21 21:13 ` Amy Griffis
2006-04-19 17:49 ` [RFC][PATCH 6/11] security: AppArmor - Userspace interface Tony Jones
` (8 subsequent siblings)
13 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:49 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
This patch implements the AppArmor file structure underneath securityfs.
Securityfs is normally mounted as /sys/kernel/security
The following files are created under /sys/kernel/security/apparmor
control
audit - Controls the global setting for auditing all
accesses.
complain - Controls the global setting for learning mode
(usually this is set per profile rather than
globally)
debug - Controls whether debugging is enabled.
This needs to be made more fine grained
logsyscall - Controls whether when logging to the audit
subsystem full syscall auditing is enabled.
The values by default for all of the above are 0.
matching - Returns the features of the installed matching submodule
profiles - Returns the profiles currently loaded and for each whether
it is in complain (learning) or enforce mode.
.load
.remove
.replace - Used by userspace tools to load, remove and replace new
profiles.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
security/apparmor/apparmorfs.c | 432 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 432 insertions(+)
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/apparmorfs.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2005 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 filesystem (part of securityfs)
+ */
+
+#include <linux/security.h>
+#include <linux/vmalloc.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+
+#include "apparmor.h"
+#include "inline.h"
+#include "match/match.h"
+
+#define SECFS_AA "apparmor"
+static struct dentry *aafs_dentry = NULL;
+
+/* profile */
+extern struct seq_operations apparmorfs_profiles_op;
+static int aa_prof_open(struct inode *inode, struct file *file);
+static int aa_prof_release(struct inode *inode, struct file *file);
+
+static struct file_operations apparmorfs_profiles_fops = {
+ .open = aa_prof_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = aa_prof_release,
+};
+
+/* matching */
+static ssize_t aa_matching_read(struct file *file, char __user *buf,
+ size_t size, loff_t *ppos);
+
+static struct file_operations apparmorfs_matching_fops = {
+ .read = aa_matching_read,
+};
+
+
+/* interface */
+static ssize_t aa_profile_load(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos);
+static ssize_t aa_profile_replace(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos);
+static ssize_t aa_profile_remove(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos);
+
+static struct file_operations apparmorfs_profile_load = {
+ .write = aa_profile_load
+};
+
+static struct file_operations apparmorfs_profile_replace = {
+ .write = aa_profile_replace
+};
+
+static struct file_operations apparmorfs_profile_remove = {
+ .write = aa_profile_remove
+};
+
+
+/* control */
+static u64 aa_control_get(void *data);
+static void aa_control_set(void *data, u64 val);
+
+DEFINE_SIMPLE_ATTRIBUTE(apparmorfs_control_fops, aa_control_get,
+ aa_control_set, "%lld\n");
+
+
+
+/* table of static entries */
+
+static struct root_entry {
+ const char *name;
+ int mode;
+ int access;
+ struct file_operations *fops;
+ void *data;
+
+ /* internal fields */
+ struct dentry *dentry;
+ int parent_index;
+} root_entries[] = {
+ /* our root, normally /sys/kernel/security/apparmor */
+ {SECFS_AA, S_IFDIR, 0550}, /* DO NOT EDIT/MOVE */
+
+ /* interface for obtaining list of profiles currently loaded */
+ {"profiles", S_IFREG, 0440, &apparmorfs_profiles_fops,
+ NULL},
+
+ /* interface for obtaining matching features supported */
+ {"matching", S_IFREG, 0440, &apparmorfs_matching_fops,
+ NULL},
+
+ /* interface for loading/removing/replacing profiles */
+ {".load", S_IFREG, 0640, &apparmorfs_profile_load,
+ NULL},
+ {".replace", S_IFREG, 0640, &apparmorfs_profile_replace,
+ NULL},
+ {".remove", S_IFREG, 0640, &apparmorfs_profile_remove,
+ NULL},
+
+ /* interface for setting binary config values */
+ {"control", S_IFDIR, 0550},
+ {"complain", S_IFREG, 0640, &apparmorfs_control_fops,
+ &apparmor_complain},
+ {"audit", S_IFREG, 0640, &apparmorfs_control_fops,
+ &apparmor_audit},
+ {"debug", S_IFREG, 0640, &apparmorfs_control_fops,
+ &apparmor_debug},
+ {"logsyscall", S_IFREG, 0640, &apparmorfs_control_fops,
+ &apparmor_logsyscall},
+ {NULL, S_IFDIR, 0},
+
+ /* root end */
+ {NULL, S_IFDIR, 0}
+};
+
+#define AAFS_DENTRY root_entries[0].dentry
+
+static const unsigned int num_entries =
+ sizeof(root_entries) / sizeof(struct root_entry);
+
+
+
+static int aa_prof_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &apparmorfs_profiles_op);
+}
+
+
+static int aa_prof_release(struct inode *inode, struct file *file)
+{
+ return seq_release(inode, file);
+}
+
+static ssize_t aa_matching_read(struct file *file, char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ const char *matching = aamatch_features();
+
+ return simple_read_from_buffer(buf, size, ppos, matching,
+ strlen(matching));
+}
+
+static char *aa_simple_write_to_buffer(const char __user *userbuf,
+ size_t alloc_size, size_t copy_size,
+ loff_t *pos, const char *msg)
+{
+ struct aaprofile *active;
+ char *data;
+
+ if (*pos != 0) {
+ /* only writes from pos 0, that is complete writes */
+ data = ERR_PTR(-ESPIPE);
+ goto out;
+ }
+
+ /* Don't allow confined processes to load/replace/remove profiles.
+ * No sane person would add rules allowing this to a profile
+ * but we enforce the restriction anyways.
+ */
+ rcu_read_lock();
+ active = get_activeptr_rcu();
+ if (active) {
+ AA_WARN("REJECTING access to profile %s (%s(%d) "
+ "profile %s active %s)\n",
+ msg, current->comm, current->pid,
+ BASE_PROFILE(active)->name, active->name);
+
+ data = ERR_PTR(-EPERM);
+ goto out;
+ }
+ rcu_read_unlock();
+
+ data = vmalloc(alloc_size);
+ if (data == NULL) {
+ data = ERR_PTR(-ENOMEM);
+ goto out;
+ }
+
+ if (copy_from_user(data, userbuf, copy_size)) {
+ vfree(data);
+ data = ERR_PTR(-EFAULT);
+ goto out;
+ }
+
+out:
+ return data;
+}
+
+static ssize_t aa_profile_load(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos)
+{
+ char *data;
+ ssize_t error;
+
+ data = aa_simple_write_to_buffer(buf, size, size, pos, "load");
+
+ if (!IS_ERR(data)) {
+ error = aa_file_prof_add(data, size);
+ vfree(data);
+ } else {
+ error = PTR_ERR(data);
+ }
+
+ return error;
+}
+
+static ssize_t aa_profile_replace(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos)
+{
+ char *data;
+ ssize_t error;
+
+ data = aa_simple_write_to_buffer(buf, size, size, pos, "replacement");
+
+ if (!IS_ERR(data)) {
+ error = aa_file_prof_repl(data, size);
+ vfree(data);
+ } else {
+ error = PTR_ERR(data);
+ }
+
+ return error;
+}
+
+static ssize_t aa_profile_remove(struct file *f, const char __user *buf,
+ size_t size, loff_t *pos)
+{
+ char *data;
+ ssize_t error;
+
+ /* aa_file_prof_remove needs a null terminated string so 1 extra
+ * byte is allocated and null the copied data is then null terminated
+ */
+ data = aa_simple_write_to_buffer(buf, size+1, size, pos, "removal");
+
+ if (!IS_ERR(data)) {
+ data[size] = 0;
+ error = aa_file_prof_remove(data, size);
+ vfree(data);
+ } else {
+ error = PTR_ERR(data);
+ }
+
+ return error;
+}
+
+static u64 aa_control_get(void *data)
+{
+ return *(int *)data;
+}
+
+static void aa_control_set(void *data, u64 val)
+{
+ if (val > 1)
+ val = 1;
+
+ *(int*)data = (int)val;
+}
+
+static void clear_apparmorfs(void)
+{
+ unsigned int i;
+
+ for (i=0; i < num_entries;i++) {
+ unsigned int index;
+
+ if (root_entries[i].mode == S_IFDIR) {
+ if (root_entries[i].name)
+ /* defer dir free till all sub-entries freed */
+ continue;
+ else
+ /* cleanup parent */
+ index = root_entries[i].parent_index;
+ } else {
+ index = i;
+ }
+
+ if (root_entries[index].dentry) {
+ securityfs_remove(root_entries[index].dentry);
+
+ AA_DEBUG("%s: deleted apparmorfs entry name=%s "
+ "dentry=%p\n",
+ __FUNCTION__,
+ root_entries[index].name,
+ root_entries[index].dentry);
+
+ root_entries[index].dentry = NULL;
+ root_entries[index].parent_index = 0;
+ }
+ }
+}
+
+static int populate_apparmorfs(struct dentry *root)
+{
+ unsigned int i, parent_index, depth;
+
+ for (i = 0; i < num_entries; i++) {
+ root_entries[i].dentry = NULL;
+ root_entries[i].parent_index = 0;
+ }
+
+ /* 1. Verify entry 0 is valid [sanity check] */
+ if (num_entries == 0 ||
+ !root_entries[0].name ||
+ strcmp(root_entries[0].name, SECFS_AA) != 0 ||
+ root_entries[0].mode != S_IFDIR) {
+ AA_ERROR("%s: root entry 0 is not SECFS_AA/dir\n",
+ __FUNCTION__);
+ goto error;
+ }
+
+ /* 2. Build back pointers */
+ parent_index = 0;
+ depth = 1;
+
+ for (i = 1; i < num_entries; i++) {
+ root_entries[i].parent_index = parent_index;
+
+ if (root_entries[i].name &&
+ root_entries[i].mode == S_IFDIR) {
+ depth++;
+ parent_index = i;
+ } else if (!root_entries[i].name) {
+ if (root_entries[i].mode != S_IFDIR || depth == 0) {
+ AA_ERROR("%s: root_entry %d invalid (%u %d)",
+ __FUNCTION__, i,
+ root_entries[i].mode,
+ root_entries[i].parent_index);
+ goto error;
+ }
+
+ depth--;
+ parent_index = root_entries[parent_index].parent_index;
+ }
+ }
+
+ if (depth != 0) {
+ AA_ERROR("%s: root_entry table not correctly terminated\n",
+ __FUNCTION__);
+ goto error;
+ }
+
+ /* 3. Create root (parent=NULL) */
+ root_entries[0].dentry = securityfs_create_file(
+ root_entries[0].name,
+ root_entries[0].mode |
+ root_entries[0].access,
+ NULL, NULL, NULL);
+
+ if (IS_ERR(root_entries[0].dentry))
+ goto error;
+ else
+ AA_DEBUG("%s: created securityfs/apparmor [dentry=%p]\n",
+ __FUNCTION__, root_entries[0].dentry);
+
+
+ /* 4. create remaining nodes */
+ for (i = 1; i < num_entries; i++) {
+ struct dentry *parent;
+ void *data = NULL;
+ struct file_operations *fops = NULL;
+
+ /* end of directory ? */
+ if (!root_entries[i].name)
+ continue;
+
+ parent = root_entries[root_entries[i].parent_index].dentry;
+
+ if (root_entries[i].mode != S_IFDIR) {
+ data = root_entries[i].data;
+ fops = root_entries[i].fops;
+ }
+
+ root_entries[i].dentry = securityfs_create_file(
+ root_entries[i].name,
+ root_entries[i].mode |
+ root_entries[i].access,
+ parent,
+ data,
+ fops);
+
+ if (IS_ERR(root_entries[i].dentry))
+ goto cleanup_error;
+
+ AA_DEBUG("%s: added apparmorfs entry "
+ "name=%s mode=%x dentry=%p [parent %p]\n",
+ __FUNCTION__, root_entries[i].name,
+ root_entries[i].mode|root_entries[i].access,
+ root_entries[i].dentry, parent);
+ }
+
+ return 0;
+
+cleanup_error:
+ clear_apparmorfs();
+
+error:
+ return -EINVAL;
+}
+
+int create_apparmorfs(void)
+{
+ int error = 0;
+
+ if (AAFS_DENTRY) {
+ error = -EEXIST;
+ AA_ERROR("%s: Subdomain securityfs already exists\n",
+ __FUNCTION__);
+ } else {
+ error = populate_apparmorfs(aafs_dentry);
+ if (error != 0) {
+ AA_ERROR("%s: Error populating Subdomain securityfs\n",
+ __FUNCTION__);
+ }
+ }
+
+ return error;
+}
+
+void destroy_apparmorfs(void)
+{
+ if (AAFS_DENTRY)
+ clear_apparmorfs();
+}
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 6/11] security: AppArmor - Userspace interface
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (4 preceding siblings ...)
2006-04-19 17:49 ` [RFC][PATCH 5/11] security: AppArmor - Filesystem Tony Jones
@ 2006-04-19 17:49 ` Tony Jones
2006-04-20 21:39 ` Pavel Machek
2006-04-19 17:50 ` [RFC][PATCH 7/11] security: AppArmor - Misc (capabilities, data structures) Tony Jones
` (7 subsequent siblings)
13 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:49 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
This patch implements the interface between the userspace policy loader
and the kernel module. It is called by the .load, .remove and .replace
file_operations hooks implemented in apparmorfs.c.
The code is reponsible for serializing data in a platform independant
manner from userspace and creating/activating the necessary apparmor
profiles.
Certain aspects are delegated to the sub matching module which implements
the aamatch_* functions.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
security/apparmor/module_interface.c | 840 +++++++++++++++++++++++++++++++++++
security/apparmor/module_interface.h | 37 +
2 files changed, 877 insertions(+)
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/module_interface.c
@@ -0,0 +1,840 @@
+/*
+ * Copyright (C) 1998-2005 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 userspace policy interface
+ */
+
+#include <asm/unaligned.h>
+
+#include "apparmor.h"
+#include "inline.h"
+#include "module_interface.h"
+#include "match/match.h"
+
+/* aa_code defined in module_interface.h */
+
+const int aacode_datasize[] = { 1, 2, 4, 8, 2, 2, 4, 0, 0, 0, 0, 0, 0 };
+
+struct aa_taskreplace_data {
+ struct aaprofile *old_profile;
+ struct aaprofile *new_profile;
+};
+
+/* inlines must be forward of there use in newer version of gcc,
+ just forward declaring with a prototype won't work anymore */
+
+static inline void free_aa_entry(struct aa_entry *entry)
+{
+ if (entry) {
+ kfree(entry->filename);
+ aamatch_free(entry->extradata);
+ kfree(entry);
+ }
+}
+
+/**
+ * alloc_aa_entry - create new empty aa_entry
+ * This routine allocates, initializes, and returns a new aa_entry
+ * file entry structure. Structure is zeroed. Returns new structure on
+ * success, %NULL on failure.
+ */
+static inline struct aa_entry *alloc_aa_entry(void)
+{
+ struct aa_entry *entry;
+
+ AA_DEBUG("%s\n", __FUNCTION__);
+ entry = kzalloc(sizeof(struct aa_entry), GFP_KERNEL);
+ if (entry) {
+ int i;
+ INIT_LIST_HEAD(&entry->list);
+ for (i = 0; i <= POS_AA_FILE_MAX; i++) {
+ INIT_LIST_HEAD(&entry->listp[i]);
+ }
+ }
+ return entry;
+}
+
+/**
+ * free_aaprofile_rcu - rcu callback for free profiles
+ * @head: rcu_head struct of the profile whose reference is being put.
+ *
+ * the rcu callback routine, which delays the freeing of a profile when
+ * its last reference is put.
+ */
+static void free_aaprofile_rcu(struct rcu_head *head)
+{
+ struct aaprofile *p = container_of(head, struct aaprofile, rcu);
+ free_aaprofile(p);
+}
+
+/**
+ * task_remove - remove profile from a task's subdomain
+ * @sd: task's subdomain
+ *
+ * remove the active profile from a task's subdomain, switching the task
+ * to an unconfined state.
+ */
+static inline void task_remove(struct subdomain *sd)
+{
+ /* spin_lock(&sd_lock) held here */
+ AA_DEBUG("%s: removing profile from task %s(%d) profile %s active %s\n",
+ __FUNCTION__,
+ sd->task->comm,
+ sd->task->pid,
+ BASE_PROFILE(sd->active)->name,
+ sd->active->name);
+
+ aa_switch_unconfined(sd);
+}
+
+/** taskremove_iter - Iterator to unconfine subdomains which match cookie
+ * @sd: subdomain to consider for profile removal
+ * @cookie: pointer to the oldprofile which is being removed
+ *
+ * If the subdomain's active profile matches old_profile, then call
+ * task_remove() to remove the profile leaving the task (subdomain) unconfined.
+ */
+static int taskremove_iter(struct subdomain *sd, void *cookie)
+{
+ struct aaprofile *old_profile = (struct aaprofile *)cookie;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sd_lock, flags);
+
+ if (__aa_is_confined(sd) && BASE_PROFILE(sd->active) == old_profile) {
+ task_remove(sd);
+ }
+
+ spin_unlock_irqrestore(&sd_lock, flags);
+
+ return 0;
+}
+
+/** task_replace - replace subdomain's current profile with a new profile
+ * @sd: subdomain to replace the profile on
+ * @new: new profile
+ *
+ * Replace a task's (subdomain's) active profile with a new profile. If
+ * task was in a hat then the new profile will also be in the equivalent
+ * hat in the new profile if it exists. If it doesn't exist the
+ * task will be placed in the special null_profile state.
+ */
+static inline void task_replace(struct subdomain *sd, struct aaprofile *new)
+{
+ AA_DEBUG("%s: replacing profile for task %s(%d) "
+ "profile=%s (%p) active=%s (%p)\n",
+ __FUNCTION__,
+ sd->task->comm, sd->task->pid,
+ BASE_PROFILE(sd->active)->name, BASE_PROFILE(sd->active),
+ sd->active->name, sd->active);
+
+ if (!sd->active)
+ goto out;
+
+ if (IN_SUBPROFILE(sd->active)) {
+ struct aaprofile *nactive;
+
+ /* The old profile was in a hat, check to see if the new
+ * profile has an equivalent hat */
+ nactive = __aa_find_profile(sd->active->name, &new->sub);
+
+ if (!nactive)
+ nactive = get_aaprofile(new->null_profile);
+
+ aa_switch(sd, nactive);
+ put_aaprofile(nactive);
+ } else {
+ aa_switch(sd, new);
+ }
+
+ out:
+ return;
+}
+
+/** taskreplace_iter - Iterator to replace a subdomain's profile
+ * @sd: subdomain to consider for profile replacement
+ * @cookie: pointer to the old profile which is being replaced.
+ *
+ * If the subdomain's active profile matches old_profile call
+ * task_replace() to replace with the subdomain's active profile with
+ * the new profile.
+ */
+static int taskreplace_iter(struct subdomain *sd, void *cookie)
+{
+ struct aa_taskreplace_data *data = (struct aa_taskreplace_data *)cookie;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sd_lock, flags);
+
+ if (__aa_is_confined(sd) &&
+ BASE_PROFILE(sd->active) == data->old_profile)
+ task_replace(sd, data->new_profile);
+
+ spin_unlock_irqrestore(&sd_lock, flags);
+
+ return 0;
+}
+
+static inline int aa_inbounds(struct aa_ext *e, size_t size)
+{
+ return (e->pos + size <= e->end);
+}
+
+/**
+ * aaconvert - convert trailing values of serialized type codes
+ * @code: type code
+ * @dest: pointer to object to receive the converted value
+ * @src: pointer to value to convert
+ *
+ * for serialized type codes which have a trailing value, convert it
+ * and place it in @dest. If a code does not have a trailing value nop.
+ */
+static void aaconvert(enum aa_code code, void *dest, void *src)
+{
+ switch (code) {
+ case AA_U8:
+ *(u8 *)dest = *(u8 *) src;
+ break;
+ case AA_U16:
+ case AA_NAME:
+ case AA_DYN_STRING:
+ *(u16 *)dest = le16_to_cpu(get_unaligned((u16 *)src));
+ break;
+ case AA_U32:
+ case AA_STATIC_BLOB:
+ *(u32 *)dest = le32_to_cpu(get_unaligned((u32 *)src));
+ break;
+ case AA_U64:
+ *(u64 *)dest = le64_to_cpu(get_unaligned((u64 *)src));
+ break;
+ default:
+ /* nop - all other type codes do not have a trailing value */
+ ;
+ }
+}
+
+/**
+ * aa_is_X - check if the next element is of type X
+ * @e: serialized data extent information
+ * @code: type code
+ * @data: object located at @e->pos (of type @code) is written into @data
+ * if @data is non-null. if data is null it means skip this
+ * entry
+ * check to see if the next element in the serialized data stream is of type
+ * X and check that it is with in bounds, if so put the associated value in
+ * @data.
+ * return the size of bytes associated with the returned data
+ * for complex object like blob and string a pointer to the allocated
+ * data is returned in data, but the size of the blob or string is
+ * returned.
+ */
+static u32 aa_is_X(struct aa_ext *e, enum aa_code code, void *data)
+{
+ void *pos = e->pos;
+ int ret = 0;
+ if (!aa_inbounds(e, AA_CODE_BYTE + aacode_datasize[code]))
+ goto fail;
+ if (code != *(u8 *)e->pos)
+ goto out;
+ e->pos += AA_CODE_BYTE;
+ if (code == AA_NAME) {
+ u16 size;
+ /* name codes are followed by X bytes */
+ size = le16_to_cpu(get_unaligned((u16 *)e->pos));
+ if (!aa_inbounds(e, (size_t) size))
+ goto fail;
+ if (data)
+ *(u16 *)data = size;
+ e->pos += aacode_datasize[code];
+ ret = 1 + aacode_datasize[code];
+ } else if (code == AA_DYN_STRING) {
+ u16 size;
+ char *str;
+ /* strings codes are followed by X bytes */
+ size = le16_to_cpu(get_unaligned((u16 *)e->pos));
+ e->pos += aacode_datasize[code];
+ if (!aa_inbounds(e, (size_t) size))
+ goto fail;
+ if (data) {
+ * (char **)data = NULL;
+ str = kmalloc(size, GFP_KERNEL);
+ if (!str)
+ goto fail;
+ memcpy(str, e->pos, (size_t) size);
+ str[size-1] = '\0';
+ * (char **)data = str;
+ }
+ e->pos += size;
+ ret = size;
+ } else if (code == AA_STATIC_BLOB) {
+ u32 size;
+ /* blobs are followed by X bytes, that can be 2^32 */
+ size = le32_to_cpu(get_unaligned((u32 *)e->pos));
+ e->pos += aacode_datasize[code];
+ if (!aa_inbounds(e, (size_t) size))
+ goto fail;
+ if (data)
+ memcpy(data, e->pos, (size_t) size);
+ e->pos += size;
+ ret = size;
+ } else {
+ if (data)
+ aaconvert(code, data, e->pos);
+ e->pos += aacode_datasize[code];
+ ret = 1 + aacode_datasize[code];
+ }
+out:
+ return ret;
+fail:
+ e->pos = pos;
+ return 0;
+}
+
+/**
+ * aa_is_nameX - check is the next element is of type X with a name of @name
+ * @e: serialized data extent information
+ * @code: type code
+ * @data: location to store deserialized data if match isX criteria
+ * @name: name to match to the serialized element.
+ *
+ * check that the next serialized data element is of type X and has a tag
+ * name @name. If the code matches and name (if specified) matches then
+ * the packed data is unpacked into *data. (Note for strings this is the
+ * size, and the next data in the stream is the string data)
+ * returns %0 if either match failes
+ */
+static int aa_is_nameX(struct aa_ext *e, enum aa_code code, void *data,
+ const char *name)
+{
+ void *pos = e->pos;
+ u16 size;
+ u32 ret;
+ /* check for presence of a tagname, and if present name size
+ * AA_NAME tag value is a u16 */
+ if (aa_is_X(e, AA_NAME, &size)) {
+ /* if a name is specified it must match. otherwise skip tag */
+ if (name && ((strlen(name) != size-1) ||
+ strncmp(name, (char *)e->pos, (size_t)size-1)))
+ goto fail;
+ e->pos += size;
+ }
+ /* now check if data actually matches */
+ ret = aa_is_X(e, code, data);
+ if (!ret)
+ goto fail;
+ return ret;
+
+fail:
+ e->pos = pos;
+ return 0;
+}
+
+/* macro to wrap error case to make a block of reads look nicer */
+#define AA_READ_X(E, C, D, N) \
+ do { \
+ u32 __ret; \
+ __ret = aa_is_nameX((E), (C), (D), (N)); \
+ if (!__ret) \
+ goto fail; \
+ } while (0)
+
+/**
+ * aa_activate_net_entry - unpacked serialized net entries
+ * @e: serialized data extent information
+ *
+ * Ignore/skips net entries if they are present in the serialized data
+ * stream. Network confinement rules are currently unsupported but some
+ * user side tools can generate them so they are currently ignored.
+ */
+static inline int aa_activate_net_entry(struct aa_ext *e)
+{
+ AA_READ_X(e, AA_STRUCT, NULL, "ne");
+ AA_READ_X(e, AA_U32, NULL, NULL);
+ AA_READ_X(e, AA_U32, NULL, NULL);
+ AA_READ_X(e, AA_U32, NULL, NULL);
+ AA_READ_X(e, AA_U16, NULL, NULL);
+ AA_READ_X(e, AA_U16, NULL, NULL);
+ AA_READ_X(e, AA_U32, NULL, NULL);
+ AA_READ_X(e, AA_U32, NULL, NULL);
+ AA_READ_X(e, AA_U16, NULL, NULL);
+ AA_READ_X(e, AA_U16, NULL, NULL);
+ /* interface name is optional so just ignore return code */
+ aa_is_nameX(e, AA_DYN_STRING, NULL, NULL);
+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
+
+ return 1;
+fail:
+ return 0;
+}
+
+/**
+ * aa_activate_file_entry - unpack serialized file entry
+ * @e: serialized data extent information
+ *
+ * unpack the information used for a file ACL entry.
+ */
+static inline struct aa_entry *aa_activate_file_entry(struct aa_ext *e)
+{
+ struct aa_entry *entry = NULL;
+
+ if (!(entry = alloc_aa_entry()))
+ goto fail;
+
+ AA_READ_X(e, AA_STRUCT, NULL, "fe");
+ AA_READ_X(e, AA_DYN_STRING, &entry->filename, NULL);
+ AA_READ_X(e, AA_U32, &entry->mode, "file.mode");
+ AA_READ_X(e, AA_U32, &entry->type, "file.pattern_type");
+
+ entry->extradata = aamatch_alloc(entry->type);
+ if (IS_ERR(entry->extradata)) {
+ entry->extradata = NULL;
+ goto fail;
+ }
+
+ if (entry->extradata &&
+ aamatch_serialize(entry->extradata, e, aa_is_nameX) != 0) {
+ goto fail;
+ }
+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
+
+ switch (entry->type) {
+ case aa_entry_literal:
+ AA_DEBUG("%s: %s [no pattern] mode=0x%x\n",
+ __FUNCTION__,
+ entry->filename,
+ entry->mode);
+ break;
+ case aa_entry_tailglob:
+ AA_DEBUG("%s: %s [tailglob] mode=0x%x\n",
+ __FUNCTION__,
+ entry->filename,
+ entry->mode);
+ break;
+ case aa_entry_pattern:
+ AA_DEBUG("%s: %s mode=0x%x\n",
+ __FUNCTION__,
+ entry->filename,
+ entry->mode);
+ break;
+ default:
+ AA_WARN("%s: INVALID entry_match_type %d\n",
+ __FUNCTION__,
+ (int)entry->type);
+ goto fail;
+ }
+
+ return entry;
+
+fail:
+ aamatch_free(entry->extradata);
+ free_aa_entry(entry);
+ return NULL;
+}
+
+/**
+ * check_rule_and_add - check a file rule is valid and add to a profile
+ * @file_entry: file rule to add
+ * @profile: profile to add the rule to
+ * @message: error message returned if the addition failes.
+ *
+ * perform consistency check to ensure that a file rule entry is valid.
+ * If the rule is valid it is added to the profile.
+ */
+static inline int check_rule_and_add(struct aa_entry *file_entry,
+ struct aaprofile *profile,
+ const char **message)
+{
+ /* verify consistency of x, px, ix, ux for entry against
+ possible duplicates for this entry */
+ int mode = AA_EXEC_MODIFIER_MASK(file_entry->mode);
+ int i;
+
+ if (mode && !(AA_MAY_EXEC & file_entry->mode)) {
+ *message = "inconsistent rule, x modifiers without x";
+ goto out;
+ }
+
+ /* check that only 1 of the modifiers is set */
+ if (mode && (mode & (mode - 1))) {
+ *message = "inconsistent rule, multiple x modifiers";
+ goto out;
+ }
+
+ list_add(&file_entry->list, &profile->file_entry);
+ profile->num_file_entries++;
+
+ mode = file_entry->mode;
+
+ /* Handle partitioned lists
+ * Chain entries onto sublists based on individual
+ * permission bits. This allows more rapid searching.
+ */
+ for (i = 0; i <= POS_AA_FILE_MAX; i++) {
+ if (mode & (1 << i))
+ /* profile->file_entryp[i] initially set to
+ * NULL in alloc_aaprofile() */
+ list_add(&file_entry->listp[i],
+ &profile->file_entryp[i]);
+ }
+
+ return 1;
+
+out:
+ free_aa_entry(file_entry);
+ return 0;
+}
+
+#define AA_ENTRY_LIST(NAME) \
+ do { \
+ if (aa_is_nameX(e, AA_LIST, NULL, (NAME))) { \
+ rulename = ""; \
+ error_string = "Invalid file entry"; \
+ while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) { \
+ struct aa_entry *file_entry; \
+ file_entry = aa_activate_file_entry(e); \
+ if (!file_entry) \
+ goto fail; \
+ if (!check_rule_and_add(file_entry, profile, \
+ &error_string)) { \
+ rulename = file_entry->filename; \
+ goto fail; \
+ } \
+ } \
+ } \
+ } while (0)
+
+/**
+ * aa_activate_profile - unpack a serialized profile
+ * @e: serialized data extent information
+ * @error: error code returned if unpacking fails
+ */
+static struct aaprofile *aa_activate_profile(struct aa_ext *e, ssize_t *error)
+{
+ struct aaprofile *profile = NULL;
+ const char *rulename = "";
+ const char *error_string = "Invalid Profile";
+
+ *error = -EPROTO;
+
+ profile = alloc_aaprofile();
+ if (!profile) {
+ error_string = "Could not allocate profile";
+ *error = -ENOMEM;
+ goto fail;
+ }
+
+ /* check that we have the right struct being passed */
+ AA_READ_X(e, AA_STRUCT, NULL, "profile");
+ AA_READ_X(e, AA_DYN_STRING, &profile->name, NULL);
+
+ error_string = "Invalid flags";
+ /* per profile debug flags (debug, complain, audit) */
+ AA_READ_X(e, AA_STRUCT, NULL, "flags");
+ AA_READ_X(e, AA_U32, &(profile->flags.debug), "profile.flags.debug");
+ AA_READ_X(e, AA_U32, &(profile->flags.complain),
+ "profile.flags.complain");
+ AA_READ_X(e, AA_U32, &(profile->flags.audit), "profile.flags.audit");
+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
+
+ error_string = "Invalid capabilities";
+ AA_READ_X(e, AA_U32, &(profile->capabilities), "profile.capabilities");
+
+ /* get the file entries. */
+ AA_ENTRY_LIST("pgent"); /* pcre rules */
+ AA_ENTRY_LIST("sgent"); /* simple globs */
+ AA_ENTRY_LIST("fent"); /* regular file entries */
+
+ /* get the net entries */
+ if (aa_is_nameX(e, AA_LIST, NULL, "net")) {
+ error_string = "Invalid net entry";
+ while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
+ if (!aa_activate_net_entry(e))
+ goto fail;
+ }
+ }
+ rulename = "";
+
+ /* get subprofiles */
+ if (aa_is_nameX(e, AA_LIST, NULL, "hats")) {
+ error_string = "Invalid profile hat";
+ while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
+ struct aaprofile *subprofile;
+ subprofile = aa_activate_profile(e, error);
+ if (!subprofile)
+ goto fail;
+ subprofile->parent = profile;
+ list_add(&subprofile->list, &profile->sub);
+ }
+ }
+
+ error_string = "Invalid end of profile";
+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
+
+ return profile;
+
+fail:
+ AA_WARN("%s: %s %s in profile %s\n", INTERFACE_ID, rulename,
+ error_string, profile && profile->name ? profile->name
+ : "unknown");
+
+ if (profile) {
+ free_aaprofile(profile);
+ profile = NULL;
+ }
+
+ return NULL;
+}
+
+/**
+ * aa_activate_top_profile - unpack a serialized base profile
+ * @e: serialized data extent information
+ * @error: error code returned if unpacking fails
+ *
+ * check interface version unpack a profile and all its hats and patch
+ * in any extra information that the profile needs.
+ */
+static void *aa_activate_top_profile(struct aa_ext *e, ssize_t *error)
+{
+ struct aaprofile *profile = NULL;
+
+ /* get the interface version */
+ if (!aa_is_nameX(e, AA_U32, &e->version, "version")) {
+ AA_WARN("%s: version missing\n", INTERFACE_ID);
+ *error = -EPROTONOSUPPORT;
+ goto fail;
+ }
+
+ /* check that the interface version is currently supported */
+ if (e->version != 2) {
+ AA_WARN("%s: unsupported interface version (%d)\n",
+ INTERFACE_ID, e->version);
+ *error = -EPROTONOSUPPORT;
+ goto fail;
+ }
+
+ profile = aa_activate_profile(e, error);
+ if (!profile)
+ goto fail;
+
+ if (!list_empty(&profile->sub) || profile->flags.complain) {
+ if (attach_nullprofile(profile))
+ goto fail;
+ }
+ return profile;
+
+fail:
+ free_aaprofile(profile);
+ return NULL;
+}
+
+/**
+ * aa_file_prof_add - add a new profile to the profile list
+ * @data: serialized data stream
+ * @size: size of the serialized data stream
+ *
+ * unpack and add a profile to the profile list. Return %0 or error
+ */
+ssize_t aa_file_prof_add(void *data, size_t size)
+{
+ struct aaprofile *profile = NULL;
+
+ struct aa_ext e = {
+ .start = data,
+ .end = data + size,
+ .pos = data
+ };
+ ssize_t error;
+
+ profile = aa_activate_top_profile(&e, &error);
+ if (!profile) {
+ AA_DEBUG("couldn't activate profile\n");
+ goto out;
+ }
+
+ /* aa_activate_top_profile allocates profile with initial 1 count
+ * aa_profilelist_add transfers that ref to profile list without
+ * further incrementing
+ */
+ if (aa_profilelist_add(profile)) {
+ error = size;
+ } else {
+ AA_WARN("trying to add profile (%s) that already exists.\n",
+ profile->name);
+ put_aaprofile(profile);
+ error = -EEXIST;
+ }
+
+out:
+ return error;
+}
+
+/**
+ * aa_file_prof_repl - replace a profile on the profile list
+ * @udata: serialized data stream
+ * @size: size of the serialized data stream
+ *
+ * unpack and replace a profile on the profile list and uses of that profile
+ * by any subdomain. If the profile does not exist on the profile list
+ * it is added. Return %0 or error.
+ */
+ssize_t aa_file_prof_repl(void *udata, size_t size)
+{
+ struct aa_taskreplace_data data;
+ struct aa_ext e = {
+ .start = udata,
+ .end = udata + size,
+ .pos = udata
+ };
+
+ ssize_t error;
+
+ data.new_profile = aa_activate_top_profile(&e, &error);
+ if (!data.new_profile) {
+ AA_DEBUG("couldn't activate profile\n");
+ goto out;
+ }
+
+ /* Refcount on data.new_profile is 1 (aa_activate_top_profile).
+ *
+ * This reference will be inherited by aa_profilelist_replace for it's
+ * profile list reference but this isn't sufficient.
+ *
+ * Another replace (*for-same-profile*) may race us here.
+ * Task A calls aa_profilelist_replace(new_profile) and is interrupted.
+ * Task B old_profile = aa_profilelist_replace() will return task A's
+ * new_profile with the count of 1. If task B proceeeds to put this
+ * profile it will dissapear from under task A.
+ *
+ * Grab extra reference on new_profile to prevent this
+ */
+
+ get_aaprofile(data.new_profile);
+
+ data.old_profile = aa_profilelist_replace(data.new_profile);
+
+ /* If there was an old profile, find all currently executing tasks
+ * using this profile and replace the old profile with the new.
+ */
+ if (data.old_profile) {
+ AA_DEBUG("%s: try to replace profile (%p)%s\n",
+ __FUNCTION__,
+ data.old_profile,
+ data.old_profile->name);
+
+ aa_subdomainlist_iterate(taskreplace_iter, (void *)&data);
+
+ /* it's off global list, and we are done replacing */
+ put_aaprofile(data.old_profile);
+ }
+
+ /* release extra reference obtained above (race) */
+ put_aaprofile(data.new_profile);
+
+ error = size;
+
+out:
+ return error;
+}
+
+/**
+ * aa_file_prof_remove - remove a profile from the system
+ * @name: name of the profile to remove
+ * @size: size of the name
+ *
+ * remove a profile from the profile list and all subdomain references
+ * to said profile. Return %0 on success, else error.
+ */
+ssize_t aa_file_prof_remove(const char *name, size_t size)
+{
+ struct aaprofile *old_profile;
+
+ /* if the old profile exists it will be removed from the list and
+ * a reference is returned.
+ */
+ old_profile = aa_profilelist_remove(name);
+
+ if (old_profile) {
+ /* remove profile from any tasks using it */
+ aa_subdomainlist_iterate(taskremove_iter, (void *)old_profile);
+
+ /* drop reference obtained by aa_profilelist_remove */
+ put_aaprofile(old_profile);
+ } else {
+ AA_WARN("%s: trying to remove profile (%s) that "
+ "doesn't exist - skipping.\n", __FUNCTION__, name);
+ return -ENOENT;
+ }
+
+ return size;
+}
+
+/**
+ * free_aaprofile_kref - free aaprofile by kref (called by put_aaprofile)
+ * @kr: kref callback for freeing of a profile
+ */
+void free_aaprofile_kref(struct kref *kr)
+{
+ struct aaprofile *p=container_of(kr, struct aaprofile, count);
+
+ call_rcu(&p->rcu, free_aaprofile_rcu);
+}
+
+/**
+ * free_aaprofile - free aaprofile structure
+ * @profile: the profile to free
+ *
+ * free a profile, its file entries hats and null_profile. All references
+ * to the profile, its hats and null_profile must have been put.
+ * If the profile was referenced by a subdomain free_aaprofile should be
+ * called from an rcu callback routine.
+ */
+void free_aaprofile(struct aaprofile *profile)
+{
+ struct aa_entry *ent, *tmp;
+ struct aaprofile *p, *ptmp;
+
+ AA_DEBUG("%s(%p)\n", __FUNCTION__, profile);
+
+ if (!profile)
+ return;
+
+ /* profile is still on global profile list -- invalid */
+ if (!list_empty(&profile->list)) {
+ AA_ERROR("%s: internal error, "
+ "profile '%s' still on global list\n",
+ __FUNCTION__,
+ profile->name);
+ BUG();
+ }
+
+ list_for_each_entry_safe(ent, tmp, &profile->file_entry, list) {
+ if (ent->filename)
+ AA_DEBUG("freeing aa_entry: %p %s\n",
+ ent->filename, ent->filename);
+ list_del_init(&ent->list);
+ free_aa_entry(ent);
+ }
+
+ /* use free_aaprofile instead of put_aaprofile to destroy the
+ * null_profile, because the null_profile use the same reference
+ * counting as hats, ie. the count goes to the base profile.
+ */
+ free_aaprofile(profile->null_profile);
+ list_for_each_entry_safe(p, ptmp, &profile->sub, list) {
+ list_del_init(&p->list);
+ p->parent = NULL;
+ put_aaprofile(p);
+ }
+
+ if (profile->name) {
+ AA_DEBUG("%s: %s\n", __FUNCTION__, profile->name);
+ kfree(profile->name);
+ }
+
+ kfree(profile);
+}
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/module_interface.h
@@ -0,0 +1,37 @@
+#ifndef __MODULEINTERFACE_H
+#define __MODULEINTERFACE_H
+
+/* Codes of the types of basic structures that are understood */
+#define AA_CODE_BYTE (sizeof(u8))
+#define INTERFACE_ID "INTERFACE"
+
+#define SUBDOMAIN_INTERFACE_VERSION 2
+
+enum aa_code {
+ AA_U8,
+ AA_U16,
+ AA_U32,
+ AA_U64,
+ AA_NAME, /* same as string except it is items name */
+ AA_DYN_STRING,
+ AA_STATIC_BLOB,
+ AA_STRUCT,
+ AA_STRUCTEND,
+ AA_LIST,
+ AA_LISTEND,
+ AA_OFFSET,
+ AA_BAD
+};
+
+/* aa_ext tracks the kernel buffer and read position in it. The interface
+ * data is copied into a kernel buffer in apparmorfs and then handed off to
+ * the activate routines.
+ */
+struct aa_ext {
+ void *start;
+ void *end;
+ void *pos; /* pointer to current position in the buffer */
+ u32 version;
+};
+
+#endif /* __MODULEINTERFACE_H */
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 7/11] security: AppArmor - Misc (capabilities, data structures)
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (5 preceding siblings ...)
2006-04-19 17:49 ` [RFC][PATCH 6/11] security: AppArmor - Userspace interface Tony Jones
@ 2006-04-19 17:50 ` Tony Jones
2006-04-19 18:16 ` Stephen Hemminger
2006-04-19 17:50 ` [RFC][PATCH 8/11] security: AppArmor - Pathname matching submodule Tony Jones
` (6 subsequent siblings)
13 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:50 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
This patch implements three distinct chunks.
- list management, for profiles loaded into the system (profile_list) and for
the set of confined tasks (subdomain_list)
- the proc/pid/attr interface used by userspace for setprofile (forcing
a task into a new profile) and changehat (switching a task into one of it's
defined sub profiles). Access to change_hat is normally via code provided
in libapparmor. See the overview posting for more information in change hat.
- capability utility functions (for displaying capability names)
Signed-off-by: Tony Jones <tonyj@suse.de>
---
security/apparmor/capabilities.c | 54 ++++++
security/apparmor/list.c | 268 +++++++++++++++++++++++++++++++
security/apparmor/procattr.c | 327 +++++++++++++++++++++++++++++++++++++++
3 files changed, 649 insertions(+)
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/capabilities.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2005 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 capability definitions
+ */
+
+#include "apparmor.h"
+
+static const char *cap_names[] = {
+ "chown",
+ "dac_override",
+ "dac_read_search",
+ "fowner",
+ "fsetid",
+ "kill",
+ "setgid",
+ "setuid",
+ "setpcap",
+ "linux_immutable",
+ "net_bind_service",
+ "net_broadcast",
+ "net_admin",
+ "net_raw",
+ "ipc_lock",
+ "ipc_owner",
+ "sys_module",
+ "sys_rawio",
+ "sys_chroot",
+ "sys_ptrace",
+ "sys_pacct",
+ "sys_admin",
+ "sys_boot",
+ "sys_nice",
+ "sys_resource",
+ "sys_time",
+ "sys_tty_config",
+ "mknod",
+ "lease"
+};
+
+const char *capability_to_name(unsigned int cap)
+{
+ const char *name;
+
+ name = (cap < (sizeof(cap_names) / sizeof(char *))
+ ? cap_names[cap] : "invalid-capability");
+
+ return name;
+}
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/list.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 1998-2005 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 Profile List Management
+ */
+
+#include <linux/seq_file.h>
+#include "apparmor.h"
+#include "inline.h"
+
+/* list of all profiles and lock */
+static LIST_HEAD(profile_list);
+static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
+
+/* list of all subdomains and lock */
+static LIST_HEAD(subdomain_list);
+static rwlock_t subdomain_lock = RW_LOCK_UNLOCKED;
+
+/**
+ * aa_profilelist_find
+ * @name: profile name (program name)
+ *
+ * Search the profile list for profile @name. Return refcounted profile on
+ * success, NULL on failure.
+ */
+struct aaprofile *aa_profilelist_find(const char *name)
+{
+ struct aaprofile *p = NULL;
+ if (name) {
+ read_lock(&profile_lock);
+ p = __aa_find_profile(name, &profile_list);
+ read_unlock(&profile_lock);
+ }
+ return p;
+}
+
+/**
+ * aa_profilelist_add - add new profile to list
+ * @profile: new profile to add to list
+ *
+ * NOTE: Caller must allocate necessary reference count that will be used
+ * by the profile_list. This is because profile allocation alloc_aaprofile()
+ * returns an unreferenced object with a initial count of %1.
+ *
+ * Return %1 on success, %0 on failure (already exists)
+ */
+int aa_profilelist_add(struct aaprofile *profile)
+{
+ struct aaprofile *old_profile;
+ int ret = 0;
+
+ if (!profile)
+ goto out;
+
+ write_lock(&profile_lock);
+ old_profile = __aa_find_profile(profile->name, &profile_list);
+ if (old_profile) {
+ put_aaprofile(old_profile);
+ goto out;
+ }
+
+ list_add(&profile->list, &profile_list);
+ ret = 1;
+ out:
+ write_unlock(&profile_lock);
+ return ret;
+}
+
+/**
+ * aa_profilelist_remove - remove a profile from the list by name
+ * @name: name of profile to be removed
+ *
+ * If the profile exists remove profile from list and return its reference.
+ * The reference count on profile is not decremented and should be decremented
+ * when the profile is no longer needed
+ */
+struct aaprofile *aa_profilelist_remove(const char *name)
+{
+ struct aaprofile *profile = NULL;
+ struct aaprofile *p, *tmp;
+
+ if (!name)
+ goto out;
+
+ write_lock(&profile_lock);
+ list_for_each_entry_safe(p, tmp, &profile_list, list) {
+ if (!strcmp(p->name, name)) {
+ list_del_init(&p->list);
+ /* mark old profile as stale */
+ p->isstale = 1;
+ profile = p;
+ break;
+ }
+ }
+ write_unlock(&profile_lock);
+
+out:
+ return profile;
+}
+
+/**
+ * aa_profilelist_replace - replace a profile on the list
+ * @profile: new profile
+ *
+ * Replace a profile on the profile list. Find the old profile by name in
+ * the list, and replace it with the new profile. NOTE: Caller must allocate
+ * necessary initial reference count for new profile as aa_profilelist_add().
+ *
+ * This is an atomic list operation. Returns the old profile (which is still
+ * refcounted) if there was one, or NULL.
+ */
+struct aaprofile *aa_profilelist_replace(struct aaprofile *profile)
+{
+ struct aaprofile *oldprofile;
+
+ write_lock(&profile_lock);
+ oldprofile = __aa_find_profile(profile->name, &profile_list);
+ if (oldprofile) {
+ list_del_init(&oldprofile->list);
+ /* mark old profile as stale */
+ oldprofile->isstale = 1;
+
+ /* __aa_find_profile incremented count, so adjust down */
+ put_aaprofile(oldprofile);
+ }
+
+ list_add(&profile->list, &profile_list);
+ write_unlock(&profile_lock);
+
+ return oldprofile;
+}
+
+/**
+ * aa_profilelist_release - Remove all profiles from profile_list
+ */
+void aa_profilelist_release(void)
+{
+ struct aaprofile *p, *tmp;
+
+ write_lock(&profile_lock);
+ list_for_each_entry_safe(p, tmp, &profile_list, list) {
+ list_del_init(&p->list);
+ put_aaprofile(p);
+ }
+ write_unlock(&profile_lock);
+}
+
+/**
+ * aa_subdomainlist_add - Add subdomain to subdomain_list
+ * @sd: new subdomain
+ */
+void aa_subdomainlist_add(struct subdomain *sd)
+{
+ unsigned long flags;
+
+ if (!sd) {
+ AA_INFO("%s: bad subdomain\n", __FUNCTION__);
+ return;
+ }
+
+ write_lock_irqsave(&subdomain_lock, flags);
+ /* new subdomains must be added to the end of the list due to a
+ * subtle interaction between fork and profile replacement.
+ */
+ list_add_tail(&sd->list, &subdomain_list);
+ write_unlock_irqrestore(&subdomain_lock, flags);
+}
+
+/**
+ * aa_subdomainlist_remove - Remove subdomain from subdomain_list
+ * @sd: subdomain to be removed
+ */
+void aa_subdomainlist_remove(struct subdomain *sd)
+{
+ unsigned long flags;
+
+ if (sd) {
+ write_lock_irqsave(&subdomain_lock, flags);
+ list_del_init(&sd->list);
+ write_unlock_irqrestore(&subdomain_lock, flags);
+ }
+}
+
+/**
+ * aa_subdomainlist_iterate - iterate over the subdomain list applying @func
+ * @func: method to be called for each element
+ * @cookie: user passed data
+ *
+ * Iterate over subdomain list applying @func, stop when @func returns
+ * non zero
+ */
+void aa_subdomainlist_iterate(aa_iter func, void *cookie)
+{
+ struct subdomain *node;
+ int ret = 0;
+ unsigned long flags;
+
+ read_lock_irqsave(&subdomain_lock, flags);
+ list_for_each_entry(node, &subdomain_list, list) {
+ ret = (*func) (node, cookie);
+ if (ret != 0)
+ break;
+ }
+ read_unlock_irqrestore(&subdomain_lock, flags);
+}
+
+/**
+ * aa_subdomainlist_release - Remove all subdomains from subdomain_list
+ */
+void aa_subdomainlist_release()
+{
+ struct subdomain *node, *tmp;
+ unsigned long flags;
+
+ write_lock_irqsave(&subdomain_lock, flags);
+ list_for_each_entry_safe(node, tmp, &subdomain_list, list) {
+ list_del_init(&node->list);
+ }
+ write_unlock_irqrestore(&subdomain_lock, flags);
+}
+
+/* seq_file helper routines
+ * Used by apparmorfs.c to iterate over profile_list
+ */
+static void *p_start(struct seq_file *f, loff_t *pos)
+{
+ struct aaprofile *node;
+ loff_t l = *pos;
+
+ read_lock(&profile_lock);
+ list_for_each_entry(node, &profile_list, list)
+ if (!l--)
+ return node;
+ return NULL;
+}
+
+static void *p_next(struct seq_file *f, void *p, loff_t *pos)
+{
+ struct list_head *lh = ((struct aaprofile *)p)->list.next;
+ (*pos)++;
+ return lh == &profile_list ?
+ NULL : list_entry(lh, struct aaprofile, list);
+}
+
+static void p_stop(struct seq_file *f, void *v)
+{
+ read_unlock(&profile_lock);
+}
+
+static int seq_show_profile(struct seq_file *f, void *v)
+{
+ struct aaprofile *profile = (struct aaprofile *)v;
+ seq_printf(f, "%s (%s)\n", profile->name,
+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce");
+ return 0;
+}
+
+struct seq_operations apparmorfs_profiles_op = {
+ .start = p_start,
+ .next = p_next,
+ .stop = p_stop,
+ .show = seq_show_profile,
+};
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/procattr.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2005 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 /proc/pid/attr handling
+ */
+
+/* for isspace */
+#include <linux/ctype.h>
+
+#include "apparmor.h"
+#include "inline.h"
+
+size_t aa_getprocattr(struct aaprofile *active, char *str, size_t size)
+{
+ int error = -EACCES; /* default to a perm denied */
+ size_t len;
+
+ if (active) {
+ size_t lena, lenm, lenp = 0;
+ const char *enforce_str = " (enforce)";
+ const char *complain_str = " (complain)";
+ const char *mode_str =
+ PROFILE_COMPLAIN(active) ? complain_str : enforce_str;
+
+ lenm = strlen(mode_str);
+
+ lena = strlen(active->name);
+
+ len = lena;
+ if (IN_SUBPROFILE(active)) {
+ lenp = strlen(BASE_PROFILE(active)->name);
+ len += (lenp + 1); /* +1 for ^ */
+ }
+ /* DONT null terminate strings we output via proc */
+ len += (lenm + 1); /* for \n */
+
+ if (len <= size) {
+ if (lenp) {
+ memcpy(str, BASE_PROFILE(active)->name,
+ lenp);
+ str += lenp;
+ *str++ = '^';
+ }
+
+ memcpy(str, active->name, lena);
+ str += lena;
+ memcpy(str, mode_str, lenm);
+ str += lenm;
+ *str++ = '\n';
+ error = len;
+ } else {
+ error = -ERANGE;
+ }
+ } else {
+ const char *unconstrained_str = "unconstrained\n";
+ len = strlen(unconstrained_str);
+
+ /* DONT null terminate strings we output via proc */
+ if (len <= size) {
+ memcpy(str, unconstrained_str, len);
+ error = len;
+ } else {
+ error = -ERANGE;
+ }
+ }
+
+ return error;
+
+}
+
+int aa_setprocattr_changehat(char *hatinfo, size_t infosize)
+{
+ int error = -EINVAL;
+ char *token = NULL, *hat, *smagic, *tmp;
+ u32 magic;
+ int rc, len, consumed;
+ unsigned long flags;
+
+ AA_DEBUG("%s: %p %zd\n", __FUNCTION__, hatinfo, infosize);
+
+ /* strip leading white space */
+ while (infosize && isspace(*hatinfo)) {
+ hatinfo++;
+ infosize--;
+ }
+
+ if (infosize == 0)
+ goto out;
+
+ /*
+ * Copy string to a new buffer so we can play with it
+ * It may be zero terminated but we add a trailing 0
+ * for 100% safety
+ */
+ token = kmalloc(infosize + 1, GFP_KERNEL);
+
+ if (!token) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(token, hatinfo, infosize);
+ token[infosize] = 0;
+
+ /* error is INVAL until we have at least parsed something */
+ error = -EINVAL;
+
+ tmp = token;
+ while (*tmp && *tmp != '^') {
+ tmp++;
+ }
+
+ if (!*tmp || tmp == token) {
+ AA_WARN("%s: Invalid input '%s'\n", __FUNCTION__, token);
+ goto out;
+ }
+
+ /* split magic and hat into two strings */
+ *tmp = 0;
+ smagic = token;
+
+ /*
+ * Initially set consumed=strlen(magic), as if sscanf
+ * consumes all input via the %x it will not process the %n
+ * directive. Otherwise, if sscanf does not consume all the
+ * input it will process the %n and update consumed.
+ */
+ consumed = len = strlen(smagic);
+
+ rc = sscanf(smagic, "%x%n", &magic, &consumed);
+
+ if (rc != 1 || consumed != len) {
+ AA_WARN("%s: Invalid hex magic %s\n",
+ __FUNCTION__,
+ smagic);
+ goto out;
+ }
+
+ hat = tmp + 1;
+
+ if (!*hat)
+ hat = NULL;
+
+ if (!hat && !magic) {
+ AA_WARN("%s: Invalid input, NULL hat and NULL magic\n",
+ __FUNCTION__);
+ goto out;
+ }
+
+ AA_DEBUG("%s: Magic 0x%x Hat '%s'\n",
+ __FUNCTION__, magic, hat ? hat : NULL);
+
+ spin_lock_irqsave(&sd_lock, flags);
+ error = aa_change_hat(hat, magic);
+ spin_unlock_irqrestore(&sd_lock, flags);
+
+out:
+ if (token) {
+ memset(token, 0, infosize);
+ kfree(token);
+ }
+
+ return error;
+}
+
+int aa_setprocattr_setprofile(struct task_struct *p, char *profilename,
+ size_t profilesize)
+{
+ int error = -EINVAL;
+ struct aaprofile *profile = NULL;
+ struct subdomain *sd;
+ char *name = NULL;
+ unsigned long flags;
+
+ AA_DEBUG("%s: current %s(%d)\n",
+ __FUNCTION__, current->comm, current->pid);
+
+ /* strip leading white space */
+ while (profilesize && isspace(*profilename)) {
+ profilename++;
+ profilesize--;
+ }
+
+ if (profilesize == 0)
+ goto out;
+
+ /*
+ * Copy string to a new buffer so we guarantee it is zero
+ * terminated
+ */
+ name = kmalloc(profilesize + 1, GFP_KERNEL);
+
+ if (!name) {
+ error = -ENOMEM;
+ goto out;
+ }
+
+ strncpy(name, profilename, profilesize);
+ name[profilesize] = 0;
+
+ repeat:
+ if (strcmp(name, "unconstrained") != 0) {
+ profile = aa_profilelist_find(name);
+ if (!profile) {
+ AA_WARN("%s: Unable to switch task %s(%d) to profile"
+ "'%s'. No such profile.\n",
+ __FUNCTION__,
+ p->comm, p->pid,
+ name);
+
+ error = -EINVAL;
+ goto out;
+ }
+ }
+
+ spin_lock_irqsave(&sd_lock, flags);
+
+ sd = AA_SUBDOMAIN(p->security);
+
+ /* switch to unconstrained */
+ if (!profile) {
+ if (__aa_is_confined(sd)) {
+ AA_WARN("%s: Unconstraining task %s(%d) "
+ "profile %s active %s\n",
+ __FUNCTION__,
+ p->comm, p->pid,
+ BASE_PROFILE(sd->active)->name,
+ sd->active->name);
+
+ aa_switch_unconfined(sd);
+ } else {
+ AA_WARN("%s: task %s(%d) "
+ "is already unconstrained\n",
+ __FUNCTION__, p->comm, p->pid);
+ }
+ } else {
+ if (!sd) {
+ /* this task was created before module was
+ * loaded, allocate a subdomain
+ */
+ AA_WARN("%s: task %s(%d) has no subdomain\n",
+ __FUNCTION__, p->comm, p->pid);
+
+ /* unlock so we can safely GFP_KERNEL */
+ spin_unlock_irqrestore(&sd_lock, flags);
+
+ sd = alloc_subdomain(p);
+ if (!sd) {
+ AA_WARN("%s: Unable to allocate subdomain for "
+ "task %s(%d). Cannot confine task to "
+ "profile %s\n",
+ __FUNCTION__,
+ p->comm, p->pid,
+ name);
+
+ error = -ENOMEM;
+ put_aaprofile(profile);
+
+ goto out;
+ }
+
+ spin_lock_irqsave(&sd_lock, flags);
+ if (!AA_SUBDOMAIN(p->security)) {
+ p->security = sd;
+ } else { /* race */
+ free_subdomain(sd);
+ sd = AA_SUBDOMAIN(p->security);
+ }
+ }
+
+ /* ensure the profile hasn't been replaced */
+
+ if (unlikely(profile->isstale)) {
+ WARN_ON(profile == null_complain_profile);
+
+ /* drop refcnt obtained from earlier get_aaprofile */
+ put_aaprofile(profile);
+ profile = aa_profilelist_find(name);
+
+ if (!profile) {
+ /* Race, profile was removed. */
+ spin_unlock_irqrestore(&sd_lock, flags);
+ goto repeat;
+ }
+ }
+
+ /* we do not do a normal task replace since we are not
+ * replacing with the same profile.
+ * If existing process is in a hat, it will be moved
+ * into the new parent profile, even if this new
+ * profile has a identical named hat.
+ */
+
+ AA_WARN("%s: Switching task %s(%d) "
+ "profile %s active %s to new profile %s\n",
+ __FUNCTION__,
+ p->comm, p->pid,
+ sd->active ? BASE_PROFILE(sd->active)->name :
+ "unconstrained",
+ sd->active ? sd->active->name : "unconstrained",
+ name);
+
+ aa_switch(sd, profile);
+
+ put_aaprofile(profile); /* drop ref we obtained above
+ * from aa_profilelist_find
+ */
+
+ /* Reset magic in case we were in a subhat before
+ * This is the only case where we zero the magic after
+ * calling aa_switch
+ */
+ sd->hat_magic = 0;
+ }
+
+ spin_unlock_irqrestore(&sd_lock, flags);
+
+out:
+ kfree(name);
+
+ return error;
+}
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 8/11] security: AppArmor - Pathname matching submodule
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (6 preceding siblings ...)
2006-04-19 17:50 ` [RFC][PATCH 7/11] security: AppArmor - Misc (capabilities, data structures) Tony Jones
@ 2006-04-19 17:50 ` Tony Jones
2006-04-19 17:50 ` [RFC][PATCH 9/11] security: AppArmor - Audit changes Tony Jones
` (5 subsequent siblings)
13 siblings, 0 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:50 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
The file match.h specifies a sub module interface consisting of the following
functions:
aamatch_alloc
aamatch_free
Allocates/deallocates submodule specific data used by each
loaded profile (policy).
aamatch_features
Returns the list of features implemented by the submodule.
These are literal, tailglob ("/path/**" match all paths
below /path) and pattern (full shell based pathname expansion).
aamatch_serialize
Called by the module interface to serialize submodule specific
data from userspace.
aamatch_match
Called to perform matching on a generated pathname.
The submodule submitted here implements only "literal" and "tailglob".
The version included with SuSE Linux implements "pattern" but via a method
that is not acceptable for mainline inclusion. We plan on developing
a new submodule as soon as possible that will implement the missing
functionality of the SuSE release using the textsearch framework and
a new bounded textsearch algorithm acceptable for subsequent inclusion
into the mainline kernel.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
security/apparmor/match/Makefile | 5 +
security/apparmor/match/match.h | 132 ++++++++++++++++++++++++++++++++
security/apparmor/match/match_default.c | 57 +++++++++++++
3 files changed, 194 insertions(+)
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/match/Makefile
@@ -0,0 +1,5 @@
+# Makefile for AppArmor aamatch submodule
+#
+obj-$(CONFIG_SECURITY_APPARMOR) += aamatch_default.o
+
+aamatch_default-y := match_default.o
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/match/match.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2002-2005 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 submodule (match) prototypes
+ */
+
+#ifndef __MATCH_H
+#define __MATCH_H
+
+#include "../module_interface.h"
+#include "../apparmor.h"
+
+/* The following functions implement an interface used by the primary
+ * AppArmor module to perform name matching (n.b. "AppArmor" was previously
+ * called "SubDomain").
+
+ * aamatch_alloc
+ * aamatch_free
+ * aamatch_features
+ * aamatch_serialize
+ * aamatch_match
+ *
+ * The intent is for the primary module to export (via virtual fs entries)
+ * the features provided by the submodule (aamatch_features) so that the
+ * parser may only load policy that can be supported.
+ *
+ * The primary module will call aamatch_serialize to allow the submodule
+ * to consume submodule specific data from parser data stream and will call
+ * aamatch_match to determine if a pathname matches an aa_entry.
+ */
+
+typedef int (*aamatch_serializecb)
+ (struct aa_ext *, enum aa_code, void *, const char *);
+
+/**
+ * aamatch_alloc: allocate extradata (if necessary)
+ * @type: type of entry being allocated
+ * Return value: NULL indicates no data was allocated (ERR_PTR(x) on error)
+ */
+extern void* aamatch_alloc(enum entry_match_type type);
+
+/**
+ * aamatch_free: release data allocated by aamatch_alloc
+ * @entry_extradata: data previously allocated by aamatch_alloc
+ */
+extern void aamatch_free(void *entry_extradata);
+
+/**
+ * aamatch_features: return match types supported
+ * Return value: space seperated string (of types supported - use type=value
+ * to indicate variants of a type)
+ */
+extern const char* aamatch_features(void);
+
+/**
+ * aamatch_serialize: serialize extradata
+ * @entry_extradata: data previously allocated by aamatch_alloc
+ * @e: input stream
+ * @cb: callback fn (consume incoming data stream)
+ * Return value: 0 success, -ve error
+ */
+extern int aamatch_serialize(void *entry_extradata, struct aa_ext *e,
+ aamatch_serializecb cb);
+
+/**
+ * aamatch_match: determine if pathname matches entry
+ * @pathname: pathname to verify
+ * @entry_name: entry name
+ * @type: type of entry
+ * @entry_extradata: data previously allocated by aamatch_alloc
+ * Return value: 1 match, 0 othersise
+ */
+extern unsigned int aamatch_match(const char *pathname, const char *entry_name,
+ enum entry_match_type type,
+ void *entry_extradata);
+
+
+/**
+ * sd_getmatch_type - return string representation of entry_match_type
+ * @type: entry match type
+ */
+static inline const char *sd_getmatch_type(enum entry_match_type type)
+{
+ const char *names[] = {
+ "aa_entry_literal",
+ "aa_entry_tailglob",
+ "aa_entry_pattern",
+ "aa_entry_invalid"
+ };
+
+ if (type >= aa_entry_invalid) {
+ type = aa_entry_invalid;
+ }
+
+ return names[type];
+}
+
+/**
+ * aamatch_match_common - helper function to check if a pathname matches
+ * a literal/tailglob
+ * @path: path requested to search for
+ * @entry_name: name from aa_entry
+ * @type: type of entry
+ */
+static inline int aamatch_match_common(const char *path,
+ const char *entry_name,
+ enum entry_match_type type)
+{
+ int retval;
+
+ /* literal, no pattern matching characters */
+ if (type == aa_entry_literal) {
+ retval = (strcmp(entry_name, path) == 0);
+ /* trailing ** glob pattern */
+ } else if (type == aa_entry_tailglob) {
+ retval = (strncmp(entry_name, path,
+ strlen(entry_name) - 2) == 0);
+ } else {
+ AA_WARN("%s: Invalid entry_match_type %d\n",
+ __FUNCTION__, type);
+ retval = 0;
+ }
+
+ return retval;
+}
+
+#endif /* __MATCH_H */
--- /dev/null
+++ linux-2.6.17-rc1/security/apparmor/match/match_default.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2002-2005 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.
+ *
+ * http://forge.novell.com/modules/xfmod/project/?apparmor
+ *
+ * AppArmor default match submodule (literal and tailglob)
+ */
+
+#include <linux/module.h>
+#include "match.h"
+
+static const char *features="literal tailglob";
+
+void* aamatch_alloc(enum entry_match_type type)
+{
+ return NULL;
+}
+
+void aamatch_free(void *ptr)
+{
+}
+
+const char *aamatch_features(void)
+{
+ return features;
+}
+
+int aamatch_serialize(void *entry_extradata, struct aa_ext *e,
+ aamatch_serializecb cb)
+{
+ return 0;
+}
+
+unsigned int aamatch_match(const char *pathname, const char *entry_name,
+ enum entry_match_type type, void *entry_extradata)
+{
+ int ret;
+
+ ret = aamatch_match_common(pathname, entry_name, type);
+
+ return ret;
+}
+
+EXPORT_SYMBOL_GPL(aamatch_alloc);
+EXPORT_SYMBOL_GPL(aamatch_free);
+EXPORT_SYMBOL_GPL(aamatch_features);
+EXPORT_SYMBOL_GPL(aamatch_serialize);
+EXPORT_SYMBOL_GPL(aamatch_match);
+
+MODULE_DESCRIPTION("AppArmor match module (aamatch) [default]");
+MODULE_AUTHOR("Tony Jones <tonyj@suse.de>");
+MODULE_LICENSE("GPL");
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 9/11] security: AppArmor - Audit changes
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (7 preceding siblings ...)
2006-04-19 17:50 ` [RFC][PATCH 8/11] security: AppArmor - Pathname matching submodule Tony Jones
@ 2006-04-19 17:50 ` Tony Jones
2006-04-21 21:21 ` Amy Griffis
2006-04-19 17:50 ` [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path Tony Jones
` (4 subsequent siblings)
13 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:50 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
This patch adds AppArmor support to the audit subsystem.
It creates id 1500 (already included in the the upstream auditd package) for
AppArmor messages.
It also exports the audit_log_vformat function (analagous to having both
printk and vprintk exported).
Signed-off-by: Tony Jones <tonyj@suse.de>
---
include/linux/audit.h | 5 +++++
kernel/audit.c | 3 ++-
2 files changed, 7 insertions(+), 1 deletion(-)
--- linux-2.6.17-rc1.orig/include/linux/audit.h
+++ linux-2.6.17-rc1/include/linux/audit.h
@@ -95,6 +95,8 @@
#define AUDIT_LAST_KERN_ANOM_MSG 1799
#define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
+#define AUDIT_AA 1500 /* AppArmor audit */
+
#define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
/* Rule flags */
@@ -349,6 +351,9 @@
__attribute__((format(printf,4,5)));
extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
+extern void audit_log_vformat(struct audit_buffer *ab,
+ const char *fmt, va_list args)
+ __attribute__((format(printf,2,0)));
extern void audit_log_format(struct audit_buffer *ab,
const char *fmt, ...)
__attribute__((format(printf,2,3)));
--- linux-2.6.17-rc1.orig/kernel/audit.c
+++ linux-2.6.17-rc1/kernel/audit.c
@@ -797,7 +797,7 @@
* will be called a second time. Currently, we assume that a printk
* can't format message larger than 1024 bytes, so we don't either.
*/
-static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
+void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
va_list args)
{
int len, avail;
@@ -999,4 +999,5 @@
EXPORT_SYMBOL(audit_log_start);
EXPORT_SYMBOL(audit_log_end);
EXPORT_SYMBOL(audit_log_format);
+EXPORT_SYMBOL(audit_log_vformat);
EXPORT_SYMBOL(audit_log);
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (8 preceding siblings ...)
2006-04-19 17:50 ` [RFC][PATCH 9/11] security: AppArmor - Audit changes Tony Jones
@ 2006-04-19 17:50 ` Tony Jones
2006-04-19 22:12 ` Christoph Hellwig
2006-04-19 17:50 ` [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore Tony Jones
` (3 subsequent siblings)
13 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:50 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
This patch adds a new function d_path_flags which takes an additional flags
parameter. Adding a new function rather than ammending the existing d_path
was done to avoid impact on the current users.
It is not essential for inclusion with AppArmor (the apparmor_mediation.patch
can easily be revised to use plain d_path) but it enables cleaner code
["(delete)" handling] and closes a loophole with pathname generation for
chrooted tasks.
It currently adds two flags:
DPATH_SYSROOT:
d_path should generate a path from the system root rather than the
task's current root.
For AppArmor this enables generation of absolute pathnames in all
cases. Currently when a task is chrooted, file access is reported
relative to the chroot. Because it is currently not possible to
obtain the absolute path in an SMP safe way, without this patch
AppArmor will have to report chroot-relative pathnames.
DPATH_NODELETED:
d_path should not append "(deleted)" to unhashed entries. Sometimes
this information is not useful for the caller and the string can
exist as the suffix of a valid pathname.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
fs/dcache.c | 48 ++++++++++++++++++++++++++++++++----------------
include/linux/dcache.h | 7 +++++++
2 files changed, 39 insertions(+), 16 deletions(-)
--- linux-2.6.17-rc1.orig/fs/dcache.c
+++ linux-2.6.17-rc1/fs/dcache.c
@@ -1381,9 +1381,11 @@
* @rootmnt: vfsmnt to which the root dentry belongs
* @buffer: buffer to return value in
* @buflen: buffer length
+ * @flags: control flags
*
* Convert a dentry into an ASCII path name. If the entry has been deleted
- * the string " (deleted)" is appended. Note that this is ambiguous.
+ * and DPATH_NODELETED is not specified in flags then the string " (deleted)"
+ * is appended. Note that this is ambiguous.
*
* Returns the buffer or an error code if the path was too long.
*
@@ -1391,7 +1393,7 @@
*/
static char * __d_path( struct dentry *dentry, struct vfsmount *vfsmnt,
struct dentry *root, struct vfsmount *rootmnt,
- char *buffer, int buflen)
+ char *buffer, int buflen, unsigned int flags)
{
char * end = buffer+buflen;
char * retval;
@@ -1399,7 +1401,8 @@
*--end = '\0';
buflen--;
- if (!IS_ROOT(dentry) && d_unhashed(dentry)) {
+ if (!(flags & DPATH_NODELETED) &&
+ !IS_ROOT(dentry) && d_unhashed(dentry)) {
buflen -= 10;
end -= 10;
if (buflen < 0)
@@ -1416,7 +1419,8 @@
for (;;) {
struct dentry * parent;
- if (dentry == root && vfsmnt == rootmnt)
+ if (!(flags & DPATH_SYSROOT) &&
+ dentry == root && vfsmnt == rootmnt)
break;
if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) {
/* Global root? */
@@ -1458,25 +1462,36 @@
}
/* write full pathname into buffer and return start of pathname */
-char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
- char *buf, int buflen)
+char * d_path_flags(struct dentry *dentry, struct vfsmount *vfsmnt,
+ char *buf, int buflen, unsigned int flags)
{
char *res;
- struct vfsmount *rootmnt;
- struct dentry *root;
+ struct vfsmount *rootmnt = NULL;
+ struct dentry *root = NULL;
- read_lock(¤t->fs->lock);
- rootmnt = mntget(current->fs->rootmnt);
- root = dget(current->fs->root);
- read_unlock(¤t->fs->lock);
+ if (!(flags & DPATH_SYSROOT)){
+ read_lock(¤t->fs->lock);
+ rootmnt = mntget(current->fs->rootmnt);
+ root = dget(current->fs->root);
+ read_unlock(¤t->fs->lock);
+ }
spin_lock(&dcache_lock);
- res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen);
+ res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen, flags);
spin_unlock(&dcache_lock);
- dput(root);
- mntput(rootmnt);
+ if (!(flags & DPATH_SYSROOT)){
+ dput(root);
+ mntput(rootmnt);
+ }
return res;
}
+/* original d_path without support for flags */
+char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt,
+ char *buf, int buflen)
+{
+ return d_path_flags(dentry, vfsmnt, buf, buflen, 0);
+}
+
/*
* NOTE! The user-level library version returns a
* character pointer. The kernel system call just
@@ -1519,7 +1534,7 @@
unsigned long len;
char * cwd;
- cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE);
+ cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE, 0);
spin_unlock(&dcache_lock);
error = PTR_ERR(cwd);
@@ -1771,6 +1786,7 @@
EXPORT_SYMBOL(d_invalidate);
EXPORT_SYMBOL(d_lookup);
EXPORT_SYMBOL(d_move);
+EXPORT_SYMBOL(d_path_flags);
EXPORT_SYMBOL(d_path);
EXPORT_SYMBOL(d_prune_aliases);
EXPORT_SYMBOL(d_rehash);
--- linux-2.6.17-rc1.orig/include/linux/dcache.h
+++ linux-2.6.17-rc1/include/linux/dcache.h
@@ -164,6 +164,10 @@
#define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched */
+/* dpath flags */
+#define DPATH_SYSROOT 0x0001 /* continue past fsroot (chroot) */
+#define DPATH_NODELETED 0x0002 /* do not append " (deleted)" */
+
extern spinlock_t dcache_lock;
/**
@@ -281,6 +285,9 @@
extern int d_validate(struct dentry *, struct dentry *);
extern char * d_path(struct dentry *, struct vfsmount *, char *, int);
+
+extern char * d_path_flags(struct dentry *, struct vfsmount *, char *, int,
+ unsigned int);
/* Allocation counts.. */
^ permalink raw reply [flat|nested] 173+ messages in thread
* [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (9 preceding siblings ...)
2006-04-19 17:50 ` [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path Tony Jones
@ 2006-04-19 17:50 ` Tony Jones
2006-04-19 22:10 ` Christoph Hellwig
2006-04-20 12:39 ` Stephen Smalley
2006-04-19 18:14 ` [RFC][PATCH 0/11] security: AppArmor - Overview Arjan van de Ven
` (2 subsequent siblings)
13 siblings, 2 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-19 17:50 UTC (permalink / raw)
To: linux-kernel; +Cc: chrisw, Tony Jones, linux-security-module
This patch exports the namespace_sem semaphore.
The shared subtree patches which went into 2.6.15-rc1 replaced the old
namespace semaphore which used to be per namespace (and visible) with a
new single static semaphore.
The reason for this change is that currently visibility of vfsmount information
to the LSM hooks is fairly patchy. Either there is no passed parameter or
it can be NULL. For the case of the former, several LSM hooks that we
require to mediate have no vfsmount/nameidata passed. We previously (mis)used
the visibility of the old per namespace semaphore to walk the processes
namespace looking for vfsmounts with a root dentry matching the dentry we were
trying to mediate.
Clearly this is not viable long term strategy and changes working towards
passing a vfsmount to all relevant LSM hooks would seem necessary (and also
useful for other users of LSM). Alternative suggestions and ideas are welcomed.
Signed-off-by: Tony Jones <tonyj@suse.de>
---
fs/namespace.c | 3 ++-
include/linux/namespace.h | 2 ++
2 files changed, 4 insertions(+), 1 deletion(-)
--- linux-2.6.17-rc1.orig/fs/namespace.c
+++ linux-2.6.17-rc1/fs/namespace.c
@@ -46,7 +46,8 @@
static struct list_head *mount_hashtable __read_mostly;
static int hash_mask __read_mostly, hash_bits __read_mostly;
static kmem_cache_t *mnt_cache __read_mostly;
-static struct rw_semaphore namespace_sem;
+struct rw_semaphore namespace_sem;
+EXPORT_SYMBOL_GPL(namespace_sem);
/* /sys/fs */
decl_subsys(fs, NULL, NULL);
--- linux-2.6.17-rc1.orig/include/linux/namespace.h
+++ linux-2.6.17-rc1/include/linux/namespace.h
@@ -5,6 +5,8 @@
#include <linux/mount.h>
#include <linux/sched.h>
+extern struct rw_semaphore namespace_sem;
+
struct namespace {
atomic_t count;
struct vfsmount * root;
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild
2006-04-19 17:49 ` [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild Tony Jones
@ 2006-04-19 17:57 ` Arjan van de Ven
2006-04-19 18:10 ` Tony Jones
2006-04-19 18:35 ` Valdis.Kletnieks
2006-04-19 19:55 ` Adrian Bunk
2 siblings, 1 reply; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-19 17:57 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> This patch glues AppArmor into the security configuration and Makefile.
> It also creates the AppArmor configuration and Makefile.
please use a "proper" patch ordering; it's not possible to apply this
patch only and get a building kernel, breaking bisection
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 2/11] security: AppArmor - Core headers
2006-04-19 17:49 ` [RFC][PATCH 2/11] security: AppArmor - Core headers Tony Jones
@ 2006-04-19 18:01 ` Arjan van de Ven
2006-04-20 17:43 ` Tony Jones
0 siblings, 1 reply; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-19 18:01 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> This patch provides the various common headerfiles used by the AppArmor module.
>
> apparmor.h contains the core data structures.
> shared.h contains definitions that are common to the userspace policy loader.
> inline.h implements various inline utility functions
>
>
> Signed-off-by: Tony Jones <tonyj@suse.de>
>
> ---
> security/apparmor/apparmor.h | 325 +++++++++++++++++++++++++++++++++++++++++
> security/apparmor/inline.h | 333 +++++++++++++++++++++++++++++++++++++++++++
> security/apparmor/shared.h | 41 +++++
> 3 files changed, 699 insertions(+)
>
> --- /dev/null
> +++ linux-2.6.17-rc1/security/apparmor/apparmor.h
> @@ -0,0 +1,325 @@
> +/*
> + * Copyright (C) 1998-2005 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 internal prototypes
> + */
> +
> +#ifndef __SUBDOMAIN_H
> +#define __SUBDOMAIN_H
this is an odd include guard for a file called apparmor.h
> +#include "shared.h"
> +
> +/* Control parameters (0 or 1), settable thru module/boot flags or
> + * via /sys/kernel/security/apparmor/control */
> +extern int apparmor_complain;
> +extern int apparmor_debug;
> +extern int apparmor_audit;
> +extern int apparmor_logsyscall;
looks like these should be in a header too
> +
> +/* PIPEFS_MAGIC */
> +#include <linux/pipe_fs_i.h>
> +/* from net/socket.c */
> +#define SOCKFS_MAGIC 0x534F434B
> +/* from inotify.c */
> +#define INOTIFYFS_MAGIC 0xBAD1DEA
> +
> +#define VALID_FSTYPE(inode) ((inode)->i_sb->s_magic != PIPEFS_MAGIC && \
> + (inode)->i_sb->s_magic != SOCKFS_MAGIC && \
> + (inode)->i_sb->s_magic != INOTIFYFS_MAGIC)
ehhhh what is this about? Isn't this highly fragile???
> +
> +/*
> + * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
> + * which is not related to profile accesses.
> + */
> +
> +#define AA_DEBUG(fmt, args...) \
> + do { \
> + if (apparmor_debug) \
> + printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
> + } while (0)
> +#define AA_INFO(fmt, args...) printk(KERN_INFO "AppArmor: " fmt, ##args)
> +#define AA_WARN(fmt, args...) printk(KERN_WARNING "AppArmor: " fmt, ##args)
> +#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args)
> +
eh why? at least use prdebug and the like, but don't do your own
> +/* aa_audit - AppArmor auditing structure
> + * Structure is populated by access control code and passed to aa_audit which
> + * provides for a single point of logging.
why duplicate the audit infrastructure??
(and it's not possible to use LSM for auditing really; so it's not just
duplication, it's a bad idea)
> +/** aa_path_getname
> + * @data: data object previously initialized by aa_path_begin
> + *
> + * Return the next mountpoint which has the same root dentry as data->root.
> + * If no more mount points exist (or in case of error) NULL is returned
> + * (caller should call aa_path_end() and inspect return code to differentiate)
> + */
> +static inline char *aa_path_getname(struct aa_path_data *data)
> +{
> + char *name = NULL;
> + struct vfsmount *mnt;
> +
> + while (data->pos != data->head) {
> + mnt = list_entry(data->pos, struct vfsmount, mnt_list);
> +
> + /* advance to next -- so that it is done before we break */
> + data->pos = data->pos->next;
> + prefetch(data->pos->next);
> +
> + if (mnt->mnt_root == data->root) {
> + name = aa_get_name(data->dentry, mnt);
> + if (!name)
> + data->errno = -ENOMEM;
> + break;
> + }
> + }
> +
> + return name;
what's the locking rules and refcounting rules for this stuff ??
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 3/11] security: AppArmor - LSM interface
2006-04-19 17:49 ` [RFC][PATCH 3/11] security: AppArmor - LSM interface Tony Jones
@ 2006-04-19 18:05 ` Arjan van de Ven
0 siblings, 0 replies; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-19 18:05 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
> +#ifndef MODULE
> +static int __init aa_getopt_complain(char *str)
> +{
> + get_option(&str, &apparmor_complain);
> + return 1;
> +}
> +__setup("apparmor_complain=", aa_getopt_complain);
this is just bogus; in 2.6 at least. No need for ifdef; module
parameters can be set on the kernel commandline for the non-module case
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 17:49 ` [RFC][PATCH 4/11] security: AppArmor - Core access controls Tony Jones
@ 2006-04-19 18:10 ` Arjan van de Ven
2006-04-19 18:57 ` Crispin Cowan
2006-04-20 17:39 ` Tony Jones
2006-04-19 19:32 ` Jan Engelhardt
` (2 subsequent siblings)
3 siblings, 2 replies; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-19 18:10 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> +/**
> + * _aa_perm_dentry
> + * @active: profile to check against
> + * @dentry: requested dentry
> + * @mask: mask of requested operations
> + * @pname: pointer to hold matched pathname (if any)
> + *
> + * Helper function. Obtain pathname for specified dentry.
which namespace will this be in?
> Verify if profile
> + * authorizes mask operations on pathname (due to lack of vfsmnt it is sadly
> + * necessary to search mountpoints in namespace -- when nameidata is passed
> + * more fully, this code can go away). If more than one mountpoint matches
> + * but none satisfy the profile, only the first pathname (mountpoint) is
> + * returned for subsequent logging.
that sounds too bad ;)
If I manage to mount /etc/passwd as /tmp/passwd, you'll only find the
later and your entire security system seems to be down the drain.
> +/**
> + * aa_register - register a new program
> + * @filp: file of program being registered
> + *
> + * Try to register a new program during execve(). This should give the
> + * new program a valid subdomain.
> + */
> +int aa_register(struct file *filp)
> +{
> + char *filename;
> + struct subdomain *sd;
> + struct aaprofile *active;
> + struct aaprofile *newprofile = NULL, unconstrained_flag;
> + int error = -ENOMEM,
> + exec_mode = 0,
> + find_profile = 0,
> + find_profile_mandatory = 0,
> + complain = 0;
> +
> + AA_DEBUG("%s\n", __FUNCTION__);
> +
> + sd = AA_SUBDOMAIN(current->security);
> +
> + if (sd) {
> + complain = SUBDOMAIN_COMPLAIN(sd);
> + } else {
> + /* task has no subdomain. This can happen when a task is
> + * created when subdomain is not loaded. Allocate and
> + * attach a subdomain to the task
> + */
> + sd = alloc_subdomain(current);
> + if (!sd) {
> + AA_WARN("%s: Failed to allocate subdomain\n",
> + __FUNCTION__);
> + goto out;
> + }
> +
> + current->security = sd;
> + }
> +
> + filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt);
what if filp->f_dentry is NULL ?
like when the file got unlinked under you?
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild
2006-04-19 17:57 ` Arjan van de Ven
@ 2006-04-19 18:10 ` Tony Jones
0 siblings, 0 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-19 18:10 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, Apr 19, 2006 at 07:57:19PM +0200, Arjan van de Ven wrote:
> On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> > This patch glues AppArmor into the security configuration and Makefile.
> > It also creates the AppArmor configuration and Makefile.
>
>
> please use a "proper" patch ordering; it's not possible to apply this
> patch only and get a building kernel, breaking bisection
Fair enough, sorry. If we repost I will make sure I do this.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (10 preceding siblings ...)
2006-04-19 17:50 ` [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore Tony Jones
@ 2006-04-19 18:14 ` Arjan van de Ven
2006-04-19 22:32 ` Andi Kleen
2006-04-20 12:17 ` Stephen Smalley
2006-04-22 12:27 ` Pavel Machek
13 siblings, 1 reply; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-19 18:14 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> Attached patches to include the AppArmor application security module in
> the linux kernel.
can you at least comment on the discussion that happened on lkml the
past few days where basically most people understood and agreed that a
path-based approach is just not possible in linux anymore...
you must have a good defense against that argument, so I'm curious to
hear what it is
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 7/11] security: AppArmor - Misc (capabilities, data structures)
2006-04-19 17:50 ` [RFC][PATCH 7/11] security: AppArmor - Misc (capabilities, data structures) Tony Jones
@ 2006-04-19 18:16 ` Stephen Hemminger
0 siblings, 0 replies; 173+ messages in thread
From: Stephen Hemminger @ 2006-04-19 18:16 UTC (permalink / raw)
To: linux-kernel
On Wed, 19 Apr 2006 10:50:02 -0700
Tony Jones <tonyj@suse.de> wrote:
> This patch implements three distinct chunks.
> - list management, for profiles loaded into the system (profile_list) and for
> the set of confined tasks (subdomain_list)
> - the proc/pid/attr interface used by userspace for setprofile (forcing
> a task into a new profile) and changehat (switching a task into one of it's
> defined sub profiles). Access to change_hat is normally via code provided
> in libapparmor. See the overview posting for more information in change hat.
> - capability utility functions (for displaying capability names)
>
>
> Signed-off-by: Tony Jones <tonyj@suse.de>
>
> ---
> security/apparmor/capabilities.c | 54 ++++++
> security/apparmor/list.c | 268 +++++++++++++++++++++++++++++++
> security/apparmor/procattr.c | 327 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 649 insertions(+)
>
> --- /dev/null
> +++ linux-2.6.17-rc1/security/apparmor/capabilities.c
> @@ -0,0 +1,54 @@
> +/*
> + * Copyright (C) 2005 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 capability definitions
> + */
> +
> +#include "apparmor.h"
> +
> +static const char *cap_names[] = {
> + "chown",
> + "dac_override",
> + "dac_read_search",
> + "fowner",
> + "fsetid",
> + "kill",
> + "setgid",
> + "setuid",
> + "setpcap",
> + "linux_immutable",
> + "net_bind_service",
> + "net_broadcast",
> + "net_admin",
> + "net_raw",
> + "ipc_lock",
> + "ipc_owner",
> + "sys_module",
> + "sys_rawio",
> + "sys_chroot",
> + "sys_ptrace",
> + "sys_pacct",
> + "sys_admin",
> + "sys_boot",
> + "sys_nice",
> + "sys_resource",
> + "sys_time",
> + "sys_tty_config",
> + "mknod",
> + "lease"
> +};
> +
> +const char *capability_to_name(unsigned int cap)
> +{
> + const char *name;
> +
> + name = (cap < (sizeof(cap_names) / sizeof(char *))
> + ? cap_names[cap] : "invalid-capability");
> +
> + return name;
> +}
> --- /dev/null
> +++ linux-2.6.17-rc1/security/apparmor/list.c
> @@ -0,0 +1,268 @@
> +/*
> + * Copyright (C) 1998-2005 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 Profile List Management
> + */
> +
> +#include <linux/seq_file.h>
> +#include "apparmor.h"
> +#include "inline.h"
> +
> +/* list of all profiles and lock */
> +static LIST_HEAD(profile_list);
> +static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
> +
> +/* list of all subdomains and lock */
> +static LIST_HEAD(subdomain_list);
> +static rwlock_t subdomain_lock = RW_LOCK_UNLOCKED;
This would be a good candidate for RCU.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild
2006-04-19 17:49 ` [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild Tony Jones
2006-04-19 17:57 ` Arjan van de Ven
@ 2006-04-19 18:35 ` Valdis.Kletnieks
2006-04-19 19:55 ` Adrian Bunk
2 siblings, 0 replies; 173+ messages in thread
From: Valdis.Kletnieks @ 2006-04-19 18:35 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
[-- Attachment #1: Type: text/plain, Size: 369 bytes --]
On Wed, 19 Apr 2006 10:49:13 PDT, Tony Jones said:
> --- /dev/null
> +++ linux-2.6.17-rc1/security/apparmor/Kconfig
> @@ -0,0 +1,9 @@
> +config SECURITY_APPARMOR
> + tristate "AppArmor support"
> + depends on SECURITY!=n
> + help
This probably needs to be
depends on SECURITY!=n && SELINUX!=y
unless you want to get into some *really* messy composition issues....
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 18:10 ` Arjan van de Ven
@ 2006-04-19 18:57 ` Crispin Cowan
2006-04-19 23:05 ` Rik van Riel
2006-04-20 12:33 ` Stephen Smalley
2006-04-20 17:39 ` Tony Jones
1 sibling, 2 replies; 173+ messages in thread
From: Crispin Cowan @ 2006-04-19 18:57 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: Tony Jones, linux-kernel, chrisw, linux-security-module
Arjan van de Ven wrote:
> On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
>
>> Verify if profile
>> + * authorizes mask operations on pathname (due to lack of vfsmnt it is sadly
>> + * necessary to search mountpoints in namespace -- when nameidata is passed
>> + * more fully, this code can go away). If more than one mountpoint matches
>> + * but none satisfy the profile, only the first pathname (mountpoint) is
>> + * returned for subsequent logging.
>>
> that sounds too bad ;)
> If I manage to mount /etc/passwd as /tmp/passwd, you'll only find the
> later and your entire security system seems to be down the drain.
>
If you are a confined process, then you don't get to mount things, for
this reason, among others.
Crispin
--
Crispin Cowan, Ph.D. http://crispincowan.com/~crispin/
Director of Software Engineering, Novell http://novell.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 17:49 ` [RFC][PATCH 4/11] security: AppArmor - Core access controls Tony Jones
2006-04-19 18:10 ` Arjan van de Ven
@ 2006-04-19 19:32 ` Jan Engelhardt
2006-04-19 19:50 ` Stephen Smalley
2006-04-20 9:40 ` Al Viro
3 siblings, 0 replies; 173+ messages in thread
From: Jan Engelhardt @ 2006-04-19 19:32 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
>+/**
>+ * _aa_perm_dentry
[...]
>+ * Return %0 (success), +ve (mask of permissions not satisfied) or -ve (system
>+ * error, most likely -%ENOMEM).
>+ */
This was probably meant to read %-ENOMEM. (Applies anywhere else too!)
Jan Engelhardt
--
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 17:49 ` [RFC][PATCH 4/11] security: AppArmor - Core access controls Tony Jones
2006-04-19 18:10 ` Arjan van de Ven
2006-04-19 19:32 ` Jan Engelhardt
@ 2006-04-19 19:50 ` Stephen Smalley
2006-04-20 9:40 ` Al Viro
3 siblings, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-19 19:50 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> +/**
> + * aa_get_name - retrieve fully qualified path name
> + * @dentry: relative path element
> + * @mnt: where in tree
> + *
> + * Returns fully qualified path name on sucess, NULL on failure.
> + * aa_put_name must be used to free allocated buffer.
> + */
> +char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt)
> +{
> + char *page, *name = NULL;
> +
> + page = (char *)__get_free_page(GFP_KERNEL);
> + if (!page)
> + goto out;
> +
> + name = d_path_flags(dentry, mnt, page, PAGE_SIZE,
> + DPATH_SYSROOT|DPATH_NODELETED);
So on every inode hook call, you end up allocating a temporary page,
calling d_path (taking global dcache_lock), and you do this possibly
multiple times per object (due to iterating over vfsmounts) and you may
need to do it for multiple objects on a single hook call (e.g.
link/rename). Is that correct?
> +/**
> + * aa_perm_nameidata: interface to sd_perm accepting nameidata
> + * @active: profile to check against
> + * @nd: namespace data (for vfsmnt and dentry)
> + * @mask: access mode requested
> + */
> +int aa_perm_nameidata(struct aaprofile *active, struct nameidata *nd, int mask)
> +{
> + int error = 0;
> +
> + if (nd)
> + error = aa_perm(active, nd->dentry, nd->mnt, mask);
> +
> + return error;
> +}
So what about the !nd case. For when permission(9) is called with a
NULL nameidata. Unconditional success in that case seems a bit
worrisome.
I also vaguely recall a problem with trying to use the nameidata
(vfsmount, dentry) pair to d_path in SELinux for audit purposes back
when avc_audit was trying to audit paths before migrating to using the
audit system for that purpose. Interacted badly with rpc_pipefs upon
rpc_lookup_parent, IIRC. Might want to check whether you handle it
correctly.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild
2006-04-19 17:49 ` [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild Tony Jones
2006-04-19 17:57 ` Arjan van de Ven
2006-04-19 18:35 ` Valdis.Kletnieks
@ 2006-04-19 19:55 ` Adrian Bunk
2006-04-19 20:52 ` Tony Jones
2 siblings, 1 reply; 173+ messages in thread
From: Adrian Bunk @ 2006-04-19 19:55 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, Apr 19, 2006 at 10:49:13AM -0700, Tony Jones wrote:
>...
> --- /dev/null
> +++ linux-2.6.17-rc1/security/apparmor/Kconfig
> @@ -0,0 +1,9 @@
> +config SECURITY_APPARMOR
> + tristate "AppArmor support"
> + depends on SECURITY!=n
>...
Are you _really_ sure SECURITY=m, SECURITY_APPARMOR=y is a valid
configuration?
cu
Adrian
--
"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild
2006-04-19 19:55 ` Adrian Bunk
@ 2006-04-19 20:52 ` Tony Jones
0 siblings, 0 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-19 20:52 UTC (permalink / raw)
To: Adrian Bunk; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, Apr 19, 2006 at 09:55:02PM +0200, Adrian Bunk wrote:
> On Wed, Apr 19, 2006 at 10:49:13AM -0700, Tony Jones wrote:
> >...
> > --- /dev/null
> > +++ linux-2.6.17-rc1/security/apparmor/Kconfig
> > @@ -0,0 +1,9 @@
> > +config SECURITY_APPARMOR
> > + tristate "AppArmor support"
> > + depends on SECURITY!=n
> >...
>
> Are you _really_ sure SECURITY=m, SECURITY_APPARMOR=y is a valid
> configuration?
Thanks Adrian. Others made the exact same point. My bad. Fixed already.
Thanks
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-19 17:50 ` [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore Tony Jones
@ 2006-04-19 22:10 ` Christoph Hellwig
2006-04-20 12:39 ` Stephen Smalley
1 sibling, 0 replies; 173+ messages in thread
From: Christoph Hellwig @ 2006-04-19 22:10 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, Apr 19, 2006 at 10:50:34AM -0700, Tony Jones wrote:
> This patch exports the namespace_sem semaphore.
>
> The shared subtree patches which went into 2.6.15-rc1 replaced the old
> namespace semaphore which used to be per namespace (and visible) with a
> new single static semaphore.
>
> The reason for this change is that currently visibility of vfsmount information
> to the LSM hooks is fairly patchy. Either there is no passed parameter or
> it can be NULL. For the case of the former, several LSM hooks that we
> require to mediate have no vfsmount/nameidata passed. We previously (mis)used
> the visibility of the old per namespace semaphore to walk the processes
> namespace looking for vfsmounts with a root dentry matching the dentry we were
> trying to mediate.
>
> Clearly this is not viable long term strategy and changes working towards
> passing a vfsmount to all relevant LSM hooks would seem necessary (and also
> useful for other users of LSM). Alternative suggestions and ideas are welcomed.
Just don't do it. No module has any business looking in there, and no
non-modular code outside a few files in fs/ either.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path
2006-04-19 17:50 ` [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path Tony Jones
@ 2006-04-19 22:12 ` Christoph Hellwig
2006-04-20 5:36 ` Tony Jones
0 siblings, 1 reply; 173+ messages in thread
From: Christoph Hellwig @ 2006-04-19 22:12 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, Apr 19, 2006 at 10:50:26AM -0700, Tony Jones wrote:
> This patch adds a new function d_path_flags which takes an additional flags
> parameter. Adding a new function rather than ammending the existing d_path
> was done to avoid impact on the current users.
>
> It is not essential for inclusion with AppArmor (the apparmor_mediation.patch
> can easily be revised to use plain d_path) but it enables cleaner code
> ["(delete)" handling] and closes a loophole with pathname generation for
> chrooted tasks.
>
> It currently adds two flags:
>
> DPATH_SYSROOT:
> d_path should generate a path from the system root rather than the
> task's current root.
>
> For AppArmor this enables generation of absolute pathnames in all
> cases. Currently when a task is chrooted, file access is reported
> relative to the chroot. Because it is currently not possible to
> obtain the absolute path in an SMP safe way, without this patch
> AppArmor will have to report chroot-relative pathnames.
This is utter bullshit. There is no such thing as a system root,
and should not rely on pathes making any sense for anything but the
process using at at this point of time. This stuff will not get in either
in d_path or whatever duplicate of it you'd try to submit.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 18:14 ` [RFC][PATCH 0/11] security: AppArmor - Overview Arjan van de Ven
@ 2006-04-19 22:32 ` Andi Kleen
2006-04-19 23:00 ` grundig
` (4 more replies)
0 siblings, 5 replies; 173+ messages in thread
From: Andi Kleen @ 2006-04-19 22:32 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: linux-kernel, chrisw, linux-security-module
Arjan van de Ven <arjan@infradead.org> writes:
>
> you must have a good defense against that argument, so I'm curious to
> hear what it is
[I'm not from the apparmor people but my understanding is]
Usually they claimed name spaces as the reason it couldn't work.
In practice AFAIK basically nobody uses name spaces for
anything. AppArmor just forbids mounts/CLONE_NEWNS for the confined
applications and there is no way a new name space can be created so
the problem doesn't exist.
I suppose if name space based user space takes over the world
there is a problem but I have yet to see any signs of plan9 like userland
taking over the world (e.g. they're certainly not used for anything in
the distributions I'm familiar with).
Some people claim it will be used in the future in a particular application
that most people I know don't want to have anything to do with,
but right now that application uses an own file system that is also unlikely
to work with selinux or anything so it won't change anything for that.
I'm not aware of any other proposed application.
Also name spaces can be still used of course, just not with
apparmor limited applications.
So it's an interesting theoretical discussion, but in practice
it's a non issue.
Anyways, I guess the bigger issue is with hard links anyways
(Chris gave a long list of other ways to get aliases in path names
earlier). Discussing those might be much more fruitful.
That said I'm personally not too fond of path named filtering
either (it always seemed ugly to me), but I haven't seen anybody
proposing anything better so far that wasn't insanely complex
and basically impossible to administer.
-Andi
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 22:32 ` Andi Kleen
@ 2006-04-19 23:00 ` grundig
2006-04-19 23:38 ` Andi Kleen
2006-04-20 8:42 ` Arjan van de Ven
` (3 subsequent siblings)
4 siblings, 1 reply; 173+ messages in thread
From: grundig @ 2006-04-19 23:00 UTC (permalink / raw)
To: Andi Kleen; +Cc: arjan, linux-kernel, chrisw, linux-security-module
El 20 Apr 2006 00:32:43 +0200,
Andi Kleen <ak@suse.de> escribió:
> Some people claim it will be used in the future in a particular application
> that most people I know don't want to have anything to do with,
> but right now that application uses an own file system that is also unlikely
> to work with selinux or anything so it won't change anything for that.
>
> I'm not aware of any other proposed application.
However such application may exist in the future (which is why the feature
was implemented, i guess). If AppArmor becomes widespread in the future
(well suse has it anyway so it's already quite widespread) it won't be easy
to create succesful apps which play with namespaces, not to speak that it
won't be possible to "securize" such apps. From my user POV it seems
really weird that a feature forbids you from using another unrelated feature.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 18:57 ` Crispin Cowan
@ 2006-04-19 23:05 ` Rik van Riel
2006-04-19 23:18 ` Seth Arnold
2006-04-20 12:33 ` Stephen Smalley
1 sibling, 1 reply; 173+ messages in thread
From: Rik van Riel @ 2006-04-19 23:05 UTC (permalink / raw)
To: Crispin Cowan
Cc: Arjan van de Ven, Tony Jones, linux-kernel, chrisw,
linux-security-module
On Wed, 19 Apr 2006, Crispin Cowan wrote:
> Arjan van de Ven wrote:
> > that sounds too bad ;)
> > If I manage to mount /etc/passwd as /tmp/passwd, you'll only find the
> > later and your entire security system seems to be down the drain.
> If you are a confined process, then you don't get to mount things, for
> this reason, among others.
Are confined processes always restricted from starting
non-confined processes?
--
All Rights Reversed
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 23:05 ` Rik van Riel
@ 2006-04-19 23:18 ` Seth Arnold
2006-04-19 23:21 ` Rik van Riel
0 siblings, 1 reply; 173+ messages in thread
From: Seth Arnold @ 2006-04-19 23:18 UTC (permalink / raw)
To: Rik van Riel
Cc: Crispin Cowan, Arjan van de Ven, Tony Jones, linux-kernel, chrisw,
linux-security-module
[-- Attachment #1: Type: text/plain, Size: 276 bytes --]
On Wed, Apr 19, 2006 at 07:05:08PM -0400, Rik van Riel wrote:
> Are confined processes always restricted from starting
> non-confined processes?
It is specified in policy via an unconstrained execution flag: 'ux'. Any
unconfined children can of course do whatever they wish.
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 23:18 ` Seth Arnold
@ 2006-04-19 23:21 ` Rik van Riel
2006-04-19 23:50 ` Crispin Cowan
0 siblings, 1 reply; 173+ messages in thread
From: Rik van Riel @ 2006-04-19 23:21 UTC (permalink / raw)
To: Seth Arnold
Cc: Crispin Cowan, Arjan van de Ven, Tony Jones, linux-kernel, chrisw,
linux-security-module
On Wed, 19 Apr 2006, Seth Arnold wrote:
> On Wed, Apr 19, 2006 at 07:05:08PM -0400, Rik van Riel wrote:
> > Are confined processes always restricted from starting
> > non-confined processes?
>
> It is specified in policy via an unconstrained execution flag: 'ux'. Any
> unconfined children can of course do whatever they wish.
And the default is for the children to inherit the security
policy from the parent process, like in SELinux ?
How do apparmor and selinux differ in how they contain bad
things?
--
All Rights Reversed
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 23:00 ` grundig
@ 2006-04-19 23:38 ` Andi Kleen
2006-04-20 1:32 ` Crispin Cowan
0 siblings, 1 reply; 173+ messages in thread
From: Andi Kleen @ 2006-04-19 23:38 UTC (permalink / raw)
To: grundig; +Cc: arjan, linux-kernel, chrisw, linux-security-module
On Thursday 20 April 2006 01:00, grundig wrote:
> From my user POV it seems
> really weird that a feature forbids you from using another unrelated feature
e.g. using a firewall usually prevents some applications
from working. Or using hugepages is not compatible with a lot of other VM
features. Or some locking doesn't work over NFS.
There are lots of things like this in the kernel like in any
complex system.
-Andi
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 23:21 ` Rik van Riel
@ 2006-04-19 23:50 ` Crispin Cowan
0 siblings, 0 replies; 173+ messages in thread
From: Crispin Cowan @ 2006-04-19 23:50 UTC (permalink / raw)
To: Rik van Riel
Cc: Seth Arnold, Arjan van de Ven, Tony Jones, linux-kernel, chrisw,
linux-security-module
Rik van Riel wrote:
> On Wed, 19 Apr 2006, Seth Arnold wrote:
>
>> On Wed, Apr 19, 2006 at 07:05:08PM -0400, Rik van Riel wrote:
>>
>>> Are confined processes always restricted from starting
>>> non-confined processes?
>>>
>> It is specified in policy via an unconstrained execution flag: 'ux'. Any
>> unconfined children can of course do whatever they wish.
>>
> And the default is for the children to inherit the security
> policy from the parent process, like in SELinux ?
>
> How do apparmor and selinux differ in how they contain bad
> things?
>
To be able to execute any child, the confined process must have explicit
permission to execute it:
* "/bin/foo px" says that the child will execute with its own
policy. The policy must exist, or access is denied. This is useful
if, say, xinetd wants to exec Sendmail.
* "/bin/foo ix" says that the child will execute with its parent's
policy, "inherit". This is useful if, say, a shell script wants to
exec cp.
* "/bin/foo ux" says that the child will exec with no confinement at
all. This should be used carefully, say, if sshd wants to exec
bash to allow an administrator to have an unconfined shell.
You can also say something like "/bin/** ix" which would let you run
anything in /bin, but all subject to the parent's policy. You could say
"/bin/** px" but that would mostly cause exec() failures except to the
extent that policies exist. You could say "/bin/** ux" but that would
not be wise :)
Crispin
--
Crispin Cowan, Ph.D. http://crispincowan.com/~crispin/
Director of Software Engineering, Novell http://novell.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 23:38 ` Andi Kleen
@ 2006-04-20 1:32 ` Crispin Cowan
2006-04-20 13:00 ` grundig
0 siblings, 1 reply; 173+ messages in thread
From: Crispin Cowan @ 2006-04-20 1:32 UTC (permalink / raw)
To: Andi Kleen; +Cc: grundig, arjan, linux-kernel, chrisw, linux-security-module
Andi Kleen wrote:
> On Thursday 20 April 2006 01:00, grundig wrote:
>
>> From my user POV it seems
>> really weird that a feature forbids you from using another unrelated feature
>>
> e.g. using a firewall usually prevents some applications
> from working. Or using hugepages is not compatible with a lot of other VM
> features. Or some locking doesn't work over NFS.
>
Exactly. The basic function of an access control system is to block
access, selectively. So it is quite natural for AppArmor, and SELinux,
to block access to various kernel features at various times. Because
AppArmor is fundamentally name-based access control, changes to the name
space affect AppArmor, and thus access to changing the name space must
be managed.
Our controls on changing the name space have rather poor granularity at
the moment. We hope to improve that over time, and especially if LSM
evolves to permit it. This is ok, because as Andi pointed out, there are
currently few applications using name spaces, so we have time to improve
the granularity.
Crispin
--
Crispin Cowan, Ph.D. http://crispincowan.com/~crispin/
Director of Software Engineering, Novell http://novell.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path
2006-04-19 22:12 ` Christoph Hellwig
@ 2006-04-20 5:36 ` Tony Jones
2006-04-20 8:26 ` Arjan van de Ven
2006-04-24 13:05 ` Alan Cox
0 siblings, 2 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-20 5:36 UTC (permalink / raw)
To: Christoph Hellwig, linux-kernel, chrisw, linux-security-module
On Wed, Apr 19, 2006 at 11:12:48PM +0100, Christoph Hellwig wrote:
> On Wed, Apr 19, 2006 at 10:50:26AM -0700, Tony Jones wrote:
> > This patch adds a new function d_path_flags which takes an additional flags
> > parameter. Adding a new function rather than ammending the existing d_path
> > was done to avoid impact on the current users.
> >
> > It is not essential for inclusion with AppArmor (the apparmor_mediation.patch
> > can easily be revised to use plain d_path) but it enables cleaner code
> > ["(delete)" handling] and closes a loophole with pathname generation for
> > chrooted tasks.
> >
> > It currently adds two flags:
> >
> > DPATH_SYSROOT:
> > d_path should generate a path from the system root rather than the
> > task's current root.
> >
> > For AppArmor this enables generation of absolute pathnames in all
> > cases. Currently when a task is chrooted, file access is reported
> > relative to the chroot. Because it is currently not possible to
> > obtain the absolute path in an SMP safe way, without this patch
> > AppArmor will have to report chroot-relative pathnames.
>
> This is utter bullshit. There is no such thing as a system root,
> and should not rely on pathes making any sense for anything but the
> process using at at this point of time. This stuff will not get in either
> in d_path or whatever duplicate of it you'd try to submit.
You are correct on calling BS in that I was wrong to refer to it as the
"system root". When a task chroots relative to it's current namespace, we
are interested in the path back to the root of that namespace, rather than
to the chroot. I believe the patch as stands achieves this, albeit with
some changing of comments.
thanks!
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path
2006-04-20 5:36 ` Tony Jones
@ 2006-04-20 8:26 ` Arjan van de Ven
2006-04-20 16:43 ` Tony Jones
2006-04-24 13:05 ` Alan Cox
1 sibling, 1 reply; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-20 8:26 UTC (permalink / raw)
To: Tony Jones; +Cc: Christoph Hellwig, linux-kernel, chrisw, linux-security-module
> You are correct on calling BS in that I was wrong to refer to it as the
> "system root". When a task chroots relative to it's current namespace, we
> are interested in the path back to the root of that namespace, rather than
> to the chroot. I believe the patch as stands achieves this, albeit with
> some changing of comments.
it actually doesn't; you assume there is such a path which is not a
given. For example if your mount got lazy umounted (like hal probably
does) then it's a floating mount not one tied to any tree going to the
root of any namespace.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 22:32 ` Andi Kleen
2006-04-19 23:00 ` grundig
@ 2006-04-20 8:42 ` Arjan van de Ven
2006-04-20 19:26 ` Crispin Cowan
2006-04-20 19:27 ` Chris Wright
2006-04-20 11:29 ` Serge E. Hallyn
` (2 subsequent siblings)
4 siblings, 2 replies; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-20 8:42 UTC (permalink / raw)
To: Andi Kleen; +Cc: linux-kernel, chrisw, linux-security-module
On Thu, 2006-04-20 at 00:32 +0200, Andi Kleen wrote:
> Arjan van de Ven <arjan@infradead.org> writes:
> >
> > you must have a good defense against that argument, so I'm curious to
> > hear what it is
>
> [I'm not from the apparmor people but my understanding is]
>
> Usually they claimed name spaces as the reason it couldn't work.
I actually posted a list of 10 things that I made up in 3 minutes; just
going over those 10 would be a good start already since they're the most
obvious ones..
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 17:49 ` [RFC][PATCH 4/11] security: AppArmor - Core access controls Tony Jones
` (2 preceding siblings ...)
2006-04-19 19:50 ` Stephen Smalley
@ 2006-04-20 9:40 ` Al Viro
2006-04-20 11:40 ` Serge E. Hallyn
3 siblings, 1 reply; 173+ messages in thread
From: Al Viro @ 2006-04-20 9:40 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
> +static int _aa_perm_dentry(struct aaprofile *active, struct dentry *dentry,
> + int mask, const char **pname)
> +{
> + char *name = NULL, *failed_name = NULL;
> + struct aa_path_data data;
> + int error = 0, failed_error = 0, path_error,
> + complain = PROFILE_COMPLAIN(active);
> +
> + /* search all paths to dentry */
> +
> + aa_path_begin(dentry, &data);
> + do {
> + name = aa_path_getname(&data);
> + if (name) {
> + /* error here is 0 (success) or +ve (mask of perms) */
> + error = aa_file_perm(active, name, mask);
> +
> + /* access via any path is enough */
> + if (complain || error == 0)
> + break; /* Caller must free name */
> +
> + /* Already have an path that failed? */
> + if (failed_name) {
> + aa_put_name(name);
> + } else {
> + failed_name = name;
> + failed_error = error;
> + }
> + }
> + } while (name);
Is that a joke? Are you really proposing to do _that_ on anything resembling
a hot path?
BTW, the problems here really have nothing to do with namespaces or
lazy umount, seeing that it's whitelisting. Moderate amount of bindings
will kill you here. So much that I suspect that one-time overhead of
creating a namespace and umounting / remounting noexec / etc. on
execve() will be cheaper than all this crap.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 22:32 ` Andi Kleen
2006-04-19 23:00 ` grundig
2006-04-20 8:42 ` Arjan van de Ven
@ 2006-04-20 11:29 ` Serge E. Hallyn
2006-04-20 13:24 ` Christoph Hellwig
2006-04-20 22:32 ` Linda A. Walsh
4 siblings, 0 replies; 173+ messages in thread
From: Serge E. Hallyn @ 2006-04-20 11:29 UTC (permalink / raw)
To: Andi Kleen; +Cc: Arjan van de Ven, linux-kernel, chrisw, linux-security-module
Quoting Andi Kleen (ak@suse.de):
> Arjan van de Ven <arjan@infradead.org> writes:
> >
> > you must have a good defense against that argument, so I'm curious to
> > hear what it is
>
> [I'm not from the apparmor people but my understanding is]
>
> Usually they claimed name spaces as the reason it couldn't work.
>
> In practice AFAIK basically nobody uses name spaces for
> anything. AppArmor just forbids mounts/CLONE_NEWNS for the confined
Well, I use them all over the place to keep accounts on separate /tmp's,
etc. It may not be the norm yet, but the general availability of
pam_mount etc, and the implementation of shared subtrees may well change
that.
But then if that happens, as Al points out, AA might be able to
embrace rather than fight it.
-serge
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-20 9:40 ` Al Viro
@ 2006-04-20 11:40 ` Serge E. Hallyn
2006-04-20 21:39 ` Tony Jones
0 siblings, 1 reply; 173+ messages in thread
From: Serge E. Hallyn @ 2006-04-20 11:40 UTC (permalink / raw)
To: Al Viro; +Cc: Tony Jones, linux-kernel, chrisw, linux-security-module
Quoting Al Viro (viro@ftp.linux.org.uk):
>
> > +static int _aa_perm_dentry(struct aaprofile *active, struct dentry *dentry,
> > + int mask, const char **pname)
> > +{
> > + char *name = NULL, *failed_name = NULL;
> > + struct aa_path_data data;
> > + int error = 0, failed_error = 0, path_error,
> > + complain = PROFILE_COMPLAIN(active);
> > +
> > + /* search all paths to dentry */
> > +
> > + aa_path_begin(dentry, &data);
> > + do {
> > + name = aa_path_getname(&data);
> > + if (name) {
> > + /* error here is 0 (success) or +ve (mask of perms) */
> > + error = aa_file_perm(active, name, mask);
> > +
> > + /* access via any path is enough */
> > + if (complain || error == 0)
> > + break; /* Caller must free name */
> > +
> > + /* Already have an path that failed? */
> > + if (failed_name) {
> > + aa_put_name(name);
> > + } else {
> > + failed_name = name;
> > + failed_error = error;
> > + }
> > + }
> > + } while (name);
>
> Is that a joke? Are you really proposing to do _that_ on anything resembling
> a hot path?
>
> BTW, the problems here really have nothing to do with namespaces or
> lazy umount, seeing that it's whitelisting. Moderate amount of bindings
> will kill you here. So much that I suspect that one-time overhead of
> creating a namespace and umounting / remounting noexec / etc. on
> execve() will be cheaper than all this crap.
I guess this would require per-vfsmount flags (i.e. mount --bind -o ro)
to be implemented, but IIUC the suggestion is
given a policy
/bin/stty {
/bin/stty r
}
during execve AA would unshare(CLONE_NEWNS), remount / readonly and
noexec, and mount /bin/stty into place with exec privs. I guess
getting /bin/stty into place shouldn't be much of a challenge (i.e.
just do the operations in the order
mkdir /.tmp123
mount --bind -o ro,noexec / /.tmp123
mount --bind /bin/stty /.tmp123/bin/stty
mount --bind /.tmp123 /
)
but implementing the 'ux' exec permission which apparmor currently has
(i.e. giving the ability for stty to then execute /bin/login without
restrictions) could be more challenging.
This also might beg for sys_unshare() (and corresponding code in clone)
to have it's own security_vfs_unshare() hook, rather than being globbed
in with CAP_SYS_ADMIN.
-serge
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 12:46 ` Serge E. Hallyn
@ 2006-04-20 12:05 ` Stephen Smalley
2006-04-20 13:21 ` Serge E. Hallyn
0 siblings, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-20 12:05 UTC (permalink / raw)
To: Serge E. Hallyn; +Cc: linux-security-module, chrisw, linux-kernel, Tony Jones
On Thu, 2006-04-20 at 07:46 -0500, Serge E. Hallyn wrote:
> Quoting Stephen Smalley (sds@tycho.nsa.gov):
> > On Wed, 2006-04-19 at 10:50 -0700, Tony Jones wrote:
> > > This patch exports the namespace_sem semaphore.
> > >
> > > The shared subtree patches which went into 2.6.15-rc1 replaced the old
> > > namespace semaphore which used to be per namespace (and visible) with a
> > > new single static semaphore.
> > >
> > > The reason for this change is that currently visibility of vfsmount information
> > > to the LSM hooks is fairly patchy. Either there is no passed parameter or
> > > it can be NULL. For the case of the former, several LSM hooks that we
> > > require to mediate have no vfsmount/nameidata passed. We previously (mis)used
> > > the visibility of the old per namespace semaphore to walk the processes
> > > namespace looking for vfsmounts with a root dentry matching the dentry we were
> > > trying to mediate.
> > >
> > > Clearly this is not viable long term strategy and changes working towards
> > > passing a vfsmount to all relevant LSM hooks would seem necessary (and also
> > > useful for other users of LSM). Alternative suggestions and ideas are welcomed.
> >
> > The alternative I would recommend is to not use LSM. It isn't suitable
> > for your path-based approach. If your path-based approach is deemed
> > legitimate, then introduce new hooks at the proper point in processing
> > where the information you need is available.
>
> Whoa, so now LSM is not for access control?
That isn't what I said, although I see that my phrasing wasn't clear. I
said it wasn't suitable for a path-based approach. That is fairly clear
from the hook placements and interfaces, and from the contortions that
AppArmor has to go through in order to obtain the paths, and the number
of times it ends up calling d_path on a single syscall. Now "new hooks"
_could_ be new LSM hooks, I suppose, but my point was that it is a
mistake to try to use the existing LSM VFS hooks for this purpose - they
are in the wrong place for it, and no amount of munging will fix that.
Make sense?
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (11 preceding siblings ...)
2006-04-19 18:14 ` [RFC][PATCH 0/11] security: AppArmor - Overview Arjan van de Ven
@ 2006-04-20 12:17 ` Stephen Smalley
2006-04-20 15:38 ` Joshua Brindle
2006-04-20 19:57 ` Crispin Cowan
2006-04-22 12:27 ` Pavel Machek
13 siblings, 2 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-20 12:17 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-security-module, chrisw, linux-kernel
On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> AppArmor is an LSM security enhancement for the Linux kernel. The
> primary goal of AppArmor is to make it easy for a system administrator
> to control application behavior, enforcing that the application has
> access to only the files and POSIX.1e draft capabilities it requires to
> do its job. AppArmor deliberately uses this simple access control model
> to make it as easy as possible for the administrator to manage the
> policy, because the worst security of all is that which is never
> deployed because it was too hard.
The worst security is that which doesn't do what it claims to do, giving
a false sense of security. Which is precisely the problem with
path-based access control; it makes the user think that he is protecting
a given object, when in fact the object may be accessible by another
means.
> AppArmor chooses which security policy to enforce for a process at
> exec() time by the executable image's pathname, in conjunction with any
> policy enforced for the currently running executable.
Multiple instances of the same program can't be distinguished?
> AppArmor mediates access to the file system using absolute path names
> with shell-syntax wildcards, so that "/srv/htdocs/** r" grants read
> access to all files in /srv/htdocs.
So you have an unbounded number of policies that can govern access to
any given file object and the enforcement of the system policy is
entirely dependent on the file tree structure and any process that can
manipulate that structure. Further, what about runtime files generated
in shared directories like /tmp, /var/run, ... And let's please
separate user interface from kernel mechanism. If you want to specify
pathnames for fixed resources in a user-level config file, that is fine,
but pathnames have historically been rejected as a suitable basis for
the kernel for a reason, not just in the security space. Why should
this change? Isn't this a fundamental design change to Linux?
> AppArmor mediates access to POSIX.1e
> Capabilities in that the process must both have e.g. "capability
> net_bind_service" and intrinsically have that capability (usually by
> being root) to be able to bind to privileged network ports. Thus a
> confined process can not subvert AppArmor except as permitted by policy,
Not sure what is meant by "subvert AppArmor" here. Bypass is certainly
possible.
> AppArmor is *not* intended to protect every aspect of the system from
> every other aspect of the system: the intended usage is that only a
> small fraction of all programs on a Linux system will have AppArmor
> profiles. Rather, AppArmor is intended to protect the system against a
> particular threat.
So the attacker knows precisely how to bypass it. The attacker (beyond
the script kiddies) isn't going to attack you at the point of strength;
he will attack you where you are known to be weak.
> For instance, to secure a machine against network attack, all programs
> that face the network should be profiled. If all open network ports lead
> to AppArmor profiles, then there is no way for the network attacker to
> attack the machine, except as controlled by AppArmor policy. As a
> convenience, AppArmor includes a netstat wrapper that reports all
> programs with open network ports and their AppArmor profile status.
Except that your internal unconfined programs/processes may nonetheless
be subverted via the confined program, because:
a) you aren't controlling all objects and operations, and
b) you aren't controlling those internal programs/processes at all, so
they are at risk of taking untrustworthy inputs from the "confined"
ones, and
c) there is a high likelihood of interactions between those
processes/programs in any real system, particularly in shared
directories where paths aren't very useful as a distinguisher.
> 2. AppArmor needs to re-construct the full path name of files to
> perform initial validation. Some of the LSM hooks that we mediate
> do not have vfsmount/nameidata passed. Our temporary workaround is
> to export the namespace_sem semaphore so we can safely walk the
> process's namespace to find a vfsmount with a root dentry matching
> the dentry we are trying to mediate. We believe a cleaner solution
> (such as passing a vfsmount or nameidata to all LSM hooks throughout
> the VFS layer) would be useful for audit, other LSMs, and
> potentially FUSE. As it is a fair amount of work to pass vfsmount or
> nameidata structures throughout the VFS, alternative suggestions
> and ideas are welcomed.
Introduce new hooks at the proper location where the information is available.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 18:57 ` Crispin Cowan
2006-04-19 23:05 ` Rik van Riel
@ 2006-04-20 12:33 ` Stephen Smalley
2006-04-20 16:27 ` Lars Marowsky-Bree
1 sibling, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-20 12:33 UTC (permalink / raw)
To: Crispin Cowan
Cc: Arjan van de Ven, Tony Jones, linux-kernel, chrisw,
linux-security-module
On Wed, 2006-04-19 at 11:57 -0700, Crispin Cowan wrote:
> Arjan van de Ven wrote:
> > On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> >
> >> Verify if profile
> >> + * authorizes mask operations on pathname (due to lack of vfsmnt it is sadly
> >> + * necessary to search mountpoints in namespace -- when nameidata is passed
> >> + * more fully, this code can go away). If more than one mountpoint matches
> >> + * but none satisfy the profile, only the first pathname (mountpoint) is
> >> + * returned for subsequent logging.
> >>
> > that sounds too bad ;)
> > If I manage to mount /etc/passwd as /tmp/passwd, you'll only find the
> > later and your entire security system seems to be down the drain.
> >
> If you are a confined process, then you don't get to mount things, for
> this reason, among others.
Which is an example of the brokenness of the security model - its
fragileness in the face of manipulation of the file tree leads to
inflexibility. So for example, if you wanted to _protect_ a process
that does mount things as part of its legitimate purpose, e.g. by
limiting what it can access to prevent it from taking untrustworthy
inputs, then you are out of luck - it is either confined and can't mount
or not confined and can mount.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-19 17:50 ` [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore Tony Jones
2006-04-19 22:10 ` Christoph Hellwig
@ 2006-04-20 12:39 ` Stephen Smalley
2006-04-20 12:46 ` Serge E. Hallyn
2006-04-20 21:50 ` Linda Walsh
1 sibling, 2 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-20 12:39 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, 2006-04-19 at 10:50 -0700, Tony Jones wrote:
> This patch exports the namespace_sem semaphore.
>
> The shared subtree patches which went into 2.6.15-rc1 replaced the old
> namespace semaphore which used to be per namespace (and visible) with a
> new single static semaphore.
>
> The reason for this change is that currently visibility of vfsmount information
> to the LSM hooks is fairly patchy. Either there is no passed parameter or
> it can be NULL. For the case of the former, several LSM hooks that we
> require to mediate have no vfsmount/nameidata passed. We previously (mis)used
> the visibility of the old per namespace semaphore to walk the processes
> namespace looking for vfsmounts with a root dentry matching the dentry we were
> trying to mediate.
>
> Clearly this is not viable long term strategy and changes working towards
> passing a vfsmount to all relevant LSM hooks would seem necessary (and also
> useful for other users of LSM). Alternative suggestions and ideas are welcomed.
The alternative I would recommend is to not use LSM. It isn't suitable
for your path-based approach. If your path-based approach is deemed
legitimate, then introduce new hooks at the proper point in processing
where the information you need is available.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 12:39 ` Stephen Smalley
@ 2006-04-20 12:46 ` Serge E. Hallyn
2006-04-20 12:05 ` Stephen Smalley
2006-04-20 21:50 ` Linda Walsh
1 sibling, 1 reply; 173+ messages in thread
From: Serge E. Hallyn @ 2006-04-20 12:46 UTC (permalink / raw)
To: Stephen Smalley; +Cc: Tony Jones, linux-kernel, chrisw, linux-security-module
Quoting Stephen Smalley (sds@tycho.nsa.gov):
> On Wed, 2006-04-19 at 10:50 -0700, Tony Jones wrote:
> > This patch exports the namespace_sem semaphore.
> >
> > The shared subtree patches which went into 2.6.15-rc1 replaced the old
> > namespace semaphore which used to be per namespace (and visible) with a
> > new single static semaphore.
> >
> > The reason for this change is that currently visibility of vfsmount information
> > to the LSM hooks is fairly patchy. Either there is no passed parameter or
> > it can be NULL. For the case of the former, several LSM hooks that we
> > require to mediate have no vfsmount/nameidata passed. We previously (mis)used
> > the visibility of the old per namespace semaphore to walk the processes
> > namespace looking for vfsmounts with a root dentry matching the dentry we were
> > trying to mediate.
> >
> > Clearly this is not viable long term strategy and changes working towards
> > passing a vfsmount to all relevant LSM hooks would seem necessary (and also
> > useful for other users of LSM). Alternative suggestions and ideas are welcomed.
>
> The alternative I would recommend is to not use LSM. It isn't suitable
> for your path-based approach. If your path-based approach is deemed
> legitimate, then introduce new hooks at the proper point in processing
> where the information you need is available.
Whoa, so now LSM is not for access control?
Of course if SuSE follows Al Viro's suggestion of using namespaces
(effectively using capabilities in their traditional sense), they'll use
fewer hooks, but they'll still need to prevent leaking of fd's accross
namespaces, for instance.
-serge
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 13:21 ` Serge E. Hallyn
@ 2006-04-20 12:48 ` Stephen Smalley
2006-04-20 12:58 ` Stephen Smalley
2006-04-20 22:11 ` Linda A. Walsh
2006-04-20 19:45 ` Tony Jones
1 sibling, 2 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-20 12:48 UTC (permalink / raw)
To: Serge E. Hallyn; +Cc: linux-security-module, chrisw, linux-kernel, Tony Jones
On Thu, 2006-04-20 at 08:21 -0500, Serge E. Hallyn wrote:
> Tony, do you have any performance measurements? Both for unconfined and
> confined apps? Presumably unconfined processes should have 0 performance
> hit, right?
Preferably something that exercises open, mkdir, link... and friends
intensively, not just the old WebStone data that I've seen posted
before.
But you don't really need the benchmarks - just look at the code, and
think about the implications of allocating a page and calling d_path on
every permission(9) call (on every component) plus from the separate
hooks in the vfs_ helpers and further consider the impact of taking the
dcache lock all the time there. And look at the iterators being used in
aa_perm_dentry as well as the truly fun ones in aa_link. All because
they are doing it from LSM hooks that were never intended to be used
this way.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 12:48 ` Stephen Smalley
@ 2006-04-20 12:58 ` Stephen Smalley
2006-04-20 22:11 ` Linda A. Walsh
1 sibling, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-20 12:58 UTC (permalink / raw)
To: Serge E. Hallyn; +Cc: linux-security-module, chrisw, linux-kernel, Tony Jones
On Thu, 2006-04-20 at 08:48 -0400, Stephen Smalley wrote:
> On Thu, 2006-04-20 at 08:21 -0500, Serge E. Hallyn wrote:
> > Tony, do you have any performance measurements? Both for unconfined and
> > confined apps? Presumably unconfined processes should have 0 performance
> > hit, right?
>
> Preferably something that exercises open, mkdir, link... and friends
> intensively, not just the old WebStone data that I've seen posted
> before.
>
> But you don't really need the benchmarks - just look at the code, and
> think about the implications of allocating a page and calling d_path on
> every permission(9) call (on every component) plus from the separate
> hooks in the vfs_ helpers and further consider the impact of taking the
> dcache lock all the time there. And look at the iterators being used in
> aa_perm_dentry as well as the truly fun ones in aa_link. All because
> they are doing it from LSM hooks that were never intended to be used
> this way.
Ah, I have to correct the above - the mask filtering skips directory
traversal checking, so not every component I suppose. Which is
interesting for another reason. But performance situation still looks
fairly bad from a code POV, and the existing hooks still seem to be the
wrong place for this kind of processing/checking.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 1:32 ` Crispin Cowan
@ 2006-04-20 13:00 ` grundig
2006-04-20 13:09 ` Serge E. Hallyn
2006-04-24 13:01 ` Alan Cox
0 siblings, 2 replies; 173+ messages in thread
From: grundig @ 2006-04-20 13:00 UTC (permalink / raw)
To: Crispin Cowan
Cc: ak, grundig, arjan, linux-kernel, chrisw, linux-security-module
El Wed, 19 Apr 2006 18:32:30 -0700,
Crispin Cowan <crispin@novell.com> escribió:
> Our controls on changing the name space have rather poor granularity at
> the moment. We hope to improve that over time, and especially if LSM
> evolves to permit it. This is ok, because as Andi pointed out, there are
> currently few applications using name spaces, so we have time to improve
> the granularity.
Wouldn't have more sense to improve it and then submit it instead of the
contrary? At least is the rule which AFAIK is applied to every feature
going in the kernel, specially when there's an available alternative
which users can use meanwhile (see reiser4...)
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 13:00 ` grundig
@ 2006-04-20 13:09 ` Serge E. Hallyn
2006-04-20 13:15 ` Al Viro
2006-04-21 0:11 ` Tony Jones
2006-04-24 13:01 ` Alan Cox
1 sibling, 2 replies; 173+ messages in thread
From: Serge E. Hallyn @ 2006-04-20 13:09 UTC (permalink / raw)
To: grundig
Cc: Crispin Cowan, ak, arjan, linux-kernel, chrisw,
linux-security-module
Quoting grundig (grundig@teleline.es):
> El Wed, 19 Apr 2006 18:32:30 -0700,
> Crispin Cowan <crispin@novell.com> escribi?:
>
> > Our controls on changing the name space have rather poor granularity at
> > the moment. We hope to improve that over time, and especially if LSM
> > evolves to permit it. This is ok, because as Andi pointed out, there are
> > currently few applications using name spaces, so we have time to improve
> > the granularity.
>
> Wouldn't have more sense to improve it and then submit it instead of the
> contrary? At least is the rule which AFAIK is applied to every feature
> going in the kernel, specially when there's an available alternative
> which users can use meanwhile (see reiser4...)
hah, that's funny
When people do that, they are rebuked for not submitting upstream. At
least this way, we can have a discussion about whether the approach
makes sense at all.
-serge
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 13:09 ` Serge E. Hallyn
@ 2006-04-20 13:15 ` Al Viro
2006-04-21 0:11 ` Tony Jones
1 sibling, 0 replies; 173+ messages in thread
From: Al Viro @ 2006-04-20 13:15 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: grundig, Crispin Cowan, ak, arjan, linux-kernel, chrisw,
linux-security-module
On Thu, Apr 20, 2006 at 08:09:17AM -0500, Serge E. Hallyn wrote:
> Quoting grundig (grundig@teleline.es):
> > El Wed, 19 Apr 2006 18:32:30 -0700,
> > Crispin Cowan <crispin@novell.com> escribi?:
> >
> > > Our controls on changing the name space have rather poor granularity at
> > > the moment. We hope to improve that over time, and especially if LSM
> > > evolves to permit it. This is ok, because as Andi pointed out, there are
> > > currently few applications using name spaces, so we have time to improve
> > > the granularity.
> >
> > Wouldn't have more sense to improve it and then submit it instead of the
> > contrary? At least is the rule which AFAIK is applied to every feature
> > going in the kernel, specially when there's an available alternative
> > which users can use meanwhile (see reiser4...)
>
> hah, that's funny
>
> When people do that, they are rebuked for not submitting upstream. At
> least this way, we can have a discussion about whether the approach
> makes sense at all.
Not in such form. If authors want the patches reviewed, the least they
can do is splitting them up in a way that would allow reading them
sequentially, damnit...
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 12:05 ` Stephen Smalley
@ 2006-04-20 13:21 ` Serge E. Hallyn
2006-04-20 12:48 ` Stephen Smalley
2006-04-20 19:45 ` Tony Jones
0 siblings, 2 replies; 173+ messages in thread
From: Serge E. Hallyn @ 2006-04-20 13:21 UTC (permalink / raw)
To: Stephen Smalley
Cc: Serge E. Hallyn, linux-security-module, chrisw, linux-kernel,
Tony Jones
Quoting Stephen Smalley (sds@tycho.nsa.gov):
> On Thu, 2006-04-20 at 07:46 -0500, Serge E. Hallyn wrote:
> > Quoting Stephen Smalley (sds@tycho.nsa.gov):
> > > On Wed, 2006-04-19 at 10:50 -0700, Tony Jones wrote:
> > > > This patch exports the namespace_sem semaphore.
> > > >
> > > > The shared subtree patches which went into 2.6.15-rc1 replaced the old
> > > > namespace semaphore which used to be per namespace (and visible) with a
> > > > new single static semaphore.
> > > >
> > > > The reason for this change is that currently visibility of vfsmount information
> > > > to the LSM hooks is fairly patchy. Either there is no passed parameter or
> > > > it can be NULL. For the case of the former, several LSM hooks that we
> > > > require to mediate have no vfsmount/nameidata passed. We previously (mis)used
> > > > the visibility of the old per namespace semaphore to walk the processes
> > > > namespace looking for vfsmounts with a root dentry matching the dentry we were
> > > > trying to mediate.
> > > >
> > > > Clearly this is not viable long term strategy and changes working towards
> > > > passing a vfsmount to all relevant LSM hooks would seem necessary (and also
> > > > useful for other users of LSM). Alternative suggestions and ideas are welcomed.
> > >
> > > The alternative I would recommend is to not use LSM. It isn't suitable
> > > for your path-based approach. If your path-based approach is deemed
> > > legitimate, then introduce new hooks at the proper point in processing
> > > where the information you need is available.
> >
> > Whoa, so now LSM is not for access control?
>
> That isn't what I said, although I see that my phrasing wasn't clear. I
> said it wasn't suitable for a path-based approach. That is fairly clear
> from the hook placements and interfaces, and from the contortions that
> AppArmor has to go through in order to obtain the paths, and the number
> of times it ends up calling d_path on a single syscall. Now "new hooks"
.
> _could_ be new LSM hooks, I suppose, but my point was that it is a
> mistake to try to use the existing LSM VFS hooks for this purpose - they
> are in the wrong place for it, and no amount of munging will fix that.
> Make sense?
Yup, that (.) seems a pursuasive hint.
Tony, do you have any performance measurements? Both for unconfined and
confined apps? Presumably unconfined processes should have 0 performance
hit, right?
-serge
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 22:32 ` Andi Kleen
` (2 preceding siblings ...)
2006-04-20 11:29 ` Serge E. Hallyn
@ 2006-04-20 13:24 ` Christoph Hellwig
2006-04-20 22:32 ` Linda A. Walsh
4 siblings, 0 replies; 173+ messages in thread
From: Christoph Hellwig @ 2006-04-20 13:24 UTC (permalink / raw)
To: Andi Kleen; +Cc: Arjan van de Ven, linux-kernel, chrisw, linux-security-module
On Thu, Apr 20, 2006 at 12:32:43AM +0200, Andi Kleen wrote:
> Arjan van de Ven <arjan@infradead.org> writes:
> >
> > you must have a good defense against that argument, so I'm curious to
> > hear what it is
>
> [I'm not from the apparmor people but my understanding is]
>
> Usually they claimed name spaces as the reason it couldn't work.
>
> In practice AFAIK basically nobody uses name spaces for
> anything.
That;s mostly because we were missing feature to actually make them
usable. One of them was the shared subtree works which now is in
and will be used in practice by things like clearcase. The second big
thing we're missing is support to call mount() without addition privilegues.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 12:17 ` Stephen Smalley
@ 2006-04-20 15:38 ` Joshua Brindle
2006-04-20 19:57 ` Crispin Cowan
1 sibling, 0 replies; 173+ messages in thread
From: Joshua Brindle @ 2006-04-20 15:38 UTC (permalink / raw)
To: Stephen Smalley; +Cc: linux-kernel, chrisw, linux-security-module, Tony Jones
On Thu, 2006-04-20 at 08:17 -0400, Stephen Smalley wrote:
> On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> > AppArmor is an LSM security enhancement for the Linux kernel. The
> > primary goal of AppArmor is to make it easy for a system administrator
> > to control application behavior, enforcing that the application has
> > access to only the files and POSIX.1e draft capabilities it requires to
> > do its job. AppArmor deliberately uses this simple access control model
> > to make it as easy as possible for the administrator to manage the
> > policy, because the worst security of all is that which is never
> > deployed because it was too hard.
>
> The worst security is that which doesn't do what it claims to do, giving
> a false sense of security. Which is precisely the problem with
> path-based access control; it makes the user think that he is protecting
> a given object, when in fact the object may be accessible by another
> means.
I've compiled a list of security related issues with path based access
control at
http://securityblog.org/brindle/2006/04/19/security-anti-pattern-path-based-access-control/
I intentionally avoided specific implementations and OS related issues
to focus on the security aspects. Note that not all path based access
control implementations are subject to all these problems but some are
common to all.
Joshua Brindle
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-20 12:33 ` Stephen Smalley
@ 2006-04-20 16:27 ` Lars Marowsky-Bree
0 siblings, 0 replies; 173+ messages in thread
From: Lars Marowsky-Bree @ 2006-04-20 16:27 UTC (permalink / raw)
To: Stephen Smalley, Crispin Cowan
Cc: Arjan van de Ven, Tony Jones, linux-kernel, chrisw,
linux-security-module
On 2006-04-20T08:33:13, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> > If you are a confined process, then you don't get to mount things, for
> > this reason, among others.
> Which is an example of the brokenness of the security model - its
> fragileness in the face of manipulation of the file tree leads to
> inflexibility.
Now, now. Not every _limitation_ translates to _brokenness_. Some of
them are simply that - limitations. If you no like, you no run that
particular solution.
--
High Availability & Clustering
SUSE Labs, Research and Development
SUSE LINUX Products GmbH - A Novell Business -- Charles Darwin
"Ignorance more frequently begets confidence than does knowledge"
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path
2006-04-20 8:26 ` Arjan van de Ven
@ 2006-04-20 16:43 ` Tony Jones
2006-04-20 17:04 ` Christoph Hellwig
0 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-20 16:43 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Christoph Hellwig, linux-kernel, chrisw, linux-security-module
On Thu, Apr 20, 2006 at 10:26:09AM +0200, Arjan van de Ven wrote:
>
> > You are correct on calling BS in that I was wrong to refer to it as the
> > "system root". When a task chroots relative to it's current namespace, we
> > are interested in the path back to the root of that namespace, rather than
> > to the chroot. I believe the patch as stands achieves this, albeit with
> > some changing of comments.
>
> it actually doesn't; you assume there is such a path which is not a
> given. For example if your mount got lazy umounted (like hal probably
> does) then it's a floating mount not one tied to any tree going to the
> root of any namespace.
So, running with your "lazy unmounted" example for a bit.
The patch I proposed changes how d_path behaves when the task has chrooted
relative to it's namespace. So in your scenario what would calling d_path
on a dentry report (for !chrooted and chrooted) without this patch ?
I can't tell if you are claiming there is a fundamental problem calling d_path
*period* in this scenario. If so, I'd appreciate a little more concrete detail
in the way of an actual example, this is a bit hand-wavy.
Or that you are just saying another version of "pathames are crap" which I'm
not sure if appropos to this patch itself.
If it's the former, I'll happily go off and write some code to test your
assertion and it's ramifications if I can better understand what the actual
assertion is :-)
Thanks
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path
2006-04-20 16:43 ` Tony Jones
@ 2006-04-20 17:04 ` Christoph Hellwig
2006-04-20 17:50 ` Tony Jones
0 siblings, 1 reply; 173+ messages in thread
From: Christoph Hellwig @ 2006-04-20 17:04 UTC (permalink / raw)
To: Tony Jones
Cc: Arjan van de Ven, Christoph Hellwig, linux-kernel, chrisw,
linux-security-module
On Thu, Apr 20, 2006 at 09:43:29AM -0700, Tony Jones wrote:
> I can't tell if you are claiming there is a fundamental problem calling d_path
> *period* in this scenario. If so, I'd appreciate a little more concrete detail
The purpose of d_path is to give user information about a path, to be
used in things like procfs output. For everything else it's fundamentally
broken and shouldn't be used. And for exactly that reason it isn't used for
anything like that in the whole tree (except the possible fishy use in nfsd).
p.s.: I also see that your patch doesn't include on to export d_path so
couldn't actually use it anyway. Not that a patch to export it would ever
be ACKed for above reasons..
>
> in the way of an actual example, this is a bit hand-wavy.
>
> Or that you are just saying another version of "pathames are crap" which I'm
> not sure if appropos to this patch itself.
>
> If it's the former, I'll happily go off and write some code to test your
> assertion and it's ramifications if I can better understand what the actual
> assertion is :-)
>
> Thanks
>
> Tony
---end quoted text---
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-19 18:10 ` Arjan van de Ven
2006-04-19 18:57 ` Crispin Cowan
@ 2006-04-20 17:39 ` Tony Jones
1 sibling, 0 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-20 17:39 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, Apr 19, 2006 at 08:10:30PM +0200, Arjan van de Ven wrote:
> On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
> > +/**
> > + * _aa_perm_dentry
> > + * @active: profile to check against
> > + * @dentry: requested dentry
> > + * @mask: mask of requested operations
> > + * @pname: pointer to hold matched pathname (if any)
> > + *
> > + * Helper function. Obtain pathname for specified dentry.
>
> which namespace will this be in?
We perform validation relative to the current tasks namespace
> > Verify if profile
> > + * authorizes mask operations on pathname (due to lack of vfsmnt it is sadly
> > + * necessary to search mountpoints in namespace -- when nameidata is passed
> > + * more fully, this code can go away). If more than one mountpoint matches
> > + * but none satisfy the profile, only the first pathname (mountpoint) is
> > + * returned for subsequent logging.
>
> that sounds too bad ;)
> If I manage to mount /etc/passwd as /tmp/passwd, you'll only find the
> later and your entire security system seems to be down the drain.
Well first off, as addressed elsewhere, a confined task cannot mount.
Also, if you do bind mount as above, we will find both but we only report
the first. The path reported in this event will be used to generate policy.
Clearly if the ordering of which entry is found first varies, then for a
subsequent iteration, the policy may not be sufficient to grant the task
access and it will likely fail. This is important, a failure to specify a
path in a profile results in a failure of access not a allowal of access.
Solution, include all paths in the profile confining the task.
I do grant that a situation of very temporal mounts can make the generation
of a sane profile difficult. I've not used namespaces in such a manner so
I've not seen exactly how bad it is. One of my hopes from this thread was
that people would post real life in the trenches with namespaces examples,
both to aid us and maybe to illustrate where our approach is broken. Likewise
if you generate policy in an environment with a large number of mounts which
will not esist when the task runs under policy enforcement, you could run into
issues.
> > + filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt);
>
> what if filp->f_dentry is NULL ?
> like when the file got unlinked under you?
I believe there is a misunderstanding about the value of a unhashed dentry
when a file is unlinked from under a task. I responded to a more detailed
version of the same question posted by Valdis Kletniek.
Thanks for the post.
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 2/11] security: AppArmor - Core headers
2006-04-19 18:01 ` Arjan van de Ven
@ 2006-04-20 17:43 ` Tony Jones
0 siblings, 0 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-20 17:43 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: linux-kernel, chrisw, linux-security-module
On Wed, Apr 19, 2006 at 08:01:30PM +0200, Arjan van de Ven wrote:
> > +#ifndef __SUBDOMAIN_H
> > +#define __SUBDOMAIN_H
>
> this is an odd include guard for a file called apparmor.h
yes, noticed it 10 secs after I posted. Fixed.
> > +#include "shared.h"
> > +
> > +/* Control parameters (0 or 1), settable thru module/boot flags or
> > + * via /sys/kernel/security/apparmor/control */
> > +extern int apparmor_complain;
> > +extern int apparmor_debug;
> > +extern int apparmor_audit;
> > +extern int apparmor_logsyscall;
>
> looks like these should be in a header too
Ok.
> > +
> > +/* PIPEFS_MAGIC */
> > +#include <linux/pipe_fs_i.h>
> > +/* from net/socket.c */
> > +#define SOCKFS_MAGIC 0x534F434B
> > +/* from inotify.c */
> > +#define INOTIFYFS_MAGIC 0xBAD1DEA
>
> > +
> > +#define VALID_FSTYPE(inode) ((inode)->i_sb->s_magic != PIPEFS_MAGIC && \
> > + (inode)->i_sb->s_magic != SOCKFS_MAGIC && \
> > + (inode)->i_sb->s_magic != INOTIFYFS_MAGIC)
>
> ehhhh what is this about? Isn't this highly fragile???
Clearly a better comment is necessary.
There are a set of filesystem types for which we don't believe pathbased
mediation is relevant. Obviously for a system which is inode based mediating
these filesystems makes more sense. I'm unsure if it is fragile. Clearly
the set could grow, if this is what you mean, then yes, a less "fragile" way
of determining these would be useful.
> > + if (apparmor_debug) \
> > + printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
> > + } while (0)
> > +#define AA_INFO(fmt, args...) printk(KERN_INFO "AppArmor: " fmt, ##args)
> > +#define AA_WARN(fmt, args...) printk(KERN_WARNING "AppArmor: " fmt, ##args)
> > +#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args)
> > +
>
> eh why? at least use prdebug and the like, but don't do your own
Ok. Thanks. I'll look at it.
> > +/* aa_audit - AppArmor auditing structure
> > + * Structure is populated by access control code and passed to aa_audit which
> > + * provides for a single point of logging.
>
> why duplicate the audit infrastructure??
>
> (and it's not possible to use LSM for auditing really; so it's not just
> duplication, it's a bad idea)
We're not duplicating. aa_audit is just a common datastructure where AA
event information is stored. It is passed to aa_audit which logs it to
the kernel audit subsystem. It facilitates a single point of logging.
If you think this can be improved (clearly another case for better commenting)
I'd be curious to hear your views.
> > +/** aa_path_getname
> > + * @data: data object previously initialized by aa_path_begin
> > + *
> > + * Return the next mountpoint which has the same root dentry as data->root.
> > + * If no more mount points exist (or in case of error) NULL is returned
> > + * (caller should call aa_path_end() and inspect return code to differentiate)
> > + */
> > +static inline char *aa_path_getname(struct aa_path_data *data)
> > +{
> > + char *name = NULL;
> > + struct vfsmount *mnt;
> > +
> > + while (data->pos != data->head) {
> > + mnt = list_entry(data->pos, struct vfsmount, mnt_list);
> > +
> > + /* advance to next -- so that it is done before we break */
> > + data->pos = data->pos->next;
> > + prefetch(data->pos->next);
> > +
> > + if (mnt->mnt_root == data->root) {
> > + name = aa_get_name(data->dentry, mnt);
> > + if (!name)
> > + data->errno = -ENOMEM;
> > + break;
> > + }
> > + }
> > +
> > + return name;
>
> what's the locking rules and refcounting rules for this stuff ??
This is where the issue of the namespace_sem rears it's ugly head.
The issue isn't the namespace sem, it's the lack of vfsmount information
passed to LSM from the VFS, It facilitates the need for this function.
The change in visibility of the per namespace semaphore in the shared
subtree changes just makes it a little bit worse.
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path
2006-04-20 17:04 ` Christoph Hellwig
@ 2006-04-20 17:50 ` Tony Jones
2006-04-21 12:16 ` Stephen Smalley
0 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-20 17:50 UTC (permalink / raw)
To: Christoph Hellwig, Arjan van de Ven, linux-kernel, chrisw,
linux-security-module
On Thu, Apr 20, 2006 at 06:04:19PM +0100, Christoph Hellwig wrote:
> p.s.: I also see that your patch doesn't include on to export d_path so
> couldn't actually use it anyway. Not that a patch to export it would ever
> be ACKed for above reasons..
Don't understand. Are you saying there is no EXPORT_SYMBOL for d_path?
I didn't add one as I didn't remove the old one. It's still there.
Thanks
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 8:42 ` Arjan van de Ven
@ 2006-04-20 19:26 ` Crispin Cowan
2006-04-20 19:27 ` Chris Wright
1 sibling, 0 replies; 173+ messages in thread
From: Crispin Cowan @ 2006-04-20 19:26 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: Andi Kleen, linux-kernel, chrisw, linux-security-module
Arjan van de Ven wrote:
> I actually posted a list of 10 things that I made up in 3 minutes; just
> going over those 10 would be a good start already since they're the most
> obvious ones..
>
I had actually posted a response to those 10 questions in the previous
"remove LSM" thread. Here it is again.
> after all what does filename mean in a linux world with
> * hardlinks
If the policy lets you access /foo/bar/baz then you get to access
/foo/bar/baz, even if it is a hard link to /foo/bif.
Some would allege that this is a security "hole" in AppArmor. However,
AppArmor's design is that you only get to *create* that hard link if you
are either unconfined or your profile says you get to create it.
AppArmor implicitly trusts all non-confined processes, so anything they
do is ok, by definition.
> * chroot
In the currently shipping AppArmor that comes with SUSE Linux, the names
AppArmor sees are chroot-relative. The patch just posted fixes that and
the names AppArmor sees are now absolute, regardless of chroot jailing.
> * namespaces
> * bind mounts
As far as we know, our namespace support is fine; we mediate attempts to
modify namespaces (such as denying mount and umount) and requiring
cap_sys_chroot to modify the root of the namespace. If there are
instances where we are incorrect we would greatly appreciate a detailed
description of the issue (or better a testcase) so we can look at
resolving it.
> * unlink of open files
> * fd passing over unix sockets
AppArmor initially validates your access at open time, and there after
you can read&write to it without mediation. AppArmor re-validates your
access if policy is reloaded, you exec() a new program, you get passed
the fd from another process, or you call our change_hat() API.
So, if the file is unlinked or renamed while you have it open, and
policy says you don't have access to the new name, then:
* within the same process you get to keep accessing it until
o policy is reloaded by the administrator
o you call the change_hat() API
* in some other process, either a child or some process you passed
an fd to, you don't get to access it because your access gets
revalidated
Note that d_path still returns pathnames for files that have been
removed from the filesystem (that are open)
> * relative pathnames
If you access "../hosts.allow" AppArmor will canonicalize your path name
to /etc/hosts.allow before checking the policy.
> * multiple threads (where one can unlink+replace file while the other
> is in the validation code)
Can you show a specific case that you think would be a problem? Security
is the problem of allowing "good stuff" and blocking "bad stuff", and
that is hard to argue for complex cases that are not specific.
Crispin
--
Crispin Cowan, Ph.D. http://crispincowan.com/~crispin/
Director of Software Engineering, Novell http://novell.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 8:42 ` Arjan van de Ven
2006-04-20 19:26 ` Crispin Cowan
@ 2006-04-20 19:27 ` Chris Wright
2006-04-21 12:18 ` Stephen Smalley
1 sibling, 1 reply; 173+ messages in thread
From: Chris Wright @ 2006-04-20 19:27 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: Andi Kleen, linux-kernel, chrisw, linux-security-module
* Arjan van de Ven (arjan@infradead.org) wrote:
> On Thu, 2006-04-20 at 00:32 +0200, Andi Kleen wrote:
> > Arjan van de Ven <arjan@infradead.org> writes:
> > >
> > > you must have a good defense against that argument, so I'm curious to
> > > hear what it is
> >
> > [I'm not from the apparmor people but my understanding is]
> >
> > Usually they claimed name spaces as the reason it couldn't work.
>
> I actually posted a list of 10 things that I made up in 3 minutes; just
> going over those 10 would be a good start already since they're the most
> obvious ones..
Yes, the conversation is all over the place. Many of the issues are
about some of the uglier parts of the AppArmor code, but the critical
issue is simple. Does their protection model actually protect against
their threat model. I would really like to see some grounded examples
that show whether it's broken or not.
thanks,
-chris
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 13:21 ` Serge E. Hallyn
2006-04-20 12:48 ` Stephen Smalley
@ 2006-04-20 19:45 ` Tony Jones
2006-04-20 20:16 ` Serge E. Hallyn
2006-04-20 20:22 ` James Morris
1 sibling, 2 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-20 19:45 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: Stephen Smalley, linux-security-module, chrisw, linux-kernel
On Thu, Apr 20, 2006 at 08:21:28AM -0500, Serge E. Hallyn wrote:
> Tony, do you have any performance measurements? Both for unconfined and
> confined apps? Presumably unconfined processes should have 0 performance
> hit, right?
Hi Serge.
We have lmbench results. We had issues getting reproducability out of dbench
but need to look at it some more. The lmbench figures we presently have are
from the old code (reader writer lock). Results were good but we recently
converted to rcu for the reader dominated rw locks.
I'm not sure there is "0 performance hit for unconfined" as you have to check
for them being unconfined :) but it's low.
If you have other benchmarks we are open to suggestions. What has been used
to benchmark SELinux?
Anyways, we need to regenerate the results, we'll try and post in the next
couple days. ok?
Thanks
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 12:17 ` Stephen Smalley
2006-04-20 15:38 ` Joshua Brindle
@ 2006-04-20 19:57 ` Crispin Cowan
2006-04-21 13:34 ` Stephen Smalley
1 sibling, 1 reply; 173+ messages in thread
From: Crispin Cowan @ 2006-04-20 19:57 UTC (permalink / raw)
To: Stephen Smalley; +Cc: Tony Jones, linux-security-module, chrisw, linux-kernel
Stephen Smalley wrote:
> On Wed, 2006-04-19 at 10:49 -0700, Tony Jones wrote:
>
>> AppArmor is an LSM security enhancement for the Linux kernel. The
>> primary goal of AppArmor is to make it easy for a system administrator
>> to control application behavior, enforcing that the application has
>> access to only the files and POSIX.1e draft capabilities it requires to
>> do its job. AppArmor deliberately uses this simple access control model
>> to make it as easy as possible for the administrator to manage the
>> policy, because the worst security of all is that which is never
>> deployed because it was too hard.
>>
> The worst security is that which doesn't do what it claims to do, giving
> a false sense of security. Which is precisely the problem with
> path-based access control; it makes the user think that he is protecting
> a given object, when in fact the object may be accessible by another
> means.
>
Perhaps in some implementation, but not in AppArmor:
* AppArmor access controls are bound to processes, not files. The
control is to contain the subject, not shield the object.
* AppArmor uses a white list, not a black list. "By another means"
assumes that you have another means, and with the white list of
accessible file names, you generally don't.
Please show a case where AppArmor is not doing what it claims to do, or
stop spreading the FUD.
Consider Lampson's classic access control matrix, where you have all
your subjects (processes doing the operations) across one edge, and all
your objects (files and processes being operated on) along the other
edge, and the matrix cells contain permitted operations. Lampson's
matrix is the maximally expressive form of access control, but it is so
large as to be unmanageable. All access control schemes are abstractions
on this space to simplify it to make it manageable.
AppArmor is a particular abstraction on this space, where we profile
each row (process) by what application it runs, and then list the
columns (files) it can access, and in what mode. This is the exact dual
of ACLs, which put access lists on a file of who can access them. This
makes AppArmor a kind of capability system (in the security theory-head
way, nothing to do with POSIX.1e "capabilities"). However, because
confined entities cannot pass around AppArmor permissions as first-class
objects, it is called an "ambient capability" system.
>> AppArmor chooses which security policy to enforce for a process at
>> exec() time by the executable image's pathname, in conjunction with any
>> policy enforced for the currently running executable.
>>
> Multiple instances of the same program can't be distinguished?
>
They can be distinguished by the context you call them from. If your
policy says "/bin/foo px" then it uses the system profile for /bin/foo.
If your policy says "/bin/foo ix" then it inherits the parent's profile.
If your policy says "/bin/foo ux" then it executes unconstrained.
We are designing features to allow more ways to execute the same program
under different profiles in different contexts. But these features
require no new hooks, and so should not concern kernel developers, and
only be of interest to people who plan to use AppArmor.
>> AppArmor mediates access to the file system using absolute path names
>> with shell-syntax wildcards, so that "/srv/htdocs/** r" grants read
>> access to all files in /srv/htdocs.
>>
> So you have an unbounded number of policies that can govern access to
> any given file object and the enforcement of the system policy is
> entirely dependent on the file tree structure and any process that can
> manipulate that structure.
No; to the contrary, the above policy means the same thing on every file
system: if any file matching /srv/htdocs/** exists, then the contained
process can access it.
On the other hand, SELinux policy describes whether or not one label can
access another, and the meaning of that policy is dependent on the
existence and state of the labels in the file system. Tar and restore
your directory tree and the SELinux policy meaning changes. Labels on
the filesystem can change over time; so that running:
find / -exec ls -Z {} \; | grep httpd_user_content_t
will only show a snapshot of what would be allowed *right now*. So if
anything, SELinux is more sensitive to file system state than AppArmor,
and in any meaningful sense has many more possible policies enforced on
the system.
> Further, what about runtime files generated
> in shared directories like /tmp, /var/run, ...
What about them? If your program needs access to /tmp and /var, then
your policy should grant it. The above is a single line out of a
profile. The Apache profile is about 150 lines.
AppArmor is sufficiently expressive that you can give permission to
create /tmp/foo but *not* /tmp/bar. In SELinux, applications can create
/tmp files and give them labels different than the default label, but
AFAIK, SELinux can only either grant or deny permission to create a file
in a given directory, and not which file you can create.
You might care about this because the semantics of /etc/hosts.allow are
rather different than /etc/mumblebarf.
> And let's please
> separate user interface from kernel mechanism. If you want to specify
> pathnames for fixed resources in a user-level config file, that is fine,
> but pathnames have historically been rejected as a suitable basis for
> the kernel for a reason, not just in the security space. Why should
> this change? Isn't this a fundamental design change to Linux?
>
Because pathname matching in the kernel is fundamentally what makes
AppArmor easy to use. It is also what prevents AppArmor from being
implemented on top of SELinux.
>> AppArmor mediates access to POSIX.1e
>> Capabilities in that the process must both have e.g. "capability
>> net_bind_service" and intrinsically have that capability (usually by
>> being root) to be able to bind to privileged network ports. Thus a
>> confined process can not subvert AppArmor except as permitted by policy,
>>
> Not sure what is meant by "subvert AppArmor" here.
"Compromise" means a confined process being able to modify or disable
AppArmor policy.
> Bypass is certainly possible.
>
An interesting claim. We disagree, other than possibly coding errors.
Can you provide an actual example of bypass?
>> AppArmor is *not* intended to protect every aspect of the system from
>> every other aspect of the system: the intended usage is that only a
>> small fraction of all programs on a Linux system will have AppArmor
>> profiles. Rather, AppArmor is intended to protect the system against a
>> particular threat.
>>
> So the attacker knows precisely how to bypass it. The attacker (beyond
> the script kiddies) isn't going to attack you at the point of strength;
> he will attack you where you are known to be weak.
>
If you properly configured your system to confine all exposed programs,
then the attacker *must* start from a confined program, so this is a
non-issue.
Please keep in mind that our security goals are different from what
you've considered in the past; a system administrator will confine
programs that he or she considers are a higher than tolerable risk. We
provide an easy and reliable mechanism to confine software that poses
unreasonable risk. We do not try to provide provable information flow
properties.
>> For instance, to secure a machine against network attack, all programs
>> that face the network should be profiled. If all open network ports lead
>> to AppArmor profiles, then there is no way for the network attacker to
>> attack the machine, except as controlled by AppArmor policy. As a
>> convenience, AppArmor includes a netstat wrapper that reports all
>> programs with open network ports and their AppArmor profile status.
>>
> Except that your internal unconfined programs/processes may nonetheless
> be subverted via the confined program, because:
> a) you aren't controlling all objects and operations, and
> b) you aren't controlling those internal programs/processes at all, so
> they are at risk of taking untrustworthy inputs from the "confined"
> ones, and
>
That you could subvert a non-confined program from a confined program is
conjecture; you have to suppose that the non-confined program will
*listen* to assorted noise coming from the confined program. Certainly
you can build a covert channel that can leak data from a confined
process to a non-confined process, but only if the non-confined process
is listening. We mediate things like ptrace that would allow the
confined process to force the non-confined process to "listen".
And if you are concerned about a particular program being so sensitive
to its environment that it could be subverted, then confine it too.
Security is always a balance between convenience and, well, security :)
You can make an AppArmor system more secure and less convenient by
confining more programs and using more specific pathnames in the
profiles. Conversely, you can make it more convenient and less secure by
confining fewer programs and using path names with more wildcards.
Making the scalable decision between security and convenience available
to the user is an important feature of AppArmor.
> c) there is a high likelihood of interactions between those
> processes/programs in any real system, particularly in shared
> directories where paths aren't very useful as a distinguisher.
>
How so? We find them to be a very useful distinguisher. Lots and lots of
people find them to be a very useful distinguisher. In fact, when
configuring AppArmor policy, our users have been surprised at what
exactly their (often in-house, usually proprietary) applications access
-- and have been grateful for a tool that can make these distinctions.
>> 2. AppArmor needs to re-construct the full path name of files to
>> perform initial validation. Some of the LSM hooks that we mediate
>> do not have vfsmount/nameidata passed. Our temporary workaround is
>> to export the namespace_sem semaphore so we can safely walk the
>> process's namespace to find a vfsmount with a root dentry matching
>> the dentry we are trying to mediate. We believe a cleaner solution
>> (such as passing a vfsmount or nameidata to all LSM hooks throughout
>> the VFS layer) would be useful for audit, other LSMs, and
>> potentially FUSE. As it is a fair amount of work to pass vfsmount or
>> nameidata structures throughout the VFS, alternative suggestions
>> and ideas are welcomed.
>>
>
> Introduce new hooks at the proper location where the information is available.
>
The usual response to a request for a new hook is "where is the user?"
We want AppArmor to be in-tree as a first-class user of LSM, and then we
can discuss new hooks, perhaps as an alternative to properly supplying
vfsmount or nameidata to all of the existing hooks, which ever is more
elegant and convenient to the kernel maintainers.
Crispin
--
Crispin Cowan, Ph.D. http://crispincowan.com/~crispin/
Director of Software Engineering, Novell http://novell.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 19:45 ` Tony Jones
@ 2006-04-20 20:16 ` Serge E. Hallyn
2006-04-20 20:22 ` James Morris
1 sibling, 0 replies; 173+ messages in thread
From: Serge E. Hallyn @ 2006-04-20 20:16 UTC (permalink / raw)
To: Tony Jones
Cc: Serge E. Hallyn, Stephen Smalley, linux-security-module, chrisw,
linux-kernel
Quoting Tony Jones (tonyj@suse.de):
> On Thu, Apr 20, 2006 at 08:21:28AM -0500, Serge E. Hallyn wrote:
>
> > Tony, do you have any performance measurements? Both for unconfined and
> > confined apps? Presumably unconfined processes should have 0 performance
> > hit, right?
>
> Hi Serge.
>
> We have lmbench results. We had issues getting reproducability out of dbench
> but need to look at it some more. The lmbench figures we presently have are
> from the old code (reader writer lock). Results were good but we recently
> converted to rcu for the reader dominated rw locks.
>
> I'm not sure there is "0 performance hit for unconfined" as you have to check
> for them being unconfined :) but it's low.
>
> If you have other benchmarks we are open to suggestions. What has been used
> to benchmark SELinux?
I typically use dbench, reaim, tbench, and kernbench, running each 20
times.
> Anyways, we need to regenerate the results, we'll try and post in the next
> couple days. ok?
Cool, thanks.
-serge
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 19:45 ` Tony Jones
2006-04-20 20:16 ` Serge E. Hallyn
@ 2006-04-20 20:22 ` James Morris
1 sibling, 0 replies; 173+ messages in thread
From: James Morris @ 2006-04-20 20:22 UTC (permalink / raw)
To: Tony Jones
Cc: Serge E. Hallyn, Stephen Smalley, linux-security-module, chrisw,
linux-kernel
On Thu, 20 Apr 2006, Tony Jones wrote:
> We have lmbench results. We had issues getting reproducability out of dbench
> but need to look at it some more.
Which filesystem were you running dbench on? IIRC, journaling plays
havoc with it and you need to use something like ext2 to get reliable
data.
(Even though dbench is generally frowned upon, it's useful in situations
like this where you're not tuning fs code or similar).
- James
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 6/11] security: AppArmor - Userspace interface
2006-04-19 17:49 ` [RFC][PATCH 6/11] security: AppArmor - Userspace interface Tony Jones
@ 2006-04-20 21:39 ` Pavel Machek
2006-04-21 18:01 ` Tony Jones
0 siblings, 1 reply; 173+ messages in thread
From: Pavel Machek @ 2006-04-20 21:39 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
Hi!
> This patch implements the interface between the userspace policy loader
> and the kernel module. It is called by the .load, .remove and .replace
> file_operations hooks implemented in apparmorfs.c.
>
> The code is reponsible for serializing data in a platform independant
> manner from userspace and creating/activating the necessary apparmor
> profiles.
Documentation patch describing what kind of data you pass here would
be nice.
> +#include "match/match.h"
> +
> +/* aa_code defined in module_interface.h */
> +
> +const int aacode_datasize[] = { 1, 2, 4, 8, 2, 2, 4, 0, 0, 0, 0, 0, 0 };
I believe this needs a comment.
> +
> +/* inlines must be forward of there use in newer version of gcc,
> + just forward declaring with a prototype won't work anymore */
their use?
> +/**
> + * aa_activate_profile - unpack a serialized profile
> + * @e: serialized data extent information
> + * @error: error code returned if unpacking fails
> + */
> +static struct aaprofile *aa_activate_profile(struct aa_ext *e, ssize_t *error)
> +{
> + struct aaprofile *profile = NULL;
> + const char *rulename = "";
> + const char *error_string = "Invalid Profile";
> +
> + *error = -EPROTO;
> +
> + profile = alloc_aaprofile();
> + if (!profile) {
> + error_string = "Could not allocate profile";
> + *error = -ENOMEM;
> + goto fail;
> + }
> +
> + /* check that we have the right struct being passed */
> + AA_READ_X(e, AA_STRUCT, NULL, "profile");
> + AA_READ_X(e, AA_DYN_STRING, &profile->name, NULL);
> +
> + error_string = "Invalid flags";
> + /* per profile debug flags (debug, complain, audit) */
> + AA_READ_X(e, AA_STRUCT, NULL, "flags");
> + AA_READ_X(e, AA_U32, &(profile->flags.debug), "profile.flags.debug");
> + AA_READ_X(e, AA_U32, &(profile->flags.complain),
> + "profile.flags.complain");
> + AA_READ_X(e, AA_U32, &(profile->flags.audit), "profile.flags.audit");
> + AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
> +
> + error_string = "Invalid capabilities";
> + AA_READ_X(e, AA_U32, &(profile->capabilities), "profile.capabilities");
> +
> + /* get the file entries. */
> + AA_ENTRY_LIST("pgent"); /* pcre rules */
> + AA_ENTRY_LIST("sgent"); /* simple globs */
> + AA_ENTRY_LIST("fent"); /* regular file entries */
> +
> + /* get the net entries */
> + if (aa_is_nameX(e, AA_LIST, NULL, "net")) {
> + error_string = "Invalid net entry";
> + while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
> + if (!aa_activate_net_entry(e))
> + goto fail;
> + }
> + }
> + rulename = "";
> +
> + /* get subprofiles */
> + if (aa_is_nameX(e, AA_LIST, NULL, "hats")) {
> + error_string = "Invalid profile hat";
> + while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
> + struct aaprofile *subprofile;
> + subprofile = aa_activate_profile(e, error);
> + if (!subprofile)
> + goto fail;
> + subprofile->parent = profile;
> + list_add(&subprofile->list, &profile->sub);
> + }
> + }
> +
> + error_string = "Invalid end of profile";
> + AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
> +
> + return profile;
Is this kind of transltion neccessary?
Pavel
--
Thanks, Sharp!
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 4/11] security: AppArmor - Core access controls
2006-04-20 11:40 ` Serge E. Hallyn
@ 2006-04-20 21:39 ` Tony Jones
0 siblings, 0 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-20 21:39 UTC (permalink / raw)
To: Serge E. Hallyn; +Cc: Al Viro, linux-kernel, chrisw, linux-security-module
On Thu, Apr 20, 2006 at 06:40:10AM -0500, Serge E. Hallyn wrote:
> Quoting Al Viro (viro@ftp.linux.org.uk):
> >
> > > +static int _aa_perm_dentry(struct aaprofile *active, struct dentry *dentry,
> > > + int mask, const char **pname)
> > > +{
> > > + char *name = NULL, *failed_name = NULL;
> > > + struct aa_path_data data;
> > > + int error = 0, failed_error = 0, path_error,
> > > + complain = PROFILE_COMPLAIN(active);
> > > +
> > > + /* search all paths to dentry */
> > > +
> > > + aa_path_begin(dentry, &data);
> > > + do {
> > > + name = aa_path_getname(&data);
> > > + if (name) {
> > > + /* error here is 0 (success) or +ve (mask of perms) */
> > > + error = aa_file_perm(active, name, mask);
> > > +
> > > + /* access via any path is enough */
> > > + if (complain || error == 0)
> > > + break; /* Caller must free name */
> > > +
> > > + /* Already have an path that failed? */
> > > + if (failed_name) {
> > > + aa_put_name(name);
> > > + } else {
> > > + failed_name = name;
> > > + failed_error = error;
> > > + }
> > > + }
> > > + } while (name);
> >
> > Is that a joke? Are you really proposing to do _that_ on anything resembling
> > a hot path?
Unfortunately Al, no it's not a joke. We've been asked to publish performance
numbers by Serge as part of another thread. We plan to do so shortly. Of
course results are likely going to be related to the complexity of the
namespace the benchmark operates within. Suggestions of benchmarks that
significantly exercise namespaces are more than welcome.
We are no fan of this code either but the fact is that vfsmounts are passed
inconsistently to the LSM. Of course this isn't an issue of LSM just not
taking available data, rather of the information not being available in the
VFS at the point the hook is invoked. Going out on a limb here, to fully
support read-only bind mounts would seem to require similar changes - but
with a more limited scope - cases like security_inode_create and
security_inode_link likely still wouldn't have the necessary information to
fully eliminate the above fuglyness. Perhaps one hook cannot be made to provide
both useful inode and name information.
> > BTW, the problems here really have nothing to do with namespaces or
> > lazy umount, seeing that it's whitelisting. Moderate amount of bindings
> > will kill you here. So much that I suspect that one-time overhead of
> > creating a namespace and umounting / remounting noexec / etc. on
> > execve() will be cheaper than all this crap.
>
> I guess this would require per-vfsmount flags (i.e. mount --bind -o ro)
> to be implemented, but IIUC the suggestion is
>
> given a policy
>
> /bin/stty {
> /bin/stty r
> }
>
> during execve AA would unshare(CLONE_NEWNS), remount / readonly and
> noexec, and mount /bin/stty into place with exec privs. I guess
> getting /bin/stty into place shouldn't be much of a challenge (i.e.
> just do the operations in the order
> mkdir /.tmp123
> mount --bind -o ro,noexec / /.tmp123
> mount --bind /bin/stty /.tmp123/bin/stty
> mount --bind /.tmp123 /
> )
> but implementing the 'ux' exec permission which apparmor currently has
> (i.e. giving the ability for stty to then execute /bin/login without
> restrictions) could be more challenging.
>
> This also might beg for sys_unshare() (and corresponding code in clone)
> to have it's own security_vfs_unshare() hook, rather than being globbed
> in with CAP_SYS_ADMIN.
Are we referring here to the idea of giving each confined task it's own
namespace upon exec? An interesting idea for sure. The exec portion you
mention above is pretty trivial. How to handle directories, scratch space
(the ability of a confined task to write selected temp files) is less clear.
Also one of the most powerful aspects of AppArmor (at least if the users are
to be believed :-) is the ability for policy to contain path name expansion
(globbing). For instance, it is very useful to grant one web application
access to /var/www/**.html and another access to /var/www/**.pl.
But I think passing vfsmounts fully into LSM and closing the cases where a
nameidata can be NULL is an alternative plan B. Something we are willing to
put effort into helping achieve.
I believe what users want is a system which offers good practical security
together with ease of expressiveness in policy (so that it may be actually
maintained by other than distribution vendors). We strongly believe that
AppArmor provides this and think it is important to persue changes to LSM
(and the VFS) as necessary. However there is clearly an undeniable elegance
to the per-confined-task namespace idea. I have my concerns about whether it
can achieve close to the same expressiveness as current AppArmor policy (one
of AppArmor's clear advantages over SELinux) but it is clearly important that
the namespace idea is explored. Just not to the exclusion of also exploring
rework of the LSM/VFS.
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 12:39 ` Stephen Smalley
2006-04-20 12:46 ` Serge E. Hallyn
@ 2006-04-20 21:50 ` Linda Walsh
2006-04-20 21:56 ` Al Viro
2006-04-21 13:59 ` Stephen Smalley
1 sibling, 2 replies; 173+ messages in thread
From: Linda Walsh @ 2006-04-20 21:50 UTC (permalink / raw)
To: Stephen Smalley; +Cc: Tony Jones, linux-kernel, chrisw, linux-security-module
Stephen Smalley wrote:
> The alternative I would recommend is to not use LSM. It isn't suitable
> for your path-based approach. If your path-based approach is deemed
> legitimate, then introduce new hooks at the proper point in processing
> where the information you need is available.
>
---
I thought LSM was supposed to provide the hooks to allow virtually
any access control scheme to be implemented? I've seen complaints
before on either here or the LSM list that one of the hurdles for
"legitimacy" was whether or not it fit on top of the current set of
LSM hooks. I also saw it asked whether or not LSM had been
designed around, primarily, the needs of SELinux and if it was
going to remain so. If it was, then why not remove all non-SELinux
hooks? If LSM is to support alternate security methods, it is
logical to believe that LSM was not implemented with calls to
support every desired security model people might want. There
are known, insecure, race conditions in linux auditing, for
example, due to lack of LSM hooks. This was a conscious
design decision made by the LSM majority over objections
of people who wanted greater flexibility to support security
mechanisms not supportable with the current set of hooks.
In regards to "legitimacy", while I share the reservations
of many people in using a path based approach to security, I
might point out that this model is a basic one integrated into
Windows NT (XP & later, 2k?). That doesn't mean it is "good",
but it certainly should add some weight to the claim of
"legitimacy". I.e. - it provides a "comfortable", known
security mechanism for people switching to Linux servers from
from "Windows Server 2003".
In the Windows approach, you can specify allowed and disallowed
paths by unique name and using wildcards. This allowed/disallowed
hash is checked before every program execution.
If you start with a large, multi-user system, and allow no
user-level mounts (they just sign in and can pick from a
limited menu of choices, the pathname approach can have some
merit. For example, one might have a security policy only
allowing execution of binaries in "/usr/bin". The employer
puts all of his "reservation-system" or "database-access" routines
in "/usr/bin" (or adds the app path(s) to the allowed hash).
The end users run the allowed binaries and that's it.
I'm not saying it's an approach I would find useful to control
security on my systems, but I can see a potential usefulness
for it, in that it is relatively easy for people to understand,
setup and use.
Linda W
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 21:50 ` Linda Walsh
@ 2006-04-20 21:56 ` Al Viro
2006-04-20 23:54 ` James Morris
2006-04-21 13:59 ` Stephen Smalley
1 sibling, 1 reply; 173+ messages in thread
From: Al Viro @ 2006-04-20 21:56 UTC (permalink / raw)
To: Linda Walsh
Cc: Stephen Smalley, Tony Jones, linux-kernel, chrisw,
linux-security-module
On Thu, Apr 20, 2006 at 02:50:32PM -0700, Linda Walsh wrote:
> any access control scheme to be implemented? I've seen complaints
> before on either here or the LSM list that one of the hurdles for
> "legitimacy" was whether or not it fit on top of the current set of
> LSM hooks. I also saw it asked whether or not LSM had been
> designed
... and the answer is obviously "no". AFAICS, that was a way to get
around Linus' "at least decide on a common set of core kernel modifications"
without any kind of thinking being involved.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 12:48 ` Stephen Smalley
2006-04-20 12:58 ` Stephen Smalley
@ 2006-04-20 22:11 ` Linda A. Walsh
2006-04-20 23:05 ` Christoph Hellwig
2006-04-21 14:02 ` Stephen Smalley
1 sibling, 2 replies; 173+ messages in thread
From: Linda A. Walsh @ 2006-04-20 22:11 UTC (permalink / raw)
To: Stephen Smalley
Cc: Serge E. Hallyn, linux-security-module, chrisw, linux-kernel,
Tony Jones
Stephen Smalley wrote:
> But you don't really need the benchmarks - just look at the code, and
> think about the implications of allocating a page and calling d_path on
> every permission(9) call (on every component) plus from the separate
> hooks in the vfs_ helpers and further consider the impact of taking the
> dcache lock all the time there. And look at the iterators being used in
> aa_perm_dentry as well as the truly fun ones in aa_link. All because
> they are doing it from LSM hooks that were never intended to be used
> this way.
>
---
Agreed. The LSM hooks as they stand now are unsuitable
for AppArmor for the same reason they were unsuitable for auditing.
Linux isn't serious about security. If it was, it would have
the needed security calls. They were written, developed and tested
and benchmarked. Full auditing of every security relevant call
with full auditing turned on, had less than a 10% performance
hit doing a kernel build (while recording 5MBytes to disk/second
by the user-space audit daemon) -- that was using a 2x400MHz SMP
machine with 1 SCSI3 based disk (~30-35MB/s max transfer rate).
It was configurable at kernel build time to "totally go away" if
not used, to costing less than 1% (in the noise level) for compiled
in but turned off.
The *current* accepted way to get pathnames going into system
calls is to trap the syscall vector as audit currently does --
a method subject to race conditions. There is no way to implement
pathname-based security (or auditing) without providing hooks
in each of the relevant system calls after they have copied their
arguments from user space, safely into kernel space. Decoding
the arguments (including copying them from user space) twice allows
for a window during which the user-space arguments can still be
changed by a user-level process. You can't copy the arguments from
userspace, twice, and expect that the userspace memory will be
remain the same between the two "copies".
L
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 22:32 ` Andi Kleen
` (3 preceding siblings ...)
2006-04-20 13:24 ` Christoph Hellwig
@ 2006-04-20 22:32 ` Linda A. Walsh
4 siblings, 0 replies; 173+ messages in thread
From: Linda A. Walsh @ 2006-04-20 22:32 UTC (permalink / raw)
To: Andi Kleen; +Cc: Arjan van de Ven, linux-kernel, chrisw, linux-security-module
Andi Kleen wrote:
> Anyways, I guess the bigger issue is with hard links anyways
> (Chris gave a long list of other ways to get aliases in path names
> earlier). Discussing those might be much more fruitful.
Can't speak to a list I haven't seen, but hard links are not
a problem. Hard links can only be used within a volume. Simply
place all your allowed executables on one partition/volume.
Perhaps it is mounted read/only from a DVD or over an NFS share.
Hard links become a non problem if users can't write to the volume
that the files reside on.
Linda
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 22:11 ` Linda A. Walsh
@ 2006-04-20 23:05 ` Christoph Hellwig
2006-04-21 1:29 ` Linda A. Walsh
2006-04-21 14:02 ` Stephen Smalley
1 sibling, 1 reply; 173+ messages in thread
From: Christoph Hellwig @ 2006-04-20 23:05 UTC (permalink / raw)
To: Linda A. Walsh
Cc: Stephen Smalley, Serge E. Hallyn, linux-security-module, chrisw,
linux-kernel, Tony Jones
On Thu, Apr 20, 2006 at 03:11:51PM -0700, Linda A. Walsh wrote:
> The *current* accepted way to get pathnames going into system
> calls is to trap the syscall vector as audit currently does --
It's not and it's never been. Please get a fucking clue instead of
posting your uninformed opinions to lkml.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 21:56 ` Al Viro
@ 2006-04-20 23:54 ` James Morris
0 siblings, 0 replies; 173+ messages in thread
From: James Morris @ 2006-04-20 23:54 UTC (permalink / raw)
To: Al Viro
Cc: Linda Walsh, Stephen Smalley, Tony Jones, linux-kernel, chrisw,
linux-security-module
On Thu, 20 Apr 2006, Al Viro wrote:
> On Thu, Apr 20, 2006 at 02:50:32PM -0700, Linda Walsh wrote:
> > any access control scheme to be implemented? I've seen complaints
> > before on either here or the LSM list that one of the hurdles for
> > "legitimacy" was whether or not it fit on top of the current set of
> > LSM hooks. I also saw it asked whether or not LSM had been
> > designed
>
> ... and the answer is obviously "no". AFAICS, that was a way to get
> around Linus' "at least decide on a common set of core kernel modifications"
> without any kind of thinking being involved.
For reference, here are the original comments from Linus which were used
to conceive LSM:
http://marc.theaimsgroup.com/?l=linux-security-module&m=98706471912438&w=2
In a nutshell, Linus did not want to have to choose a security model.
In my view, the generic, correctly abstracted mechanism was actually
SELinux all along, and unfortunately, only a few people really understood
that then. SELinux was itself designed to allow different security models
to be composed, with clean separation of models, policy and enforcement
mechanism.
LSM was somewhat designed around SELinux, but necessarily lacking the
stronger semantics of SELinux, to allow other similar schemes to be
plugged in (the first significant example of which other than SELinux, has
only just appeared on lkml five years later).
- James
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 13:09 ` Serge E. Hallyn
2006-04-20 13:15 ` Al Viro
@ 2006-04-21 0:11 ` Tony Jones
1 sibling, 0 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-21 0:11 UTC (permalink / raw)
To: Serge E. Hallyn
Cc: grundig, Crispin Cowan, ak, arjan, linux-kernel, chrisw,
linux-security-module
On Thu, Apr 20, 2006 at 08:09:17AM -0500, Serge E. Hallyn wrote:
> Quoting grundig (grundig@teleline.es):
> > El Wed, 19 Apr 2006 18:32:30 -0700,
> > Crispin Cowan <crispin@novell.com> escribi?:
> >
> > > Our controls on changing the name space have rather poor granularity at
> > > the moment. We hope to improve that over time, and especially if LSM
> > > evolves to permit it. This is ok, because as Andi pointed out, there are
> > > currently few applications using name spaces, so we have time to improve
> > > the granularity.
> >
> > Wouldn't have more sense to improve it and then submit it instead of the
> > contrary? At least is the rule which AFAIK is applied to every feature
> > going in the kernel, specially when there's an available alternative
> > which users can use meanwhile (see reiser4...)
>
> hah, that's funny
>
> When people do that, they are rebuked for not submitting upstream. At
> least this way, we can have a discussion about whether the approach
> makes sense at all.
When an out of tree user is requesting a change for which it will likely be
the only user (such that it can make it in tree), caution is warranted. But
it does create a bit of a chicken and egg conundrum for the proposer.
At least this is the way it's always seemed to me (re: the requested VFS/LSM
changes). Anyways, it's not an issue and there isn't a lot of point dwelling
over past LSM history. I 100% agree with Serge, discussion first about the
approach is definately the way to go.
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 23:05 ` Christoph Hellwig
@ 2006-04-21 1:29 ` Linda A. Walsh
2006-04-21 2:09 ` Chris Wright
0 siblings, 1 reply; 173+ messages in thread
From: Linda A. Walsh @ 2006-04-21 1:29 UTC (permalink / raw)
To: Christoph Hellwig, Linda A. Walsh, Stephen Smalley,
Serge E. Hallyn, linux-security-module, chrisw, linux-kernel,
Tony Jones
Christoph Hellwig wrote:
> On Thu, Apr 20, 2006 at 03:11:51PM -0700, Linda A. Walsh wrote:
>
>> The *current* accepted way to get pathnames going into system
>> calls is to trap the syscall vector as audit currently does --
>>
> It's not and it's never been. [suggestion deleted]
What is not? I'm looking at entry.S, and 2 ptrace.c's, one under
arch/i386/kernel and another under kernel. Perhaps we are talking
about different architectures? Referring to the i386 architecture,
entry.S has the system call table processing, no?
This is the the code from the sysenter call:
testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AU
DIT),TI_flags(%ebp)
That looks like a patch for SECCOMP, SYSCALL_EMU and AUDIT that goes
off to do special processing in the system sys_trace call. This calls the
ptrace function for every syscall, no? Doesn't that then call
kernel/ptrace.c(sys_ptrace), grab the system lock (that is
what lock_system() is for, isn't it?), which then calls the
arch-specific ptrace.c in 'arch/i386/kernel'? Or have I missed
something yet?
Now here is code from that ptrace.c:
------------
/* notification of system call entry/exit
* - triggered by current->work.syscall_trace
*/
__attribute__((regparm(3)))
int do_syscall_trace(struct pt_regs *regs, int entryexit)
{
... do sysemu related stuff...
/* do the secure computing check first */
if (!entryexit)
secure_computing(regs->orig_eax);
if (unlikely(current->audit_context)) {
if (entryexit)
audit_syscall_exit(current, AUDITSC_RESULT(regs->eax),
regs->eax);
--------------
Doesn't ptrace trap every syscall and call audit for every syscall
when audit is enabled?
Perhaps my wording was confusing? I'm sorry, I should have
said:
"The *current* accepted way to get pathnames going into system calls is
to put a trap in the syscall vector processing code to be indirectly
called through the ptrace call with every system call as audit currently
does..."?
Or is that not correct either? If not, could you please be more
specific in your objection instead of suggesting I get pointers on my sex
life?
Of course the above code brings up a 2nd question. Is it acceptable
for audit records to be lost, or if a system gets heavily loaded, isn't
it possible for audit_syscall to block waiting some place to record the
audit context? Wouldn't those call occur after the "lock_kernel();"
line in kernel/ptrace.c, Could it be holding the "big kernel lock"
(still) when it blocks? Or would audit drop the kernel lock before
blocking?
In my last linux audit driver implementation, I had it setup such
that the audited process would block, but the system could continue so
that "auditd" (a non audited process) could free up a buffer by "reading"
it thus unblocking any processes blocked on an audit call. But, not
hanging the system needlessly was one of my design goals.
Linda
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-21 1:29 ` Linda A. Walsh
@ 2006-04-21 2:09 ` Chris Wright
2006-04-21 5:10 ` Linda Walsh
0 siblings, 1 reply; 173+ messages in thread
From: Chris Wright @ 2006-04-21 2:09 UTC (permalink / raw)
To: Linda A. Walsh
Cc: Christoph Hellwig, Stephen Smalley, Serge E. Hallyn,
linux-security-module, chrisw, linux-kernel, Tony Jones
* Linda A. Walsh (law@tlinx.org) wrote:
> "The *current* accepted way to get pathnames going into system calls is
> to put a trap in the syscall vector processing code to be indirectly
> called through the ptrace call with every system call as audit currently
> does..."?
>
> Or is that not correct either?
No it's not. See getname(9).
thanks,
-chris
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-21 2:09 ` Chris Wright
@ 2006-04-21 5:10 ` Linda Walsh
2006-04-23 12:11 ` Arjan van de Ven
0 siblings, 1 reply; 173+ messages in thread
From: Linda Walsh @ 2006-04-21 5:10 UTC (permalink / raw)
To: linux-kernel; +Cc: Christoph Hellwig, linux-security-module
Chris Wright wrote:
> * Linda A. Walsh (law@tlinx.org) wrote:
>> "The *current* accepted way to get pathnames going into system
>> calls is
>> to put a trap in the syscall vector processing code to be indirectly
>> called through the ptrace call with every system call as audit
>> currently does..."?
>>
>> Or is that not correct either?
> No it's not. See getname(9).
I'm familiar with the getname call, it's probably the case that
audit calls getname to do the actual copy from user->kernel space, I
haven't checked. But I can't find the manpage you are referring to.
I may be suffering from impaired "colloquialisms" in my writing, but
I was referring to the process of collecting pathnames for use in
a security policy (ex. audit, systrace or AppArmor) for the
kernel calls that take one or more pathnames being done via code
inserted into the system call code that is called with each system
call.
Whatever policy (audit, AppArmor, etc) is in place is then called
on every syscall and each policy then decides what actual
system calls it is interested in and then does call specific
argument processing to make a record of or enforce policy.
The argument processing would likely involve getname() to retrieve
the path from user space.
Is there something specific on the getname manpage you are
referring to or are we talking about the same thing?
Thanks for the clarification...:-)
Linda
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path
2006-04-20 17:50 ` Tony Jones
@ 2006-04-21 12:16 ` Stephen Smalley
0 siblings, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-21 12:16 UTC (permalink / raw)
To: Tony Jones
Cc: Christoph Hellwig, Arjan van de Ven, linux-kernel, chrisw,
linux-security-module
On Thu, 2006-04-20 at 10:50 -0700, Tony Jones wrote:
> On Thu, Apr 20, 2006 at 06:04:19PM +0100, Christoph Hellwig wrote:
>
> > p.s.: I also see that your patch doesn't include on to export d_path so
> > couldn't actually use it anyway. Not that a patch to export it would ever
> > be ACKed for above reasons..
>
> Don't understand. Are you saying there is no EXPORT_SYMBOL for d_path?
>
> I didn't add one as I didn't remove the old one. It's still there.
Yes, it does appear to be exported already, presumably for nfsd. Still
leaves open the question of whether it should be exported, or more
importantly what is considered legitimate use of it.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 19:27 ` Chris Wright
@ 2006-04-21 12:18 ` Stephen Smalley
2006-04-21 17:30 ` Chris Wright
0 siblings, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-21 12:18 UTC (permalink / raw)
To: Chris Wright
Cc: Arjan van de Ven, Andi Kleen, linux-kernel, linux-security-module
On Thu, 2006-04-20 at 12:27 -0700, Chris Wright wrote:
> * Arjan van de Ven (arjan@infradead.org) wrote:
> > On Thu, 2006-04-20 at 00:32 +0200, Andi Kleen wrote:
> > > Arjan van de Ven <arjan@infradead.org> writes:
> > > >
> > > > you must have a good defense against that argument, so I'm curious to
> > > > hear what it is
> > >
> > > [I'm not from the apparmor people but my understanding is]
> > >
> > > Usually they claimed name spaces as the reason it couldn't work.
> >
> > I actually posted a list of 10 things that I made up in 3 minutes; just
> > going over those 10 would be a good start already since they're the most
> > obvious ones..
>
> Yes, the conversation is all over the place. Many of the issues are
> about some of the uglier parts of the AppArmor code, but the critical
> issue is simple. Does their protection model actually protect against
> their threat model. I would really like to see some grounded examples
> that show whether it's broken or not.
Difficult to evaluate, when the answer whenever a flaw is pointed out is
"that's not in our threat model." Easy enough to have a protection
model match the threat model when the threat model is highly limited
(and never really documented anywhere, particularly in a way that might
warn its users of its limitations).
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 19:57 ` Crispin Cowan
@ 2006-04-21 13:34 ` Stephen Smalley
0 siblings, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-21 13:34 UTC (permalink / raw)
To: Crispin Cowan
Cc: James Morris, Tony Jones, linux-security-module, chrisw,
linux-kernel
On Thu, 2006-04-20 at 12:57 -0700, Crispin Cowan wrote:
> Perhaps in some implementation, but not in AppArmor:
>
> * AppArmor access controls are bound to processes, not files. The
> control is to contain the subject, not shield the object.
> * AppArmor uses a white list, not a black list. "By another means"
> assumes that you have another means, and with the white list of
> accessible file names, you generally don't.
>
> Please show a case where AppArmor is not doing what it claims to do, or
> stop spreading the FUD.
I'm not the one spreading FUD.
If you read one of AppArmor's whitelist profiles and conclude that
because /etc/shadow is not listed in it, your shadow password data is
protected against reading via a compromise of that program, then you
might find yourself unpleasantly surprised. You can't tell that from
any AppArmor profile; you only know that if said process tries to open
the path "/etc/shadow", it should be denied access. You don't know
whether any other path in that same profile might ever refer to that
same file, or whether the shadow data might be exposed to said process
via a non-file object (e.g. shared memory) being used by programs
legitimately accessing the shadow data, or whether said process might be
able to compromise another process on the same system via an
uncontrolled mechanism and gain access in that manner.
End users aren't going to recognize this limitation unless you spell it
out in your end user documentation. They will believe that their shadow
password data is now safe, because they've read the very simple profile
for their program and it doesn't include "/etc/shadow" anywhere. They
will be disappointed when they find that their shadow password data has
leaked. And please don't assume that this only applies to
confidentiality/secrecy concerns; the same reasoning applies to
protecting the integrity of their systems.
> Consider Lampson's classic access control matrix, where you have all
> your subjects (processes doing the operations) across one edge, and all
> your objects (files and processes being operated on) along the other
> edge, and the matrix cells contain permitted operations. Lampson's
> matrix is the maximally expressive form of access control, but it is so
> large as to be unmanageable. All access control schemes are abstractions
> on this space to simplify it to make it manageable.
>
> AppArmor is a particular abstraction on this space, where we profile
> each row (process) by what application it runs, and then list the
> columns (files) it can access, and in what mode.
There is an assumption in the access matrix that the subjects and
objects are accurately and unambiguously identified. That is achieved
when the subjects and objects are labeled by the kernel and the labels
are used for the access control, or when unique identifiers are used for
the subject and object and used for the access control. It is not
achieved via pathnames. Therein lies the problem.
> > So you have an unbounded number of policies that can govern access to
> > any given file object and the enforcement of the system policy is
> > entirely dependent on the file tree structure and any process that can
> > manipulate that structure.
> No; to the contrary, the above policy means the same thing on every file
> system: if any file matching /srv/htdocs/** exists, then the contained
> process can access it.
That seems to miss my point, which was that a single file object (i.e.
inode) may be accessible under multiple paths, and thus a single process
that accesses it may get different permissions depending on which path
it used, yielding multiple policies for the same object. And
rearrangement of the file tree alters the effective policy that is
applied to a given file object, as it is path-based rather than
object-based.
> On the other hand, SELinux policy describes whether or not one label can
> access another, and the meaning of that policy is dependent on the
> existence and state of the labels in the file system.
No, the meaning of the policy is not dependent on the filesystem state;
you can analyze the policy separate from the filesystem state and know
definitively whether or not e.g. high integrity data can ever be
corrupted by a low integrity source, or whether secret data can ever be
leaked to an insecure sink. The policy is in terms of abstractions /
security equivalence classes, because you are trying to enforce higher
level security goals re confidentiality and integrity, not just whether
program X can read file F.
> Tar and restore
> your directory tree and the SELinux policy meaning changes. Labels on
> the filesystem can change over time; so that running:
> find / -exec ls -Z {} \; | grep httpd_user_content_t
>
> will only show a snapshot of what would be allowed *right now*. So if
> anything, SELinux is more sensitive to file system state than AppArmor,
> and in any meaningful sense has many more possible policies enforced on
> the system.
No, the meaning of the policy doesn't change. The precise set of
objects that fall within a given security equivalence class can change
subject to the control of the policy (so even such changes fall within
the scope of an analysis of the policy, and do not alter the information
flow analysis). Now, if your concern is with file relabeling, I'd agree
that isn't desirable. The goal is to ensure that data is labeled
correctly when it is created, and preserved throughout its lifetime.
File relabeling is usually an indication of a defect in policy or
userspace, and should be gradually eradicated from the normal runtime
operation of the system.
>
> > Further, what about runtime files generated
> > in shared directories like /tmp, /var/run, ...
> What about them? If your program needs access to /tmp and /var, then
> your policy should grant it. The above is a single line out of a
> profile. The Apache profile is about 150 lines.
Runtime files often don't have well-defined names, e.g. randomly
generated components, pids, arbitrary choices of users, etc. So
path-based configuration runs into problems, whereas labeled objects
reflect the security properties of their creators and thus already are
protected properly.
> AppArmor is sufficiently expressive that you can give permission to
> create /tmp/foo but *not* /tmp/bar. In SELinux, applications can create
> /tmp files and give them labels different than the default label, but
> AFAIK, SELinux can only either grant or deny permission to create a file
> in a given directory, and not which file you can create.
In SELinux, newly created files are labeled in accordance with policy
and reflect the security properties of their creators.
Thus, /tmp/xyGp98x if created by sendmail would have a different
security label than the same path if created by named, and policy can
ensure that only the appropriate process can access that file.
> You might care about this because the semantics of /etc/hosts.allow are
> rather different than /etc/mumblebarf.
Yes, but this can be addressed either by providing distinct tools for
manipulation of objects that require distinct protection (and
configuring policy to label the objects created by those tools
accordingly), or by just instrumenting your basic editing tools to
preserve security attributes in the same way they already preserve file
modes or ACLs (a fair amount of which has been done for SELinux in at
least some distros, albeit not complete). More work? Sure. But the
right technical approach.
> > And let's please
> > separate user interface from kernel mechanism. If you want to specify
> > pathnames for fixed resources in a user-level config file, that is fine,
> > but pathnames have historically been rejected as a suitable basis for
> > the kernel for a reason, not just in the security space. Why should
> > this change? Isn't this a fundamental design change to Linux?
> >
> Because pathname matching in the kernel is fundamentally what makes
> AppArmor easy to use. It is also what prevents AppArmor from being
> implemented on top of SELinux.
But it is also fundamentally contrary to the Unix (and more so Linux)
model, IMHO. Naturally, not my call to make, but it seems problematic,
as this kind of approach has been rejected before.
>
> > Bypass is certainly possible.
> >
> An interesting claim. We disagree, other than possibly coding errors.
> Can you provide an actual example of bypass?
I'm not talking about implementation bugs in AppArmor; I mean the
incomplete mediation and inaccurate basis of security decisions in
AppArmor. Examples given already include the subversion of the system
via an uncontrolled mechanism like local IPC or being able to access the
same data under another path. That is a bypass of the intended
protection (or at least the protection that would be expected by your
users, barring a big fat disclaimer on your product literature).
> > So the attacker knows precisely how to bypass it. The attacker (beyond
> > the script kiddies) isn't going to attack you at the point of strength;
> > he will attack you where you are known to be weak.
> >
> If you properly configured your system to confine all exposed programs,
> then the attacker *must* start from a confined program, so this is a
> non-issue.
But that doesn't help when you don't control all operations (hence
bypass via uncontrolled mechanisms) and when your basis of control is
ambiguous.
> Please keep in mind that our security goals are different from what
> you've considered in the past; a system administrator will confine
> programs that he or she considers are a higher than tolerable risk. We
> provide an easy and reliable mechanism to confine software that poses
> unreasonable risk. We do not try to provide provable information flow
> properties.
If you can't control information flow, then you can't provide any real
confidentiality or integrity guarantees. If I wanted a reliable
mechanism with minimal impact on userspace and didn't want to use
SELinux for some reason, I'd use a virtualization technique, not
AppArmor.
> That you could subvert a non-confined program from a confined program is
> conjecture; you have to suppose that the non-confined program will
> *listen* to assorted noise coming from the confined program.
That isn't unlikely. As just one trivial example, malicious symlink
attacks are all about tricking a more privileged program into relying on
untrustworthy inputs.
> And if you are concerned about a particular program being so sensitive
> to its environment that it could be subverted, then confine it too.
AppArmor doesn't seem to generalize too well to full system protection.
> Security is always a balance between convenience and, well, security :)
> You can make an AppArmor system more secure and less convenient by
> confining more programs and using more specific pathnames in the
> profiles. Conversely, you can make it more convenient and less secure by
> confining fewer programs and using path names with more wildcards.
> Making the scalable decision between security and convenience available
> to the user is an important feature of AppArmor.
But you are limited in your achievable security by the mechanism in
AppArmor (again, incomplete mediation and inaccurate basis for security
decisions). SELinux provides genuine scalability here, from a minimal
targeted policy through a highly strict one, all with the same
mechanism.
> > c) there is a high likelihood of interactions between those
> > processes/programs in any real system, particularly in shared
> > directories where paths aren't very useful as a distinguisher.
> >
> How so? We find them to be a very useful distinguisher. Lots and lots of
> people find them to be a very useful distinguisher. In fact, when
> configuring AppArmor policy, our users have been surprised at what
> exactly their (often in-house, usually proprietary) applications access
> -- and have been grateful for a tool that can make these distinctions.
For fixed resources, paths are ok (in userspace config files, not kernel
mechanism). But for runtime files created in shared directories, the
name is often dynamically generated or arbitrarily selected, and doesn't
tell us anything about the real security properties.
> The usual response to a request for a new hook is "where is the user?"
> We want AppArmor to be in-tree as a first-class user of LSM, and then we
> can discuss new hooks, perhaps as an alternative to properly supplying
> vfsmount or nameidata to all of the existing hooks, which ever is more
> elegant and convenient to the kernel maintainers.
Usually you have to fix your implementation before you can get it
in-tree. We had to do that for SELinux, e.g. migrating from our own
file labeling implementation to using xattrs. I would argue that your
current implementation is a misuse of the current LSM interfaces. Not
my call to make, of course, but if that is the prevailing opinion, you
should have to rework your implementation first, and get the necessary
dependencies in place. All of which presumes that a path-based
mechanism is acceptable at all (again, not my call to make).
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 21:50 ` Linda Walsh
2006-04-20 21:56 ` Al Viro
@ 2006-04-21 13:59 ` Stephen Smalley
1 sibling, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-21 13:59 UTC (permalink / raw)
To: Linda Walsh; +Cc: Tony Jones, linux-kernel, chrisw, linux-security-module
On Thu, 2006-04-20 at 14:50 -0700, Linda Walsh wrote:
>
> Stephen Smalley wrote:
> > The alternative I would recommend is to not use LSM. It isn't suitable
> > for your path-based approach. If your path-based approach is deemed
> > legitimate, then introduce new hooks at the proper point in processing
> > where the information you need is available.
> >
> ---
> I thought LSM was supposed to provide the hooks to allow virtually
> any access control scheme to be implemented?
The first question is whether a path-based mechanism is suitable for the
kernel at all. Not my call to make, but seems to run counter to the
Unix and more so the Linux model, and to past discussions on
linux-fsdevel and linux-kernel.
If a path-based mechanism is suitable, then the next question is whether
LSM is suitable as a means of implementing such a mechanism. At
present, I would argue that it is not - the hook placement and
interfaces are not well suited to it (despite being originally proposed
by the WireX folks who worked on SubDomain/AppArmor), and the current
AppArmor implementation requires significant contortions to work around
the interface mismatch. Which would suggest that they need to propose
changes to LSM (e.g. new hooks at more suitable locations) first.
> I've seen complaints
> before on either here or the LSM list that one of the hurdles for
> "legitimacy" was whether or not it fit on top of the current set of
> LSM hooks.
I don't recall that one; submitting new hook proposals is ok as long as
there is a user that will also be submitted. SELinux itself has needed
to extend the LSM interface over time.
> I also saw it asked whether or not LSM had been
> designed around, primarily, the needs of SELinux and if it was
> going to remain so.
SELinux was and remains the primary user, so that obviously has
influence, but as I've noted before, the original VFS hooks were first
proposed by the WireX folks, and they were active participants during
LSM development.
> If it was, then why not remove all non-SELinux
> hooks?
That is actually a good idea. They can always be added back if a
genuine user comes along. SELinux also has some stubs that should be
dropped at the same time.
> If LSM is to support alternate security methods, it is
> logical to believe that LSM was not implemented with calls to
> support every desired security model people might want. There
> are known, insecure, race conditions in linux auditing, for
> example, due to lack of LSM hooks. This was a conscious
> design decision made by the LSM majority over objections
> of people who wanted greater flexibility to support security
> mechanisms not supportable with the current set of hooks.
I think you haven't looked at the native Linux 2.6 audit implementation
very closely. LSM wasn't suitable for audit. The namei code and other
parts of the kernel have been hooked to call into the audit system to
collect information as needed.
> In regards to "legitimacy", while I share the reservations
> of many people in using a path based approach to security, I
> might point out that this model is a basic one integrated into
> Windows NT (XP & later, 2k?). That doesn't mean it is "good",
> but it certainly should add some weight to the claim of
> "legitimacy". I.e. - it provides a "comfortable", known
> security mechanism for people switching to Linux servers from
> from "Windows Server 2003".
>
> In the Windows approach, you can specify allowed and disallowed
> paths by unique name and using wildcards. This allowed/disallowed
> hash is checked before every program execution.
Do you know how they implement it? The question is not whether
path-based configuration in userspace is ok; it is whether the kernel
mechanism should be relying on pathnames. There are also much saner
implementation approaches for name-based schemes than calling d_path to
generate the full path and checking that against a profile on each open;
DTE was one example.
> If you start with a large, multi-user system, and allow no
> user-level mounts (they just sign in and can pick from a
> limited menu of choices, the pathname approach can have some
> merit. For example, one might have a security policy only
> allowing execution of binaries in "/usr/bin". The employer
> puts all of his "reservation-system" or "database-access" routines
> in "/usr/bin" (or adds the app path(s) to the allowed hash).
> The end users run the allowed binaries and that's it.
SELinux can express such restrictions via its TE configuration already.
Or you can implement this kind of mechanism in other ways, but it
doesn't require the kernel to be generating and checking pathnames.
> I'm not saying it's an approach I would find useful to control
> security on my systems, but I can see a potential usefulness
> for it, in that it is relatively easy for people to understand,
> setup and use.
Which is fine for userspace tools, but doesn't justify it as the kernel
mechanism.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-20 22:11 ` Linda A. Walsh
2006-04-20 23:05 ` Christoph Hellwig
@ 2006-04-21 14:02 ` Stephen Smalley
1 sibling, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-21 14:02 UTC (permalink / raw)
To: Linda A. Walsh
Cc: Serge E. Hallyn, linux-security-module, chrisw, linux-kernel,
Tony Jones
On Thu, 2006-04-20 at 15:11 -0700, Linda A. Walsh wrote:
> The *current* accepted way to get pathnames going into system
> calls is to trap the syscall vector as audit currently does --
> a method subject to race conditions. There is no way to implement
> pathname-based security (or auditing) without providing hooks
> in each of the relevant system calls after they have copied their
> arguments from user space, safely into kernel space. Decoding
> the arguments (including copying them from user space) twice allows
> for a window during which the user-space arguments can still be
> changed by a user-level process. You can't copy the arguments from
> userspace, twice, and expect that the userspace memory will be
> remain the same between the two "copies".
They aren't being copied twice. Look at getname() in fs/namei.c, and
note the call to audit_getname(). The native Linux 2.6 audit framework
combines processing at entry/exit with certain hooks placed at key
locations to collect the necessary information, without requiring the
degree of invasiveness of the SGI CAPP auditing patches of long ago.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-21 12:18 ` Stephen Smalley
@ 2006-04-21 17:30 ` Chris Wright
2006-04-21 18:07 ` Stephen Smalley
0 siblings, 1 reply; 173+ messages in thread
From: Chris Wright @ 2006-04-21 17:30 UTC (permalink / raw)
To: Stephen Smalley
Cc: Chris Wright, Arjan van de Ven, Andi Kleen, linux-kernel,
linux-security-module
* Stephen Smalley (sds@tycho.nsa.gov) wrote:
> Difficult to evaluate, when the answer whenever a flaw is pointed out is
> "that's not in our threat model." Easy enough to have a protection
> model match the threat model when the threat model is highly limited
> (and never really documented anywhere, particularly in a way that might
> warn its users of its limitations).
I know, there's two questions. Whether the protection model is valid,
and whether the threat model is worth considering. So far, I've not
seen anything that's compelling enough to show AppArmor fundamentally
broken. Ugly and inefficient, yes...broken, not yet.
thanks,
-chris
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 6/11] security: AppArmor - Userspace interface
2006-04-20 21:39 ` Pavel Machek
@ 2006-04-21 18:01 ` Tony Jones
2006-04-21 18:41 ` Pavel Machek
0 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-21 18:01 UTC (permalink / raw)
To: Pavel Machek; +Cc: linux-kernel, chrisw, linux-security-module
On Thu, Apr 20, 2006 at 09:39:43PM +0000, Pavel Machek wrote:
> Hi!
>
> > This patch implements the interface between the userspace policy loader
> > and the kernel module. It is called by the .load, .remove and .replace
> > file_operations hooks implemented in apparmorfs.c.
> >
> > The code is reponsible for serializing data in a platform independant
> > manner from userspace and creating/activating the necessary apparmor
> > profiles.
>
> Documentation patch describing what kind of data you pass here would
> be nice.
Very true. We will add it.
> > +#include "match/match.h"
> > +
> > +/* aa_code defined in module_interface.h */
> > +
> > +const int aacode_datasize[] = { 1, 2, 4, 8, 2, 2, 4, 0, 0, 0, 0, 0, 0 };
>
> I believe this needs a comment.
Yep.
> > +
> > +/* inlines must be forward of there use in newer version of gcc,
> > + just forward declaring with a prototype won't work anymore */
>
> their use?
Thanks
> > +/**
> > + * aa_activate_profile - unpack a serialized profile
> > + * @e: serialized data extent information
> > + * @error: error code returned if unpacking fails
> > + */
> > +static struct aaprofile *aa_activate_profile(struct aa_ext *e, ssize_t *error)
> > +{
> > + struct aaprofile *profile = NULL;
> > + const char *rulename = "";
> > + const char *error_string = "Invalid Profile";
> > +
> > + *error = -EPROTO;
> > +
> > + profile = alloc_aaprofile();
> > + if (!profile) {
> > + error_string = "Could not allocate profile";
> > + *error = -ENOMEM;
> > + goto fail;
> > + }
> > +
> > + /* check that we have the right struct being passed */
> > + AA_READ_X(e, AA_STRUCT, NULL, "profile");
> > + AA_READ_X(e, AA_DYN_STRING, &profile->name, NULL);
> > +
> > + error_string = "Invalid flags";
> > + /* per profile debug flags (debug, complain, audit) */
> > + AA_READ_X(e, AA_STRUCT, NULL, "flags");
> > + AA_READ_X(e, AA_U32, &(profile->flags.debug), "profile.flags.debug");
> > + AA_READ_X(e, AA_U32, &(profile->flags.complain),
> > + "profile.flags.complain");
> > + AA_READ_X(e, AA_U32, &(profile->flags.audit), "profile.flags.audit");
> > + AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
> > +
> > + error_string = "Invalid capabilities";
> > + AA_READ_X(e, AA_U32, &(profile->capabilities), "profile.capabilities");
> > +
> > + /* get the file entries. */
> > + AA_ENTRY_LIST("pgent"); /* pcre rules */
> > + AA_ENTRY_LIST("sgent"); /* simple globs */
> > + AA_ENTRY_LIST("fent"); /* regular file entries */
> > +
> > + /* get the net entries */
> > + if (aa_is_nameX(e, AA_LIST, NULL, "net")) {
> > + error_string = "Invalid net entry";
> > + while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
> > + if (!aa_activate_net_entry(e))
> > + goto fail;
> > + }
> > + }
> > + rulename = "";
> > +
> > + /* get subprofiles */
> > + if (aa_is_nameX(e, AA_LIST, NULL, "hats")) {
> > + error_string = "Invalid profile hat";
> > + while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
> > + struct aaprofile *subprofile;
> > + subprofile = aa_activate_profile(e, error);
> > + if (!subprofile)
> > + goto fail;
> > + subprofile->parent = profile;
> > + list_add(&subprofile->list, &profile->sub);
> > + }
> > + }
> > +
> > + error_string = "Invalid end of profile";
> > + AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
> > +
> > + return profile;
>
> Is this kind of transltion neccessary?
Don't understand. Please expand/clarify. The code serializes the profile data
from userspace.
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-21 17:30 ` Chris Wright
@ 2006-04-21 18:07 ` Stephen Smalley
2006-04-21 20:06 ` Valdis.Kletnieks
2006-04-24 4:18 ` Neil Brown
0 siblings, 2 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-21 18:07 UTC (permalink / raw)
To: Chris Wright
Cc: James Morris, Arjan van de Ven, Andi Kleen, linux-kernel,
linux-security-module
On Fri, 2006-04-21 at 10:30 -0700, Chris Wright wrote:
> * Stephen Smalley (sds@tycho.nsa.gov) wrote:
> > Difficult to evaluate, when the answer whenever a flaw is pointed out is
> > "that's not in our threat model." Easy enough to have a protection
> > model match the threat model when the threat model is highly limited
> > (and never really documented anywhere, particularly in a way that might
> > warn its users of its limitations).
>
> I know, there's two questions. Whether the protection model is valid,
> and whether the threat model is worth considering. So far, I've not
> seen anything that's compelling enough to show AppArmor fundamentally
> broken. Ugly and inefficient, yes...broken, not yet.
Access control of any form requires unambiguous identification of
subjects and objects in the system. Paths don't achieve such
identification. Is that broken enough? If not, what is? What
qualifies as broken?
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 6/11] security: AppArmor - Userspace interface
2006-04-21 18:01 ` Tony Jones
@ 2006-04-21 18:41 ` Pavel Machek
0 siblings, 0 replies; 173+ messages in thread
From: Pavel Machek @ 2006-04-21 18:41 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
Hi!
> > > +/**
> > > + * aa_activate_profile - unpack a serialized profile
> > > + * @e: serialized data extent information
> > > + * @error: error code returned if unpacking fails
> > > + */
> > > +static struct aaprofile *aa_activate_profile(struct aa_ext *e, ssize_t *error)
> > > +{
> > > + struct aaprofile *profile = NULL;
> > > + const char *rulename = "";
> > > + const char *error_string = "Invalid Profile";
> > > +
> > > + *error = -EPROTO;
> > > +
> > > + profile = alloc_aaprofile();
> > > + if (!profile) {
> > > + error_string = "Could not allocate profile";
> > > + *error = -ENOMEM;
> > > + goto fail;
> > > + }
> > > +
> > > + /* check that we have the right struct being passed */
> > > + AA_READ_X(e, AA_STRUCT, NULL, "profile");
> > > + AA_READ_X(e, AA_DYN_STRING, &profile->name, NULL);
> > > +
> > > + error_string = "Invalid flags";
> > > + /* per profile debug flags (debug, complain, audit) */
> > > + AA_READ_X(e, AA_STRUCT, NULL, "flags");
> > > + AA_READ_X(e, AA_U32, &(profile->flags.debug), "profile.flags.debug");
> > > + AA_READ_X(e, AA_U32, &(profile->flags.complain),
> > > + "profile.flags.complain");
> > > + AA_READ_X(e, AA_U32, &(profile->flags.audit), "profile.flags.audit");
> > > + AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
> > > +
> > > + error_string = "Invalid capabilities";
> > > + AA_READ_X(e, AA_U32, &(profile->capabilities), "profile.capabilities");
> > > +
> > > + /* get the file entries. */
> > > + AA_ENTRY_LIST("pgent"); /* pcre rules */
> > > + AA_ENTRY_LIST("sgent"); /* simple globs */
> > > + AA_ENTRY_LIST("fent"); /* regular file entries */
> > > +
> > > + /* get the net entries */
> > > + if (aa_is_nameX(e, AA_LIST, NULL, "net")) {
> > > + error_string = "Invalid net entry";
> > > + while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
> > > + if (!aa_activate_net_entry(e))
> > > + goto fail;
> > > + }
> > > + }
> > > + rulename = "";
> > > +
> > > + /* get subprofiles */
> > > + if (aa_is_nameX(e, AA_LIST, NULL, "hats")) {
> > > + error_string = "Invalid profile hat";
> > > + while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
> > > + struct aaprofile *subprofile;
> > > + subprofile = aa_activate_profile(e, error);
> > > + if (!subprofile)
> > > + goto fail;
> > > + subprofile->parent = profile;
> > > + list_add(&subprofile->list, &profile->sub);
> > > + }
> > > + }
> > > +
> > > + error_string = "Invalid end of profile";
> > > + AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
> > > +
> > > + return profile;
> >
> > Is this kind of transltion neccessary?
>
> Don't understand. Please expand/clarify. The code serializes the profile data
> from userspace.
Yes, and it looks quite complex; would it be possible to get rid of
this serializing code? Could some existing infrastructure be used? One
file per value? Just pass the structure and make sure userspace is
matched to kernel? Something else?
Pavel
--
Thanks for all the (sleeping) penguins.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-21 18:07 ` Stephen Smalley
@ 2006-04-21 20:06 ` Valdis.Kletnieks
2006-04-21 20:35 ` Stephen Smalley
2006-04-24 4:18 ` Neil Brown
1 sibling, 1 reply; 173+ messages in thread
From: Valdis.Kletnieks @ 2006-04-21 20:06 UTC (permalink / raw)
To: Stephen Smalley
Cc: Chris Wright, James Morris, Arjan van de Ven, Andi Kleen,
linux-kernel, linux-security-module
[-- Attachment #1: Type: text/plain, Size: 1657 bytes --]
On Fri, 21 Apr 2006 14:07:33 EDT, Stephen Smalley said:
> On Fri, 2006-04-21 at 10:30 -0700, Chris Wright wrote:
> > * Stephen Smalley (sds@tycho.nsa.gov) wrote:
> > > Difficult to evaluate, when the answer whenever a flaw is pointed out is
> > > "that's not in our threat model." Easy enough to have a protection
> > > model match the threat model when the threat model is highly limited
> > > (and never really documented anywhere, particularly in a way that might
> > > warn its users of its limitations).
> >
> > I know, there's two questions. Whether the protection model is valid,
> > and whether the threat model is worth considering. So far, I've not
> > seen anything that's compelling enough to show AppArmor fundamentally
> > broken. Ugly and inefficient, yes...broken, not yet.
>
> Access control of any form requires unambiguous identification of
> subjects and objects in the system. Paths don't achieve such
> identification. Is that broken enough? If not, what is? What
> qualifies as broken?
I'd be willing to at least *listen* to an argument of the form "paths are
in general broken, but we have constraints X, Y, and Z on the system such
that the broken parts never manifest" (for instance, a restriction on
hardlinks that prevents hardlinking 2 files unless the resulting security
domains of the two paths would be identical).
However, I'll say up front that such an argument would only suffice to
move it from "broken" to "very brittle in face of changes" (for instance,
would such a hardlink restriction cause collateral damage that an attacker
could exploit? How badly does it fail in the face of a misdesigned policy?)
[-- Attachment #2: Type: application/pgp-signature, Size: 222 bytes --]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-21 20:06 ` Valdis.Kletnieks
@ 2006-04-21 20:35 ` Stephen Smalley
2006-04-21 20:44 ` Stephen Smalley
2006-04-21 21:38 ` Dave Neuer
0 siblings, 2 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-21 20:35 UTC (permalink / raw)
To: Valdis.Kletnieks
Cc: Chris Wright, James Morris, Arjan van de Ven, Andi Kleen,
linux-kernel, linux-security-module
On Fri, 2006-04-21 at 16:06 -0400, Valdis.Kletnieks@vt.edu wrote:
> On Fri, 21 Apr 2006 14:07:33 EDT, Stephen Smalley said:
> > On Fri, 2006-04-21 at 10:30 -0700, Chris Wright wrote:
> > > * Stephen Smalley (sds@tycho.nsa.gov) wrote:
> > > > Difficult to evaluate, when the answer whenever a flaw is pointed out is
> > > > "that's not in our threat model." Easy enough to have a protection
> > > > model match the threat model when the threat model is highly limited
> > > > (and never really documented anywhere, particularly in a way that might
> > > > warn its users of its limitations).
> > >
> > > I know, there's two questions. Whether the protection model is valid,
> > > and whether the threat model is worth considering. So far, I've not
> > > seen anything that's compelling enough to show AppArmor fundamentally
> > > broken. Ugly and inefficient, yes...broken, not yet.
> >
> > Access control of any form requires unambiguous identification of
> > subjects and objects in the system. Paths don't achieve such
> > identification. Is that broken enough? If not, what is? What
> > qualifies as broken?
>
> I'd be willing to at least *listen* to an argument of the form "paths are
> in general broken, but we have constraints X, Y, and Z on the system such
> that the broken parts never manifest" (for instance, a restriction on
> hardlinks that prevents hardlinking 2 files unless the resulting security
> domains of the two paths would be identical).
IIUC, AppArmor does impose such constraints, but only from the
perspective of an individual program's profile. Upon link(2), they
check that the program had link permission to the old link name and that
both the old link name and new link name have consistent permissions in
the profile, and they prohibit or limit by capability the ability to
manipulate the namespace by confined programs. But this doesn't mean
that another program running under a different profile can't create such
a link (if allowed to do so by its profile, of course), or that an
unconfined process cannot do so. There is no real "system policy" or
system-wide security properties with AppArmor; you can only look at it
in terms of individual programs (which themselves are identified by path
too).
> However, I'll say up front that such an argument would only suffice to
> move it from "broken" to "very brittle in face of changes" (for instance,
> would such a hardlink restriction cause collateral damage that an attacker
> could exploit? How badly does it fail in the face of a misdesigned policy?)
Indeed. I think Thomas Bleher made a good assessment of it in:
https://lists.ubuntu.com/archives/ubuntu-hardened/2006-March/000143.html
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-21 20:35 ` Stephen Smalley
@ 2006-04-21 20:44 ` Stephen Smalley
2006-04-21 21:38 ` Dave Neuer
1 sibling, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-21 20:44 UTC (permalink / raw)
To: Valdis.Kletnieks
Cc: Chris Wright, James Morris, Arjan van de Ven, Andi Kleen,
linux-kernel, linux-security-module
On Fri, 2006-04-21 at 16:35 -0400, Stephen Smalley wrote:
> On Fri, 2006-04-21 at 16:06 -0400, Valdis.Kletnieks@vt.edu wrote:
> > On Fri, 21 Apr 2006 14:07:33 EDT, Stephen Smalley said:
> > > On Fri, 2006-04-21 at 10:30 -0700, Chris Wright wrote:
> > > > * Stephen Smalley (sds@tycho.nsa.gov) wrote:
> > > > > Difficult to evaluate, when the answer whenever a flaw is pointed out is
> > > > > "that's not in our threat model." Easy enough to have a protection
> > > > > model match the threat model when the threat model is highly limited
> > > > > (and never really documented anywhere, particularly in a way that might
> > > > > warn its users of its limitations).
> > > >
> > > > I know, there's two questions. Whether the protection model is valid,
> > > > and whether the threat model is worth considering. So far, I've not
> > > > seen anything that's compelling enough to show AppArmor fundamentally
> > > > broken. Ugly and inefficient, yes...broken, not yet.
> > >
> > > Access control of any form requires unambiguous identification of
> > > subjects and objects in the system. Paths don't achieve such
> > > identification. Is that broken enough? If not, what is? What
> > > qualifies as broken?
> >
> > I'd be willing to at least *listen* to an argument of the form "paths are
> > in general broken, but we have constraints X, Y, and Z on the system such
> > that the broken parts never manifest" (for instance, a restriction on
> > hardlinks that prevents hardlinking 2 files unless the resulting security
> > domains of the two paths would be identical).
>
> IIUC, AppArmor does impose such constraints, but only from the
> perspective of an individual program's profile. Upon link(2), they
> check that the program had link permission to the old link name and that
> both the old link name and new link name have consistent permissions in
> the profile, and they prohibit or limit by capability the ability to
> manipulate the namespace by confined programs. But this doesn't mean
> that another program running under a different profile can't create such
> a link (if allowed to do so by its profile, of course), or that an
> unconfined process cannot do so. There is no real "system policy" or
> system-wide security properties with AppArmor; you can only look at it
> in terms of individual programs (which themselves are identified by path
> too).
Oh, and in the case, of links to programs (as opposed to data files),
the AppArmor folks have been known to encourage people to create
multiple hard links to a single program with different profiles as a way
of supporting multiple security domains for a single program, e.g.
creating multiple links to bash and using them as user shells to
establish different security domains for users.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 5/11] security: AppArmor - Filesystem
2006-04-19 17:49 ` [RFC][PATCH 5/11] security: AppArmor - Filesystem Tony Jones
@ 2006-04-21 21:13 ` Amy Griffis
0 siblings, 0 replies; 173+ messages in thread
From: Amy Griffis @ 2006-04-21 21:13 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
Tony Jones wrote: [Wed Apr 19 2006, 01:49:46PM EDT]
> This patch implements the AppArmor file structure underneath securityfs.
> Securityfs is normally mounted as /sys/kernel/security
>
> The following files are created under /sys/kernel/security/apparmor
> control
> audit - Controls the global setting for auditing all
> accesses.
> complain - Controls the global setting for learning mode
> (usually this is set per profile rather than
> globally)
> debug - Controls whether debugging is enabled.
> This needs to be made more fine grained
> logsyscall - Controls whether when logging to the audit
> subsystem full syscall auditing is enabled.
Why not use audit's audit_enabled toggle instead? This would
eliminate the overhead of data collection for syscall auditing, in
addition to eliminating the extra log data.
Is it likely that a user will want to keep syscall auditing on for
some applications, while having it disabled for AppArmor's use?
>
> The values by default for all of the above are 0.
>
> matching - Returns the features of the installed matching submodule
> profiles - Returns the profiles currently loaded and for each whether
> it is in complain (learning) or enforce mode.
> .load
> .remove
> .replace - Used by userspace tools to load, remove and replace new
> profiles.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 9/11] security: AppArmor - Audit changes
2006-04-19 17:50 ` [RFC][PATCH 9/11] security: AppArmor - Audit changes Tony Jones
@ 2006-04-21 21:21 ` Amy Griffis
2006-04-22 0:13 ` Steve Grubb
0 siblings, 1 reply; 173+ messages in thread
From: Amy Griffis @ 2006-04-21 21:21 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module, linux-audit
Tony Jones wrote: [Wed Apr 19 2006, 01:50:18PM EDT]
> This patch adds AppArmor support to the audit subsystem.
>
> It creates id 1500 (already included in the the upstream auditd package) for
> AppArmor messages.
>
> It also exports the audit_log_vformat function (analagous to having both
> printk and vprintk exported).
linux-audit (cc'd) will likely want to review these changes.
>
> Signed-off-by: Tony Jones <tonyj@suse.de>
>
> ---
> include/linux/audit.h | 5 +++++
> kernel/audit.c | 3 ++-
> 2 files changed, 7 insertions(+), 1 deletion(-)
>
> --- linux-2.6.17-rc1.orig/include/linux/audit.h
> +++ linux-2.6.17-rc1/include/linux/audit.h
> @@ -95,6 +95,8 @@
> #define AUDIT_LAST_KERN_ANOM_MSG 1799
> #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
>
> +#define AUDIT_AA 1500 /* AppArmor audit */
> +
> #define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
>
> /* Rule flags */
> @@ -349,6 +351,9 @@
> __attribute__((format(printf,4,5)));
>
> extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
> +extern void audit_log_vformat(struct audit_buffer *ab,
> + const char *fmt, va_list args)
> + __attribute__((format(printf,2,0)));
> extern void audit_log_format(struct audit_buffer *ab,
> const char *fmt, ...)
> __attribute__((format(printf,2,3)));
> --- linux-2.6.17-rc1.orig/kernel/audit.c
> +++ linux-2.6.17-rc1/kernel/audit.c
> @@ -797,7 +797,7 @@
> * will be called a second time. Currently, we assume that a printk
> * can't format message larger than 1024 bytes, so we don't either.
> */
> -static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
> +void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
> va_list args)
> {
> int len, avail;
> @@ -999,4 +999,5 @@
> EXPORT_SYMBOL(audit_log_start);
> EXPORT_SYMBOL(audit_log_end);
> EXPORT_SYMBOL(audit_log_format);
> +EXPORT_SYMBOL(audit_log_vformat);
> EXPORT_SYMBOL(audit_log);
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-21 20:35 ` Stephen Smalley
2006-04-21 20:44 ` Stephen Smalley
@ 2006-04-21 21:38 ` Dave Neuer
2006-04-22 10:01 ` Thomas Bleher
1 sibling, 1 reply; 173+ messages in thread
From: Dave Neuer @ 2006-04-21 21:38 UTC (permalink / raw)
To: Stephen Smalley
Cc: Valdis.Kletnieks, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On 4/21/06, Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
> IIUC, AppArmor does impose such constraints, but only from the
> perspective of an individual program's profile. Upon link(2), they
> check that the program had link permission to the old link name and that
> both the old link name and new link name have consistent permissions in
> the profile, and they prohibit or limit by capability the ability to
> manipulate the namespace by confined programs. But this doesn't mean
> that another program running under a different profile can't create such
> a link (if allowed to do so by its profile, of course), or that an
> unconfined process cannot do so. There is no real "system policy" or
> system-wide security properties with AppArmor; you can only look at it
> in terms of individual programs (which themselves are identified by path
> too).
>
> > However, I'll say up front that such an argument would only suffice to
> > move it from "broken" to "very brittle in face of changes" (for instance,
> > would such a hardlink restriction cause collateral damage that an attacker
> > could exploit? How badly does it fail in the face of a misdesigned policy?)
>
> Indeed. I think Thomas Bleher made a good assessment of it in:
> https://lists.ubuntu.com/archives/ubuntu-hardened/2006-March/000143.html
But what about Dr. Cowan's response at:
https://lists.ubuntu.com/archives/ubuntu-hardened/2006-March/000144.html
In particular, if you don't trust your users, why do you give them the
ability to create links?
Dave
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 9/11] security: AppArmor - Audit changes
2006-04-21 21:21 ` Amy Griffis
@ 2006-04-22 0:13 ` Steve Grubb
2006-04-22 0:19 ` Tony Jones
0 siblings, 1 reply; 173+ messages in thread
From: Steve Grubb @ 2006-04-22 0:13 UTC (permalink / raw)
To: linux-audit
Cc: Amy Griffis, Tony Jones, chrisw, linux-security-module,
linux-kernel
On Friday 21 April 2006 17:21, Amy Griffis wrote:
> linux-audit (cc'd) will likely want to review these changes.
Yes, I second that. Tony, please cc audit patches to linux-audit mail list so
we can see them. That said, I did tell Tony they could use message type
numbers 1500 - 1600 for AppArmor if they need it.
-Steve
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 9/11] security: AppArmor - Audit changes
2006-04-22 0:13 ` Steve Grubb
@ 2006-04-22 0:19 ` Tony Jones
0 siblings, 0 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-22 0:19 UTC (permalink / raw)
To: Steve Grubb
Cc: linux-audit, Amy Griffis, chrisw, linux-security-module,
linux-kernel
On Fri, Apr 21, 2006 at 08:13:52PM -0400, Steve Grubb wrote:
> On Friday 21 April 2006 17:21, Amy Griffis wrote:
> > linux-audit (cc'd) will likely want to review these changes.
>
> Yes, I second that. Tony, please cc audit patches to linux-audit mail list so
> we can see them. That said, I did tell Tony they could use message type
> numbers 1500 - 1600 for AppArmor if they need it.
Sorry, I thought I'd bounced this one patch in the series to the audit list.
I meant to. One more thing lost in the noise. Apologies.
1500 should already be reserved for apparmor userside. Only change is to
enable it kernelside plus of course the one more symbol export to bloat the
kernel image. Export of the vformat call is to make it analagous to vprintk.
Sometimes it's more convenient to have a single point of logging (as we do)
and you need to log data which is in va_list format.
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-21 21:38 ` Dave Neuer
@ 2006-04-22 10:01 ` Thomas Bleher
0 siblings, 0 replies; 173+ messages in thread
From: Thomas Bleher @ 2006-04-22 10:01 UTC (permalink / raw)
To: Dave Neuer
Cc: Stephen Smalley, Valdis.Kletnieks, Chris Wright, James Morris,
Arjan van de Ven, Andi Kleen, linux-kernel, linux-security-module
[-- Attachment #1: Type: text/plain, Size: 3266 bytes --]
* Dave Neuer <mr.fred.smoothie@pobox.com> [2006-04-21 23:41]:
> On 4/21/06, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> >
> > IIUC, AppArmor does impose such constraints, but only from the
> > perspective of an individual program's profile. Upon link(2), they
> > check that the program had link permission to the old link name and that
> > both the old link name and new link name have consistent permissions in
> > the profile, and they prohibit or limit by capability the ability to
> > manipulate the namespace by confined programs. But this doesn't mean
> > that another program running under a different profile can't create such
> > a link (if allowed to do so by its profile, of course), or that an
> > unconfined process cannot do so. There is no real "system policy" or
> > system-wide security properties with AppArmor; you can only look at it
> > in terms of individual programs (which themselves are identified by path
> > too).
> >
> > > However, I'll say up front that such an argument would only suffice to
> > > move it from "broken" to "very brittle in face of changes" (for instance,
> > > would such a hardlink restriction cause collateral damage that an attacker
> > > could exploit? How badly does it fail in the face of a misdesigned policy?)
> >
> > Indeed. I think Thomas Bleher made a good assessment of it in:
> > https://lists.ubuntu.com/archives/ubuntu-hardened/2006-March/000143.html
>
> But what about Dr. Cowan's response at:
> https://lists.ubuntu.com/archives/ubuntu-hardened/2006-March/000144.html
I didn't have time to answer his mail then, but I will try to do so now.
Mr. Cowan asserts that today Linux is used mainly as a single-user
machine or a dedicated network servers and that AppArmor is designed to
secure these.
For me, this is not enough, because I also need to secure multi-user
computers and I don't want to learn a new security mechanism for these
machines. (I worked several years as a system administrator for a
university where this was my main job).
But the more important point is that, IMO, AppArmor also fails to secure
e.g. dedicated network servers. Consider for example an Apache server
where users are allowed to install CGIs. How do you prevent an attacker
from subverting a buggy CGI and using the host to send spam?
(Hint: It's really easy using standard SELinux policy).
> In particular, if you don't trust your users, why do you give them the
> ability to create links?
Well, let's have a look at how Linux is used at e.g. university (that's
where I have the most experience). Lot's of untrusted students, doing
lots of weird things. They need to be allowed to run all sorts of
software, experiment with Linux, share files locally and so on. It's not
easy to confine such users.
On those machines, you don't care very much about individual users (if a
user is stupid enough to get his account hacked you just wipe his
homedir and restore from backup), but you do care about system integrity
and secrecy of things like /etc/shadow.
It is possible to confine such a system using SELinux (I've done it). Is
it possible using AppArmor? As far as I understood it is not. For me,
that's a severe limit in functionality.
Thomas
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 191 bytes --]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
` (12 preceding siblings ...)
2006-04-20 12:17 ` Stephen Smalley
@ 2006-04-22 12:27 ` Pavel Machek
13 siblings, 0 replies; 173+ messages in thread
From: Pavel Machek @ 2006-04-22 12:27 UTC (permalink / raw)
To: Tony Jones; +Cc: linux-kernel, chrisw, linux-security-module
Hi!
I must say that I do not like this code. I created something similar,
ptrace-based, long time ago. It was called subterfugue.sf.net, and it
was easy-to-use; but it was also very un-unixy, slow, and gross hack.
Unfortunately AA only fixes the 'slow' part by moving it to the
kernel.
> AppArmor mediates access to the file system using absolute path names
> with shell-syntax wildcards, so that "/srv/htdocs/** r" grants read
> access to all files in /srv/htdocs. AppArmor mediates access to POSIX.1e
shell-syntax-parser in kernel is not cool.
> AppArmor is strictly monotonic to security: it only restricts privilege,
> never enhancing privilege. So if you add AppArmor to a system, it only
> becomes more secure or stays the same, the security policy will not add
Not true, as sendmail hole showed long time ago. Error paths tend to
be untested, and AA is very capable of unmasking such bugs.
> AppArmor is *not* intended to protect every aspect of the system from
> every other aspect of the system: the intended usage is that only a
> small fraction of all programs on a Linux system will have AppArmor
> profiles. Rather, AppArmor is intended to protect the system against a
> particular threat.
If it is not scalable to whole system, why bother?
If it is only used for small part of system, why not use subterfugue?
Recently patches were proposed to improve ptrace performance a lot...
> Who Needs This?
> -------------------
> AppArmor is a core part of SUSE Linux.
It is part of suse linux, but I'd not call it core part.
Pavel
--
Thanks, Sharp!
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore
2006-04-21 5:10 ` Linda Walsh
@ 2006-04-23 12:11 ` Arjan van de Ven
0 siblings, 0 replies; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-23 12:11 UTC (permalink / raw)
To: Linda Walsh; +Cc: linux-kernel, Christoph Hellwig, linux-security-module
On Thu, 2006-04-20 at 22:10 -0700, Linda Walsh wrote:
> Chris Wright wrote:
> > * Linda A. Walsh (law@tlinx.org) wrote:
> >> "The *current* accepted way to get pathnames going into system
> >> calls is
> >> to put a trap in the syscall vector processing code to be indirectly
> >> called through the ptrace call with every system call as audit
> >> currently does..."?
> >>
> >> Or is that not correct either?
> > No it's not. See getname(9).
>
> I'm familiar with the getname call, it's probably the case that
> audit calls getname to do the actual copy from user->kernel space, I
> haven't checked. But I can't find the manpage you are referring to.
you CANNOT copy twice. If you copy twice you might as well not audit
since userspace can just change it inbetween. what audit does is use the
original ONE copy that the normal syscall does .
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-21 18:07 ` Stephen Smalley
2006-04-21 20:06 ` Valdis.Kletnieks
@ 2006-04-24 4:18 ` Neil Brown
2006-04-24 7:03 ` Theodore Ts'o
` (3 more replies)
1 sibling, 4 replies; 173+ messages in thread
From: Neil Brown @ 2006-04-24 4:18 UTC (permalink / raw)
To: Stephen Smalley
Cc: Chris Wright, James Morris, Arjan van de Ven, Andi Kleen,
linux-kernel, linux-security-module
On Friday April 21, sds@tycho.nsa.gov wrote:
> On Fri, 2006-04-21 at 10:30 -0700, Chris Wright wrote:
> > * Stephen Smalley (sds@tycho.nsa.gov) wrote:
> > > Difficult to evaluate, when the answer whenever a flaw is pointed out is
> > > "that's not in our threat model." Easy enough to have a protection
> > > model match the threat model when the threat model is highly limited
> > > (and never really documented anywhere, particularly in a way that might
> > > warn its users of its limitations).
> >
> > I know, there's two questions. Whether the protection model is valid,
> > and whether the threat model is worth considering. So far, I've not
> > seen anything that's compelling enough to show AppArmor fundamentally
> > broken. Ugly and inefficient, yes...broken, not yet.
>
> Access control of any form requires unambiguous identification of
> subjects and objects in the system. Paths don't achieve such
> identification. Is that broken enough? If not, what is? What
> qualifies as broken?
I have to disagree with this. Paths *do* achieve unambiguous
identification of something. That something is ..... the path.
Think about the name of this system for a minute. "AppArmor".
i.e. it is Armour for an Application. It protects the application.
It doesn't (as far as I can tell: I'm not an expert and don't work on
this thing) claim to protect files. It protects applications.
It protects them from doing the wrong thing - from doing something
they weren't designed to do. i.e. it protects them from being
subverted by exploiting a bug.
A large part of the behaviour of an application is the path names that
it uses and what it does with them. If an application started doing
unexpected things with unexpected paths (e.g. exec("/bin/sh") or
open("/etc/shadow",O_RDONLY)) then this is a sure sign that it has
been subverted and that AppArmor need to protect it, from itself.
Obviously the protection will not be complete. The profiles describe
what the application is expected to do, and to some extent, this
description will be in general terms. It might identify files that
can be written to, but not what will be written to them. etc.
While the protection against subversion cannot be complete, it can be
sufficient to dramatically reduce the chances of privilege
escalation. There are lots of wrong things you can get an
application to do once you find an exploitable bug. Many of these
will lead to a crash. AppArmor will not try to protect against these
(I suspect). There are substantially fewer that lead to privilege
escalation. AppArmor focusses its effort in terms of profile design
on exactly these sorts of unplanned behaviours.
So I think you still haven't given convincing evidence that AppArmor
is broken by design.
NeilBrown
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 4:18 ` Neil Brown
@ 2006-04-24 7:03 ` Theodore Ts'o
2006-04-24 13:04 ` Pavel Machek
2006-04-24 21:07 ` Stephen Smalley
2006-04-24 7:14 ` Arjan van de Ven
` (2 subsequent siblings)
3 siblings, 2 replies; 173+ messages in thread
From: Theodore Ts'o @ 2006-04-24 7:03 UTC (permalink / raw)
To: Neil Brown
Cc: Stephen Smalley, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On Mon, Apr 24, 2006 at 02:18:50PM +1000, Neil Brown wrote:
> Think about the name of this system for a minute. "AppArmor".
> i.e. it is Armour for an Application. It protects the application.
> It doesn't (as far as I can tell: I'm not an expert and don't work on
> this thing) claim to protect files. It protects applications.
...
> While the protection against subversion cannot be complete, it can be
> sufficient to dramatically reduce the chances of privilege
> escalation. There are lots of wrong things you can get an
> application to do once you find an exploitable bug. Many of these
> will lead to a crash. AppArmor will not try to protect against these
> (I suspect). There are substantially fewer that lead to privilege
> escalation. AppArmor focusses its effort in terms of profile design
> on exactly these sorts of unplanned behaviours.
>
> So I think you still haven't given convincing evidence that AppArmor
> is broken by design.
I have to agree with Neil here. I spent over 10 years doing network
security as my day job, including chairing the IP Security working
group and being a member of the IETF Security Area Directorate, before
switching over to Linux as the thing that would pay the bills, and I
can state quite authoratatively that perfect security which is never
used because it's too hard to install, maintain, and configure, isn't
worth much compared to imperfect security which is easy enough such
that users always use it by default.
The goal of protecting against broken, buggy applications is a worthy
one. If people can show that for a large set of stack overruns, or
other types of buggy applications, it is possible to evade AppArmor by
doing something clever, then AppArmor would need to be fixed or it's
not worth doing. But if it can prevent a large class of buggy
applications from allowing an atttacker to escalate that bugginess
into a system penetration, then it has added value.
In the security world, there is a huge tradition of the best being the
enemy of the good --- and the best being so painful to use that people
don't want to use it, or the moment it gets in the way (either because
of performance reasons or their application does something that
requires painful configuration of the SELinux policy files), they
deconfigure it. At which point the "best" becomes useless.
You may or may not agree with the philosophical architecture question,
but that doesn't necessarily make it "broken by design". Choice is
good; if AppArmor forces SELinux to become less painful to use and
configure, then that in the long run will be a good thing.
- Ted
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 4:18 ` Neil Brown
2006-04-24 7:03 ` Theodore Ts'o
@ 2006-04-24 7:14 ` Arjan van de Ven
2006-04-24 8:11 ` Lars Marowsky-Bree
2006-04-25 19:27 ` Seth Arnold
2006-04-24 13:11 ` Joshua Brindle
2006-04-24 20:45 ` Stephen Smalley
3 siblings, 2 replies; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-24 7:14 UTC (permalink / raw)
To: Neil Brown
Cc: Stephen Smalley, Chris Wright, James Morris, Andi Kleen,
linux-kernel, linux-security-module
> A large part of the behaviour of an application is the path names that
> it uses and what it does with them. If an application started doing
> unexpected things with unexpected paths (e.g. exec("/bin/sh") or
> open("/etc/shadow",O_RDONLY)) then this is a sure sign that it has
> been subverted and that AppArmor need to protect it, from itself.
does apparmor at least (offer) to kill the app when this happens?
(rationale: the app is hijacked, better kill it before it goes to do
damage)
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 7:14 ` Arjan van de Ven
@ 2006-04-24 8:11 ` Lars Marowsky-Bree
2006-04-25 19:27 ` Seth Arnold
1 sibling, 0 replies; 173+ messages in thread
From: Lars Marowsky-Bree @ 2006-04-24 8:11 UTC (permalink / raw)
To: Arjan van de Ven, Neil Brown
Cc: Stephen Smalley, Chris Wright, James Morris, Andi Kleen,
linux-kernel, linux-security-module
On 2006-04-24T09:14:58, Arjan van de Ven <arjan@infradead.org> wrote:
> does apparmor at least (offer) to kill the app when this happens?
> (rationale: the app is hijacked, better kill it before it goes to do
> damage)
Heh, that was just my question to Crispin this morning, because that's
what I'd prefer too.
Not just for security, but simply because experience shows that error
paths are not well auditted in general; even if it doesn't cause
privilege escalation, I prefer if it doesn't shred the data it is
allowed to access by hitting a misconfiguration in my profile...
--
High Availability & Clustering
SUSE Labs, Research and Development
SUSE LINUX Products GmbH - A Novell Business -- Charles Darwin
"Ignorance more frequently begets confidence than does knowledge"
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-20 13:00 ` grundig
2006-04-20 13:09 ` Serge E. Hallyn
@ 2006-04-24 13:01 ` Alan Cox
1 sibling, 0 replies; 173+ messages in thread
From: Alan Cox @ 2006-04-24 13:01 UTC (permalink / raw)
To: grundig
Cc: Crispin Cowan, ak, arjan, linux-kernel, chrisw,
linux-security-module
On Iau, 2006-04-20 at 15:00 +0200, grundig wrote:
> Wouldn't have more sense to improve it and then submit it instead of the
> contrary?
Submitting it is very useful. It allows everyone to see what is involved
in knocking it into shape and to ask useful questions like 'does LSM
need to pass more/differing information'.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 7:03 ` Theodore Ts'o
@ 2006-04-24 13:04 ` Pavel Machek
2006-04-24 13:43 ` Joshua Brindle
2006-04-24 21:07 ` Stephen Smalley
1 sibling, 1 reply; 173+ messages in thread
From: Pavel Machek @ 2006-04-24 13:04 UTC (permalink / raw)
To: Theodore Ts'o, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, Arjan van de Ven, Andi Kleen, linux-kernel,
linux-security-module
> In the security world, there is a huge tradition of the best being the
> enemy of the good --- and the best being so painful to use that people
> don't want to use it, or the moment it gets in the way (either because
> of performance reasons or their application does something that
> requires painful configuration of the SELinux policy files), they
> deconfigure it. At which point the "best" becomes useless.
>
> You may or may not agree with the philosophical architecture question,
> but that doesn't necessarily make it "broken by design". Choice is
> good; if AppArmor forces SELinux to become less painful to use and
> configure, then that in the long run will be a good thing.
SELinux kernel support can _almost_ do what AA does; with notable
exception of labels for new files. That can probably be fixed with
patch of reasonable size (or maybe even with LD_PRELOAD library, glibc
modification, or stuff like that). (There was post showing that in
this long flamewar).
That way you can have SELinux that works on AA config files.
(I still dislike path-based security, but labeling patch can probably
be useful for other stuff, too.)
Pavel
--
Thanks for all the (sleeping) penguins.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path
2006-04-20 5:36 ` Tony Jones
2006-04-20 8:26 ` Arjan van de Ven
@ 2006-04-24 13:05 ` Alan Cox
1 sibling, 0 replies; 173+ messages in thread
From: Alan Cox @ 2006-04-24 13:05 UTC (permalink / raw)
To: Tony Jones; +Cc: Christoph Hellwig, linux-kernel, chrisw, linux-security-module
On Mer, 2006-04-19 at 22:36 -0700, Tony Jones wrote:
> "system root". When a task chroots relative to it's current namespace, we
> are interested in the path back to the root of that namespace, rather than
> to the chroot. I believe the patch as stands achieves this, albeit with
> some changing of comments.
If the directory the task is in has been deleted then what is its path
relative to the namespace ? This isn't theoretical because if your
security profiles work on the basis of this path but do not prevent the
deletion of the current directory or some node above it (or doing
mkdir/chdir/rmdir sequences) an app may be able to subvert it by doing
this deliberately.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 4:18 ` Neil Brown
2006-04-24 7:03 ` Theodore Ts'o
2006-04-24 7:14 ` Arjan van de Ven
@ 2006-04-24 13:11 ` Joshua Brindle
2006-04-24 13:26 ` Andi Kleen
2006-04-24 20:45 ` Stephen Smalley
3 siblings, 1 reply; 173+ messages in thread
From: Joshua Brindle @ 2006-04-24 13:11 UTC (permalink / raw)
To: Neil Brown
Cc: Stephen Smalley, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
Neil Brown wrote:
> On Friday April 21, sds@tycho.nsa.gov wrote:
>>
>> Access control of any form requires unambiguous identification of
>> subjects and objects in the system. Paths don't achieve such
>> identification. Is that broken enough? If not, what is? What
>> qualifies as broken?
>>
>
> I have to disagree with this. Paths *do* achieve unambiguous
> identification of something. That something is ..... the path.
>
>
On the contrary. Due to namespaces a single path can describe many
different files, depending on the namespace you are in. Same with
chroots, if an app that is chrooted can read /etc/shadow it can also
read it outside the chroot. Even if this weren't the case the path isn't
the object. Objects are 'things' being acted upon by a subject. A path
is merely an address to an object. A burglar might use your address to
get to your house but in the end it's your house he's robbing, not the
address.
> Think about the name of this system for a minute. "AppArmor".
> i.e. it is Armour for an Application. It protects the application.
> It doesn't (as far as I can tell: I'm not an expert and don't work on
> this thing) claim to protect files. It protects applications.
>
A large part of protecting applications is protecting which apps can
interact with those applications, directly or indirectly. Without the
ability to look at the policy and know if its actually doing what you
think it is (which you can't with path based access control) you have no
way of telling whether an application is actually protected. This leads
to false sense of security.
Another large part of protecting applications is protecting the system
which supports them. The apparmor crowd will claim that these apps are
trusted but there are many ways a confined application can indirectly
influence an unconfined application and most privilege escalation
attacks are multi-step already thus buying little.
> It protects them from doing the wrong thing - from doing something
> they weren't designed to do. i.e. it protects them from being
> subverted by exploiting a bug.
>
> A large part of the behaviour of an application is the path names that
> it uses and what it does with them. If an application started doing
> unexpected things with unexpected paths (e.g. exec("/bin/sh") or
> open("/etc/shadow",O_RDONLY)) then this is a sure sign that it has
> been subverted and that AppArmor need to protect it, from itself.
>
>
Sure but if, instead, it's able to open /var/chroot/etc/shadow which is
a hardlink to /etc/shadow you've bought nothing. You may filter out
worms and script kiddies this way but in the end you are using obscurity
(of filesystem layout, what the policy allows, how the apps are
configured, etc) for security, which again, leads to a false sense of
security.
> Obviously the protection will not be complete. The profiles describe
> what the application is expected to do, and to some extent, this
> description will be in general terms. It might identify files that
> can be written to, but not what will be written to them. etc.
>
> While the protection against subversion cannot be complete, it can be
> sufficient to dramatically reduce the chances of privilege
> escalation. There are lots of wrong things you can get an
> application to do once you find an exploitable bug. Many of these
> will lead to a crash. AppArmor will not try to protect against these
> (I suspect). There are substantially fewer that lead to privilege
> escalation. AppArmor focusses its effort in terms of profile design
> on exactly these sorts of unplanned behaviours.
>
>
It only reduces the chance to inexperienced and/or lazy hackers ;) . It
wouldn't take someone experienced to figure out that you have apparmor
running on the system and thus know how to break/bypass it. Once again,
false sense of security.
> So I think you still haven't given convincing evidence that AppArmor
> is broken by design.
>
I haven't heard any responses to any of the ~11ish points brought up at
http://securityblog.org/brindle/2006/04/19/security-anti-pattern-path-based-access-control/
. Its very long but I can paste it into an email if necessary.
In particular I'd love to hear about how Apparmor is so easy to use,
considering the apparmor crowd advocates things like making hardlinks to
/bin/bash and setting that new path to a 'restricted' users login shell.
This is not obvious, secure, scalable or intuitive. I'd hope most
administrators recognize the severe limitations of this 'solution' and
opt for something stronger.
Joshua Brindle
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 13:11 ` Joshua Brindle
@ 2006-04-24 13:26 ` Andi Kleen
2006-04-24 13:39 ` Joshua Brindle
2006-04-24 13:52 ` Alan Cox
0 siblings, 2 replies; 173+ messages in thread
From: Andi Kleen @ 2006-04-24 13:26 UTC (permalink / raw)
To: Joshua Brindle
Cc: Neil Brown, Stephen Smalley, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Monday 24 April 2006 15:11, Joshua Brindle wrote:
> Sure but if, instead, it's able to open /var/chroot/etc/shadow which is
> a hardlink to /etc/shadow you've bought nothing. You may filter out
> worms and script kiddies this way but in the end you are using obscurity
> (of filesystem layout, what the policy allows, how the apps are
> configured, etc) for security, which again, leads to a false sense of
> security.
AppArmor disallows both chroot and name space changes for the constrained
application so the scenario you're describing cannot happen. What happens
with unconstrained applications it doesn't care about by design.
This has been covered several times in this thread already - please pay
more attention.
-Andi
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 13:26 ` Andi Kleen
@ 2006-04-24 13:39 ` Joshua Brindle
2006-04-24 15:16 ` Joshua Brindle
2006-04-24 13:52 ` Alan Cox
1 sibling, 1 reply; 173+ messages in thread
From: Joshua Brindle @ 2006-04-24 13:39 UTC (permalink / raw)
To: Andi Kleen
Cc: Neil Brown, Stephen Smalley, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
Andi Kleen wrote:
> On Monday 24 April 2006 15:11, Joshua Brindle wrote:
>
>
>> Sure but if, instead, it's able to open /var/chroot/etc/shadow which is
>> a hardlink to /etc/shadow you've bought nothing. You may filter out
>> worms and script kiddies this way but in the end you are using obscurity
>> (of filesystem layout, what the policy allows, how the apps are
>> configured, etc) for security, which again, leads to a false sense of
>> security.
>>
>
> AppArmor disallows both chroot and name space changes for the constrained
> application so the scenario you're describing cannot happen. What happens
> with unconstrained applications it doesn't care about by design.
>
> This has been covered several times in this thread already - please pay
> more attention.
I was paying attention, thank you. Can apparmor force an application to
only start within a certain chroot? So it may not be able to chroot
during runtime but if you can't be sure that it starts in the chroot the
argument still applies. Particularly since the app may not even fail to
run outside the chroot given that it will have access to all the same
libraries, etc it did inside (due to the paths being the same).
Joshua
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 13:04 ` Pavel Machek
@ 2006-04-24 13:43 ` Joshua Brindle
0 siblings, 0 replies; 173+ messages in thread
From: Joshua Brindle @ 2006-04-24 13:43 UTC (permalink / raw)
To: Pavel Machek
Cc: Theodore Ts'o, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, Arjan van de Ven, Andi Kleen, linux-kernel,
linux-security-module
Pavel Machek wrote:
>> In the security world, there is a huge tradition of the best being the
>> enemy of the good --- and the best being so painful to use that people
>> don't want to use it, or the moment it gets in the way (either because
>> of performance reasons or their application does something that
>> requires painful configuration of the SELinux policy files), they
>> deconfigure it. At which point the "best" becomes useless.
>>
>> You may or may not agree with the philosophical architecture question,
>> but that doesn't necessarily make it "broken by design". Choice is
>> good; if AppArmor forces SELinux to become less painful to use and
>> configure, then that in the long run will be a good thing.
>>
>
> SELinux kernel support can _almost_ do what AA does; with notable
> exception of labels for new files. That can probably be fixed with
> patch of reasonable size (or maybe even with LD_PRELOAD library, glibc
> modification, or stuff like that). (There was post showing that in
> this long flamewar).
>
New file labels based on path should not be addressed in the kernel and
LD_PRELOAD would be incredibly hacky. Our solution to the problem is
restorecond (http://danwalsh.livejournal.com/4368.html) which addresses
users who want to be able to mkdir public_html and immediately use it.
Userland solutions like this will make SELinux easier and easier to use,
and they already have. Anyone not keeping up with SELinux lately a
tremendous amount has been done in the area of usability as outlined at
this years selinux symposium
(http://selinux-symposium.org/2006/slides/01-smalley-yir.pdf).
Joshua
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 13:26 ` Andi Kleen
2006-04-24 13:39 ` Joshua Brindle
@ 2006-04-24 13:52 ` Alan Cox
2006-04-24 14:09 ` Andi Kleen
1 sibling, 1 reply; 173+ messages in thread
From: Alan Cox @ 2006-04-24 13:52 UTC (permalink / raw)
To: Andi Kleen
Cc: Joshua Brindle, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
On Llu, 2006-04-24 at 15:26 +0200, Andi Kleen wrote:
> On Monday 24 April 2006 15:11, Joshua Brindle wrote:
>
> > Sure but if, instead, it's able to open /var/chroot/etc/shadow which is
> > a hardlink to /etc/shadow you've bought nothing. You may filter out
> > worms and script kiddies this way but in the end you are using obscurity
> > (of filesystem layout, what the policy allows, how the apps are
> > configured, etc) for security, which again, leads to a false sense of
> > security.
>
> AppArmor disallows both chroot and name space changes for the constrained
> application so the scenario you're describing cannot happen. What happens
> with unconstrained applications it doesn't care about by design.
>
> This has been covered several times in this thread already - please pay
> more attention.
There is a much simpler answer anyway, sit in a loop trying to
open /etc/shadow~ and wait for someone to change password. All the
problems about names remain because of links anyway.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 13:52 ` Alan Cox
@ 2006-04-24 14:09 ` Andi Kleen
0 siblings, 0 replies; 173+ messages in thread
From: Andi Kleen @ 2006-04-24 14:09 UTC (permalink / raw)
To: Alan Cox
Cc: Joshua Brindle, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
On Monday 24 April 2006 15:52, Alan Cox wrote:
> There is a much simpler answer anyway, sit in a loop trying to
> open /etc/shadow~ and wait for someone to change password. All the
> problems about names remain because of links anyway.
AFAIK AA avoids this problem by only allowing access to files, not forbidding
access. So unless you put /etc/shadow~ (or /etc/*) into the profile
this cannot happen.
Instead you would list the files that application is allowed to access.
-Andi
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 13:39 ` Joshua Brindle
@ 2006-04-24 15:16 ` Joshua Brindle
2006-04-24 15:50 ` Tony Jones
2006-04-25 17:12 ` Valdis.Kletnieks
0 siblings, 2 replies; 173+ messages in thread
From: Joshua Brindle @ 2006-04-24 15:16 UTC (permalink / raw)
To: Joshua Brindle
Cc: Andi Kleen, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
Joshua Brindle wrote:
> Andi Kleen wrote:
>> On Monday 24 April 2006 15:11, Joshua Brindle wrote:
>>
>>
>>> Sure but if, instead, it's able to open /var/chroot/etc/shadow which
>>> is a hardlink to /etc/shadow you've bought nothing. You may filter
>>> out worms and script kiddies this way but in the end you are using
>>> obscurity (of filesystem layout, what the policy allows, how the
>>> apps are configured, etc) for security, which again, leads to a
>>> false sense of security.
>>>
>>
>> AppArmor disallows both chroot and name space changes for the
>> constrained
>> application so the scenario you're describing cannot happen. What
>> happens
>> with unconstrained applications it doesn't care about by design.
>>
>> This has been covered several times in this thread already - please pay
>> more attention.
> I was paying attention, thank you. Can apparmor force an application
> to only start within a certain chroot? So it may not be able to chroot
> during runtime but if you can't be sure that it starts in the chroot
> the argument still applies. Particularly since the app may not even
> fail to run outside the chroot given that it will have access to all
> the same libraries, etc it did inside (due to the paths being the same).
To make this much more real, the /usr/sbin/named policy that ships with
apparmor has the following line:
/** r,
Thats right, named can read any file on the system, I suppose this is
because the policy relies on named being chrooted. So if for any reason
named doesn't chroot its been granted read access on the entire
filesystem. If I'm misunderstanding this policy please correct me but I
believe this shows the problem very loudly and clearly.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 15:16 ` Joshua Brindle
@ 2006-04-24 15:50 ` Tony Jones
2006-04-24 17:03 ` Joshua Brindle
2006-04-25 17:12 ` Valdis.Kletnieks
1 sibling, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-24 15:50 UTC (permalink / raw)
To: Joshua Brindle
Cc: Andi Kleen, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
On Mon, Apr 24, 2006 at 11:16:25AM -0400, Joshua Brindle wrote:
> To make this much more real, the /usr/sbin/named policy that ships with
> apparmor has the following line:
Ships with AppArmor where? On SuSE?
> /** r,
> Thats right, named can read any file on the system, I suppose this is
> because the policy relies on named being chrooted. So if for any reason
> named doesn't chroot its been granted read access on the entire
> filesystem. If I'm misunderstanding this policy please correct me but I
> believe this shows the problem very loudly and clearly.
The d_path changes for absolute path mediation for chroot are not yet in any
SuSE release. Nor are they reflected in any developed profiles (yet).
Another direction is a new security_chroot hook together with appropriate
CLONE_FS tracking (inside AppArmor) to force chrooting confined tasks into a
subprofile (similar to change hat). We are evaluating the options based on
feedback here and from other places. Hence the RFC.
I hope this helps.
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 15:50 ` Tony Jones
@ 2006-04-24 17:03 ` Joshua Brindle
0 siblings, 0 replies; 173+ messages in thread
From: Joshua Brindle @ 2006-04-24 17:03 UTC (permalink / raw)
To: Tony Jones
Cc: Andi Kleen, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
Tony Jones wrote:
> On Mon, Apr 24, 2006 at 11:16:25AM -0400, Joshua Brindle wrote:
>
>> To make this much more real, the /usr/sbin/named policy that ships with
>> apparmor has the following line:
>>
>
> Ships with AppArmor where? On SuSE?
>
apparmor-profiles-2.0.tar.gz available on the novell forge.
>
>> /** r,
>> Thats right, named can read any file on the system, I suppose this is
>> because the policy relies on named being chrooted. So if for any reason
>> named doesn't chroot its been granted read access on the entire
>> filesystem. If I'm misunderstanding this policy please correct me but I
>> believe this shows the problem very loudly and clearly.
>>
>
> The d_path changes for absolute path mediation for chroot are not yet in any
> SuSE release. Nor are they reflected in any developed profiles (yet).
>
>
So you are currently not protecting this access vector and it was said
pretty clearly that this patch wouldn't make it into mainline. I don't
understand how you intend to address this. Are people running different
distros out of luck with regard to Apparmor?
> Another direction is a new security_chroot hook together with appropriate
> CLONE_FS tracking (inside AppArmor) to force chrooting confined tasks into a
> subprofile (similar to change hat). We are evaluating the options based on
> feedback here and from other places. Hence the RFC.
>
> I hope this helps
Thats fine, what about private namespaces, which are better than chroots
anyway in terms of flexibility. Are you going to be able to specify the
precise namespace that an app may use in order to use these policies?
By the way, the fact that there is such a rule in the policy isn't the
problem, its a symptom of the problem. All of these 'fixes' seem to be
band-aiding the symptoms. Aren't these alot of hoops to jump through for
the sake of using paths?
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 4:18 ` Neil Brown
` (2 preceding siblings ...)
2006-04-24 13:11 ` Joshua Brindle
@ 2006-04-24 20:45 ` Stephen Smalley
2006-04-25 8:10 ` Neil Brown
3 siblings, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-24 20:45 UTC (permalink / raw)
To: Neil Brown
Cc: Chris Wright, James Morris, Arjan van de Ven, Andi Kleen,
linux-kernel, linux-security-module
On Mon, 2006-04-24 at 14:18 +1000, Neil Brown wrote:
> On Friday April 21, sds@tycho.nsa.gov wrote:
> > On Fri, 2006-04-21 at 10:30 -0700, Chris Wright wrote:
> > > * Stephen Smalley (sds@tycho.nsa.gov) wrote:
> > > > Difficult to evaluate, when the answer whenever a flaw is pointed out is
> > > > "that's not in our threat model." Easy enough to have a protection
> > > > model match the threat model when the threat model is highly limited
> > > > (and never really documented anywhere, particularly in a way that might
> > > > warn its users of its limitations).
> > >
> > > I know, there's two questions. Whether the protection model is valid,
> > > and whether the threat model is worth considering. So far, I've not
> > > seen anything that's compelling enough to show AppArmor fundamentally
> > > broken. Ugly and inefficient, yes...broken, not yet.
> >
> > Access control of any form requires unambiguous identification of
> > subjects and objects in the system. Paths don't achieve such
> > identification. Is that broken enough? If not, what is? What
> > qualifies as broken?
>
> I have to disagree with this. Paths *do* achieve unambiguous
> identification of something. That something is ..... the path.
A path is not an object; it is a way of referring to an object. No need
to reason about this abstractly - just look at the kernel's internal
model; where are these mystical path objects and how are they
implemented? And as a way of referring to an object, paths are
ambiguous identifiers. Further, that ambiguity is leveraged by AppArmor
to e.g. support multiple profiles for the same program via alternate
paths.
> Think about the name of this system for a minute. "AppArmor".
> i.e. it is Armour for an Application. It protects the application.
> It doesn't (as far as I can tell: I'm not an expert and don't work on
> this thing) claim to protect files. It protects applications.
>From the AppArmor overview on the novellforge page:
"AppArmor security policies completely define what system resources
individual applications can access..."
>From the AppArmor FAQ:
"AppArmor profiles are human-readable text files that mediate access to
files and directories..."
Isn't that claiming to protect files? If not, please make sure the end
user documentation clearly says "AppArmor is not designed to protect
files."
> It protects them from doing the wrong thing - from doing something
> they weren't designed to do. i.e. it protects them from being
> subverted by exploiting a bug.
>
> A large part of the behaviour of an application is the path names that
> it uses and what it does with them. If an application started doing
> unexpected things with unexpected paths (e.g. exec("/bin/sh") or
> open("/etc/shadow",O_RDONLY)) then this is a sure sign that it has
> been subverted and that AppArmor need to protect it, from itself.
Um, no. You are trying to protect the rest of the system from
misbehavior by the application. You aren't protecting the application
at all - you have already said it has been subverted, and it is then
free to corrupt or leak any information it normally has legitimate
access to. And since you don't care about information flow, you can't
actually guarantee that the rest of the system isn't corrupted by the
application misbehavior; any of your unconfined processes may become the
conduit by which the corruption spills over into the rest of the system.
> While the protection against subversion cannot be complete, it can be
> sufficient to dramatically reduce the chances of privilege
> escalation. There are lots of wrong things you can get an
> application to do once you find an exploitable bug. Many of these
> will lead to a crash. AppArmor will not try to protect against these
> (I suspect). There are substantially fewer that lead to privilege
> escalation. AppArmor focusses its effort in terms of profile design
> on exactly these sorts of unplanned behaviours.
I don't see how it achieves such prevention with the limitations I've
already noted, which are design limitations, not just characteristics of
the implementation.
> So I think you still haven't given convincing evidence that AppArmor
> is broken by design.
If it isn't, then is anyone and everyone free to introduce other
path-based mechanisms in the kernel in the future? Why has that been
frowned upon in the past if there really isn't anything wrong with it?
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 7:03 ` Theodore Ts'o
2006-04-24 13:04 ` Pavel Machek
@ 2006-04-24 21:07 ` Stephen Smalley
2006-04-24 23:52 ` Theodore Ts'o
2006-04-25 4:25 ` Casey Schaufler
1 sibling, 2 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-24 21:07 UTC (permalink / raw)
To: Theodore Ts'o
Cc: Neil Brown, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On Mon, 2006-04-24 at 03:03 -0400, Theodore Ts'o wrote:
> I have to agree with Neil here. I spent over 10 years doing network
> security as my day job, including chairing the IP Security working
> group and being a member of the IETF Security Area Directorate, before
> switching over to Linux as the thing that would pay the bills, and I
> can state quite authoratatively that perfect security which is never
> used because it's too hard to install, maintain, and configure, isn't
> worth much compared to imperfect security which is easy enough such
> that users always use it by default.
Seems like a strawman. We aren't claiming that SELinux is perfect, and
there is plenty of work ongoing on SELinux usability. But a
fundamentally unsound mechanism is more dangerous than one that is never
enabled; at least in the latter case, one knows where one stands. It is
the illusory sense of security that accompanies path-based access
control that is dangerous. You don't have to be an SELinux advocate to
see the problems with a path-based kernel access control mechanism.
> The goal of protecting against broken, buggy applications is a worthy
> one. If people can show that for a large set of stack overruns, or
> other types of buggy applications, it is possible to evade AppArmor by
> doing something clever, then AppArmor would need to be fixed or it's
> not worth doing. But if it can prevent a large class of buggy
> applications from allowing an atttacker to escalate that bugginess
> into a system penetration, then it has added value.
Does it have any hope of stopping an attacker who has designed his
attack with full knowledge of AppArmor's design and implementation (no
security through obscurity)?
> In the security world, there is a huge tradition of the best being the
> enemy of the good --- and the best being so painful to use that people
> don't want to use it, or the moment it gets in the way (either because
> of performance reasons or their application does something that
> requires painful configuration of the SELinux policy files), they
> deconfigure it. At which point the "best" becomes useless.
>
> You may or may not agree with the philosophical architecture question,
> but that doesn't necessarily make it "broken by design". Choice is
> good; if AppArmor forces SELinux to become less painful to use and
> configure, then that in the long run will be a good thing.
The problems with path-based mechanisms are technical in nature, not
just philosophical.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 21:07 ` Stephen Smalley
@ 2006-04-24 23:52 ` Theodore Ts'o
2006-04-25 6:22 ` Arjan van de Ven
2006-04-25 16:45 ` Stephen Smalley
2006-04-25 4:25 ` Casey Schaufler
1 sibling, 2 replies; 173+ messages in thread
From: Theodore Ts'o @ 2006-04-24 23:52 UTC (permalink / raw)
To: Stephen Smalley
Cc: Neil Brown, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On Mon, Apr 24, 2006 at 05:07:56PM -0400, Stephen Smalley wrote:
> > The goal of protecting against broken, buggy applications is a worthy
> > one. If people can show that for a large set of stack overruns, or
> > other types of buggy applications, it is possible to evade AppArmor by
> > doing something clever, then AppArmor would need to be fixed or it's
> > not worth doing. But if it can prevent a large class of buggy
> > applications from allowing an atttacker to escalate that bugginess
> > into a system penetration, then it has added value.
>
> Does it have any hope of stopping an attacker who has designed his
> attack with full knowledge of AppArmor's design and implementation (no
> security through obscurity)?
Well, it also depends on your threat model, right? What capabilities
are you assuming the attacker will have? Does the attacker have an
account on the system? Or has the attacker just exploited a stack
overrun in a network daemon, or a failure to check some input field
coming from the network, and the goal is to stop the attacker from
escalating that to gaining full root privs on the system.
There is a big difference between assuming the attacker has full
knowledge of AppArmor's design and implementation, which granted, is a
fair assumpion (no security through obsecurity) and assuming the
attacker has full root privs, and still wanting to stop them (i.e.,
mandatory access controls). You seem to be judging AppArmor with the
goals of SELinux, and that's not necessarily a fair comparison.
A Hummer can go through 36 inches of standing water, where as a Prius
can not. Does that mean that a Prius is a failure? Only if you judge
it by the standards of the Hummer. But from point of view of gas
mileage, the Prius will run circles around the Hummer....
> The problems with path-based mechanisms are technical in nature, not
> just philosophical.
If you restrict namespaces and chroot, then it solves that particular
problem. It will be useless for software packages that use
namespaces, such as for example if a hypothetical future version of a
propietary source code management tool decided to use shared subtree
support. There are however a huge number of software packages,
including most commercial/propietary packages that have to work across
a broad range of heterogenous systems, including AIX, Solaris, and
Linux, that won't be using namespaces and shared subtrees anytime
soon.
- Ted
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 21:07 ` Stephen Smalley
2006-04-24 23:52 ` Theodore Ts'o
@ 2006-04-25 4:25 ` Casey Schaufler
2006-04-25 7:50 ` James Morris
2006-04-25 16:47 ` Stephen Smalley
1 sibling, 2 replies; 173+ messages in thread
From: Casey Schaufler @ 2006-04-25 4:25 UTC (permalink / raw)
To: Stephen Smalley, Theodore Ts'o; +Cc: linux-kernel, linux-security-module
--- Stephen Smalley <sds@tycho.nsa.gov> wrote:
> Seems like a strawman. We aren't claiming that
> SELinux is perfect, and
> there is plenty of work ongoing on SELinux
> usability. But a
> fundamentally unsound mechanism is more dangerous
> than one that is never
> enabled; at least in the latter case, one knows
> where one stands. It is
> the illusory sense of security that accompanies
> path-based access
> control that is dangerous.
I suggest that this logic be applied to
the "strict policy", "targeted policy",
and "user written policy" presentations
of SELinux. You never know what the policy
might be.
Casey Schaufler
casey@schaufler-ca.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 23:52 ` Theodore Ts'o
@ 2006-04-25 6:22 ` Arjan van de Ven
2006-04-25 16:45 ` Stephen Smalley
1 sibling, 0 replies; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-25 6:22 UTC (permalink / raw)
To: Theodore Ts'o
Cc: Stephen Smalley, Neil Brown, Chris Wright, James Morris,
Andi Kleen, linux-kernel, linux-security-module
>
> If you restrict namespaces and chroot,
... and hardlinks
but yes good points otherwise.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 4:25 ` Casey Schaufler
@ 2006-04-25 7:50 ` James Morris
2006-04-25 12:46 ` Theodore Ts'o
2006-04-25 16:00 ` Casey Schaufler
2006-04-25 16:47 ` Stephen Smalley
1 sibling, 2 replies; 173+ messages in thread
From: James Morris @ 2006-04-25 7:50 UTC (permalink / raw)
To: Casey Schaufler
Cc: Stephen Smalley, Theodore Ts'o, linux-kernel,
linux-security-module
On Mon, 24 Apr 2006, Casey Schaufler wrote:
> > Seems like a strawman. We aren't claiming that SELinux is perfect,
> > and there is plenty of work ongoing on SELinux usability. But a
> > fundamentally unsound mechanism is more dangerous than one that is
> > never enabled; at least in the latter case, one knows where one
> > stands. It is the illusory sense of security that accompanies
> > path-based access control that is dangerous.
>
> I suggest that this logic be applied to the "strict policy", "targeted
> policy", and "user written policy" presentations of SELinux. You never
> know what the policy might be.
You are conflating the policies provided with SELinux systems with the
mechanisms of SELinux.
One of the important features of SELinux is its policy flexibility, with
clean separation of policy and mechanism. SELinux provides the mechanisms
to control all security relevant access of processes to data, and accesses
between processes.
It is up to the policy to determine how much of that mechanism is
utilized, according to desired security goals.
Targeted policy in fact does perform a usability-security tradeoff (as all
real security systems must do), aimed at the relatively simple case of
protecting systems with a few internet facing services. This is the
default policy shipped with _millions_ of Fedora and RHEL systems, and
represent, to the best of my knowledge, the first ever releases of general
purpose operating systems with MAC enabled by default.
The aims and limitations of targeted policy are very well documented.
If you wished, you could load a simpler policy which can offer an
equivalent level of protection offered by non-MAC schemes such as
AppArmor. In fact, some work has been going on more generally in this
area in Japan during the last couple of years.
Other types of users will want stricter policies, to meet their security
goals. The SELinux mechanism is general enough to cater to very high
levels of protection and assurance.
So, please, consider that the mechanism of SELinux is quite separate from
the types of policies which may be deployed.
And that arguments regarding SELinux "complexity" often confuse these
issues, as well as issues around tools and abstractions presented to
users.
To make a rough analogy (as Ted mentioned his IETF work earlier...):
Network security is a complicated issue, the fundamental nature of which
is determined by the protocols, systems and interactions between them.
IPsec seeks to provide a robust scheme for protecting a specific set of
protocols within a specific range of security goals. If you want to read
all of the specifications, you'll find it's very complex (too complex,
according to some). Yet, after many years of hard work, it's in
widespread use by general users, most of who simply click on a button on
their desktop to make it work. You wouldn't expect end users to actually
configure IPsec at the lowest levels, and even sysadmins need the right
tools and abstractions to effectively and safely deploy the technology
(see how far an average sysadmin gets with racoon and its man page).
The fundamental mechanisms of IPsec are sound. It has taken many, many
years to get it to this stage, despite claims of it being "too
complicated". In that time, several "simple" protocols were designed and
implemented to address the "complexity" issues, but it turns out, after
all, that with the right level of abstraction and tools, IPsec is not too
complicated to be secure or to use: by the obvious example of both its
widespread adoption and, afaik, no systemic security failures.
Similarly:
The Linux kernel has a specific level of complexity determined by the
nature of its many and varied mechanisms for resource access and
communications. SELinux seeks to reveal these and provide a mechanism to
control all security relevant interactions, as required. Much work is
underway on implementing and improving tools, and ensuring that the
abstraction levels are optimal for different classes of users (e.g. end
users, developers, sysadmins and security architects). I believe it will
not be long until the new SELinux tools provide a much better experience
for users, while the underlying security mechanisms will remain sound and
capable of meeting a very wide range of security objectives.
- James
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 20:45 ` Stephen Smalley
@ 2006-04-25 8:10 ` Neil Brown
2006-04-25 8:28 ` Al Viro
` (2 more replies)
0 siblings, 3 replies; 173+ messages in thread
From: Neil Brown @ 2006-04-25 8:10 UTC (permalink / raw)
To: Stephen Smalley
Cc: Chris Wright, James Morris, Arjan van de Ven, Andi Kleen,
linux-kernel, linux-security-module
On Monday April 24, sds@tycho.nsa.gov wrote:
> On Mon, 2006-04-24 at 14:18 +1000, Neil Brown wrote:
> > On Friday April 21, sds@tycho.nsa.gov wrote:
> > > On Fri, 2006-04-21 at 10:30 -0700, Chris Wright wrote:
> > > > * Stephen Smalley (sds@tycho.nsa.gov) wrote:
> > > > > Difficult to evaluate, when the answer whenever a flaw is pointed out is
> > > > > "that's not in our threat model." Easy enough to have a protection
> > > > > model match the threat model when the threat model is highly limited
> > > > > (and never really documented anywhere, particularly in a way that might
> > > > > warn its users of its limitations).
> > > >
> > > > I know, there's two questions. Whether the protection model is valid,
> > > > and whether the threat model is worth considering. So far, I've not
> > > > seen anything that's compelling enough to show AppArmor fundamentally
> > > > broken. Ugly and inefficient, yes...broken, not yet.
> > >
> > > Access control of any form requires unambiguous identification of
> > > subjects and objects in the system. Paths don't achieve such
> > > identification. Is that broken enough? If not, what is? What
> > > qualifies as broken?
> >
> > I have to disagree with this. Paths *do* achieve unambiguous
> > identification of something. That something is ..... the path.
>
> A path is not an object; it is a way of referring to an object. No need
> to reason about this abstractly - just look at the kernel's internal
> model; where are these mystical path objects and how are they
> implemented? And as a way of referring to an object, paths are
> ambiguous identifiers. Further, that ambiguity is leveraged by AppArmor
> to e.g. support multiple profiles for the same program via alternate
> paths.
But objects aren't the point. Paths are.
The primary goal of AppArmor isn't to protect objects. That is
secondary. The primary goal is to stop applications from
doing things that they weren't intended to do. i.e. it is to watch
their behaviour and make sure it doesn't deviate from what is
intended. The usage of names is a significant element of the
behaviour of the application, so AppArmor watches what names an
application uses and stops it from using names that it isn't
authorised to use.
Again, it is *not* about protecting data (primarily). It is about
stopping an application from doing what it isn't expected do.
This will largely have the effect of protecting data, as protecting
data is the intended secondary effect of AppArmor's primary mechanism
which is behaviour control.
>
> > Think about the name of this system for a minute. "AppArmor".
> > i.e. it is Armour for an Application. It protects the application.
> > It doesn't (as far as I can tell: I'm not an expert and don't work on
> > this thing) claim to protect files. It protects applications.
>
> >From the AppArmor overview on the novellforge page:
> "AppArmor security policies completely define what system resources
> individual applications can access..."
>
> >From the AppArmor FAQ:
> "AppArmor profiles are human-readable text files that mediate access to
> files and directories..."
>
> Isn't that claiming to protect files? If not, please make sure the end
> user documentation clearly says "AppArmor is not designed to protect
> files."
I think this text is fairly vague, and could be taken to mean several
things.
I think the policies do define what resources can be accessed and does
it using names. "Anything with name X can be accessed". Note that
AppArmor profiles never say what cannot be accessed, only what can.
In that sense they are not primarily protecting things so in a sense
they are not protecting any given file. Nevertheless the net result
is an increased level of data protection.
Maybe the documentation could be improved - that wouldn't be an
uncommon situation.
>
> > It protects them from doing the wrong thing - from doing something
> > they weren't designed to do. i.e. it protects them from being
> > subverted by exploiting a bug.
> >
> > A large part of the behaviour of an application is the path names that
> > it uses and what it does with them. If an application started doing
> > unexpected things with unexpected paths (e.g. exec("/bin/sh") or
> > open("/etc/shadow",O_RDONLY)) then this is a sure sign that it has
> > been subverted and that AppArmor need to protect it, from itself.
>
> Um, no. You are trying to protect the rest of the system from
> misbehavior by the application. You aren't protecting the application
> at all - you have already said it has been subverted, and it is then
> free to corrupt or leak any information it normally has legitimate
> access to. And since you don't care about information flow, you can't
> actually guarantee that the rest of the system isn't corrupted by the
> application misbehavior; any of your unconfined processes may become the
> conduit by which the corruption spills over into the rest of the system.
I have a knife with which to eat my dinner, but the moment I move
it more than 10cm from my plate, a robotic hand reaches out and
immobilised my hand and hence the knife. Who is being protected?
Not me I guess, because the sinful desire to kill has already taken
over my brain, though maybe I am being protected from life in prison
for murder.
Not you because you could still come and jump onto my knife and impale
yourself, or someone could grab your arm and drag your wrist along the
blade spilling much of your blood.
So maybe nobody is being protected. But somehow, fewer people die
when the robot arm is active.
This is how AppArmor works. It doesn't try to guarantee that no file
will be corrupted or leak. It doesn't try to ensure that no bug can ever
be exploited. But it does try to minimise harm. And it succeeds.
And remember, the robot didn't grab the knife. It grabbed my hand.
That is a bit like checking pathnames rather than inodes. It doesn't
provide a guarantee of "knife will not enter a body" just as AppArmor
doesn't guarantee that "file will not be changed". But is still tends
to produce the desired result.
>
> > While the protection against subversion cannot be complete, it can be
> > sufficient to dramatically reduce the chances of privilege
> > escalation. There are lots of wrong things you can get an
> > application to do once you find an exploitable bug. Many of these
> > will lead to a crash. AppArmor will not try to protect against these
> > (I suspect). There are substantially fewer that lead to privilege
> > escalation. AppArmor focusses its effort in terms of profile design
> > on exactly these sorts of unplanned behaviours.
>
> I don't see how it achieves such prevention with the limitations I've
> already noted, which are design limitations, not just characteristics of
> the implementation.
>
I don't see how you can say that. If you can stop a process from
calling
exec("/bin/sh"),
and there is no doubt that AppArmor can implement that policy for you,
then you have achieved a degree of prevention. It is clearly not
complete. There are a great many more things that AppArmor can
prevent an application from performing. Each one increases the level
of prevention. Maybe it doesn't reach 100% prevention of all
undesirable acts. But it is still useful.
> > So I think you still haven't given convincing evidence that AppArmor
> > is broken by design.
>
> If it isn't, then is anyone and everyone free to introduce other
> path-based mechanisms in the kernel in the future? Why has that been
> frowned upon in the past if there really isn't anything wrong with it?
"path-based mechanisms" like open, unlink, mkdir, ....
There are plenty of these in the kernel.
"path-based mechanisms" like "You cannot truncate a file named /etc/shadow"?
No, that would not be appropriate in the kernel as it is not well
defined.
However AppArmor doesn't (or shouldn't) do this. It might say "You
cannot truncate a file that you found by looking up the name
/etc/shadow", and I think that would be a valid and useful thing to
do. It might not do what you want, but that all depends on what you
want. The things you can ask AppArmor to do are still useful and
meaningful even if they are not the things that you might ask SELinux
to do.
NeilBrown
[Opinions in this article are mine and do not necessarily reflect the
official position of SuSE, Novell, or anyone else. They might not
even be mine tomorrow...]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 8:10 ` Neil Brown
@ 2006-04-25 8:28 ` Al Viro
2006-04-25 12:42 ` James Carter
2006-04-25 17:07 ` Stephen Smalley
2 siblings, 0 replies; 173+ messages in thread
From: Al Viro @ 2006-04-25 8:28 UTC (permalink / raw)
To: Neil Brown
Cc: Stephen Smalley, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On Tue, Apr 25, 2006 at 06:10:36PM +1000, Neil Brown wrote:
> I have a knife with which to eat my dinner, but the moment I move
> it more than 10cm from my plate, a robotic hand reaches out and
> immobilised my hand and hence the knife. Who is being protected?
>
> Not me I guess, because the sinful desire to kill has already taken
> over my brain, though maybe I am being protected from life in prison
> for murder.
... unless you figure out that knife can be thrown and 20cm + diameter of
plate might be enough of a swing to send it in the right direction with
the right angular momentum...
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 8:10 ` Neil Brown
2006-04-25 8:28 ` Al Viro
@ 2006-04-25 12:42 ` James Carter
2006-04-25 12:43 ` Andi Kleen
2006-04-25 17:07 ` Stephen Smalley
2 siblings, 1 reply; 173+ messages in thread
From: James Carter @ 2006-04-25 12:42 UTC (permalink / raw)
To: Neil Brown
Cc: Stephen Smalley, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On Tue, 2006-04-25 at 18:10 +1000, Neil Brown wrote:
> I have a knife with which to eat my dinner, but the moment I move
> it more than 10cm from my plate, a robotic hand reaches out and
> immobilised my hand and hence the knife. Who is being protected?
>
> Not me I guess, because the sinful desire to kill has already taken
> over my brain, though maybe I am being protected from life in prison
> for murder.
>
> Not you because you could still come and jump onto my knife and impale
> yourself, or someone could grab your arm and drag your wrist along the
> blade spilling much of your blood.
>
> So maybe nobody is being protected. But somehow, fewer people die
> when the robot arm is active.
>
> This is how AppArmor works. It doesn't try to guarantee that no file
> will be corrupted or leak. It doesn't try to ensure that no bug can ever
> be exploited. But it does try to minimise harm. And it succeeds.
>
> And remember, the robot didn't grab the knife. It grabbed my hand.
> That is a bit like checking pathnames rather than inodes. It doesn't
> provide a guarantee of "knife will not enter a body" just as AppArmor
> doesn't guarantee that "file will not be changed". But is still tends
> to produce the desired result.
I talk to one of the unconfined people at the table and ask them to
rename the "knife" to "spoon". Now I am free to do what I wish.
You don't care about the name "knife", you care about the object it
represents.
--
James Carter <jwcart2@epoch.ncsc.mil>
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 12:42 ` James Carter
@ 2006-04-25 12:43 ` Andi Kleen
2006-04-25 14:50 ` James Carter
2006-04-25 15:01 ` Stephen Smalley
0 siblings, 2 replies; 173+ messages in thread
From: Andi Kleen @ 2006-04-25 12:43 UTC (permalink / raw)
To: jwcart2
Cc: Neil Brown, Stephen Smalley, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Tuesday 25 April 2006 14:42, James Carter wrote:
> I talk to one of the unconfined people at the table and ask them to
> rename the "knife" to "spoon". Now I am free to do what I wish.
That assumes that your jail allows talking to other people.
> You don't care about the name "knife", you care about the object it
> represents.
In the apparmor model you only care about what the application is allowed
to do. If it does anything extraordinary like trying to talk to people it
shouldn't talk to it gets a veto.
-Andi
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 7:50 ` James Morris
@ 2006-04-25 12:46 ` Theodore Ts'o
2006-04-25 15:06 ` Stephen Smalley
2006-04-25 16:00 ` Casey Schaufler
1 sibling, 1 reply; 173+ messages in thread
From: Theodore Ts'o @ 2006-04-25 12:46 UTC (permalink / raw)
To: James Morris
Cc: Casey Schaufler, Stephen Smalley, linux-kernel,
linux-security-module
On Tue, Apr 25, 2006 at 03:50:00AM -0400, James Morris wrote:
> To make a rough analogy (as Ted mentioned his IETF work earlier...):
>
> The fundamental mechanisms of IPsec are sound. It has taken many, many
> years to get it to this stage, despite claims of it being "too
> complicated". In that time, several "simple" protocols were designed and
> implemented to address the "complexity" issues, but it turns out, after
> all, that with the right level of abstraction and tools, IPsec is not too
> complicated to be secure or to use: by the obvious example of both its
> widespread adoption and, afaik, no systemic security failures.
And yet, many people use SSH and TLS, and it is more than sufficient
for their needs. Despite being very involved with the development of
IPSec, and Kerberos, there are plenty of times when I will tell people
to *not* use those technologies because they are *just* *too*
*complicated*.
Choice is good.
SELinux should not be the only way to do things.
- Ted
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 12:43 ` Andi Kleen
@ 2006-04-25 14:50 ` James Carter
2006-04-25 15:01 ` Stephen Smalley
1 sibling, 0 replies; 173+ messages in thread
From: James Carter @ 2006-04-25 14:50 UTC (permalink / raw)
To: Andi Kleen
Cc: Neil Brown, Stephen Smalley, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Tue, 2006-04-25 at 14:43 +0200, Andi Kleen wrote:
> On Tuesday 25 April 2006 14:42, James Carter wrote:
>
> > I talk to one of the unconfined people at the table and ask them to
> > rename the "knife" to "spoon". Now I am free to do what I wish.
>
> That assumes that your jail allows talking to other people.
>
> > You don't care about the name "knife", you care about the object it
> > represents.
>
> In the apparmor model you only care about what the application is allowed
> to do. If it does anything extraordinary like trying to talk to people it
> shouldn't talk to it gets a veto.
IIUC Apparmor does not confine IPC, so it can't stop an application from
talking to one it shouldn't.
--
James Carter <jwcart2@epoch.ncsc.mil>
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 12:43 ` Andi Kleen
2006-04-25 14:50 ` James Carter
@ 2006-04-25 15:01 ` Stephen Smalley
2006-04-25 18:11 ` Tony Jones
1 sibling, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-25 15:01 UTC (permalink / raw)
To: Andi Kleen
Cc: jwcart2, Neil Brown, Chris Wright, James Morris, Arjan van de Ven,
linux-kernel, linux-security-module
On Tue, 2006-04-25 at 14:43 +0200, Andi Kleen wrote:
> On Tuesday 25 April 2006 14:42, James Carter wrote:
>
> > I talk to one of the unconfined people at the table and ask them to
> > rename the "knife" to "spoon". Now I am free to do what I wish.
>
> That assumes that your jail allows talking to other people.
AppArmor doesn't control IPC (which has been noted previously), and it
isn't clear how one generalizes its path-based scheme to handle all
kinds of kernel operations. So it isn't even a very good jail-like
mechanism. Which brings up an interesting topic of its own: If you
want the AppArmor model, then why not just use existing jail-like or
virtualization mechanisms? IIUC, Vservers and OpenVZ are already far
more complete in their coverage than AppArmor and leverage existing
kernel mechanisms like namespaces that at least have well-defined
semantics. I expect that I could achieve a much higher degree of
confidence in such a mechanism than in AppArmor. Why can't AppArmor
just become a userspace tool for configuring namespaces and setting up
the environment in which the application runs?
> > You don't care about the name "knife", you care about the object it
> > represents.
>
> In the apparmor model you only care about what the application is allowed
> to do. If it does anything extraordinary like trying to talk to people it
> shouldn't talk to it gets a veto.
Again, it doesn't control IPC.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 12:46 ` Theodore Ts'o
@ 2006-04-25 15:06 ` Stephen Smalley
0 siblings, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-25 15:06 UTC (permalink / raw)
To: Theodore Ts'o
Cc: James Morris, Casey Schaufler, linux-kernel,
linux-security-module
On Tue, 2006-04-25 at 08:46 -0400, Theodore Ts'o wrote:
> On Tue, Apr 25, 2006 at 03:50:00AM -0400, James Morris wrote:
> > To make a rough analogy (as Ted mentioned his IETF work earlier...):
> >
> > The fundamental mechanisms of IPsec are sound. It has taken many, many
> > years to get it to this stage, despite claims of it being "too
> > complicated". In that time, several "simple" protocols were designed and
> > implemented to address the "complexity" issues, but it turns out, after
> > all, that with the right level of abstraction and tools, IPsec is not too
> > complicated to be secure or to use: by the obvious example of both its
> > widespread adoption and, afaik, no systemic security failures.
>
> And yet, many people use SSH and TLS, and it is more than sufficient
> for their needs. Despite being very involved with the development of
> IPSec, and Kerberos, there are plenty of times when I will tell people
> to *not* use those technologies because they are *just* *too*
> *complicated*.
>
> Choice is good.
>
> SELinux should not be the only way to do things.
That's fine - it doesn't explain why a path-based access control
mechanism belongs in the kernel. Or why LSM is the right way to
implement such a mechanism, given the complete mismatch in the placement
and interfaces of its hooks.
Let's keep the debate separate, please - there is one debate regarding
removal of LSM, and you've expressed your view there. There is another
debate regarding whether AppArmor belongs in the kernel, and that
depends on the answers to the above questions. But it isn't sufficient
to argue that because SELinux isn't the only true way that AppArmor
should be merged, eh?
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 7:50 ` James Morris
2006-04-25 12:46 ` Theodore Ts'o
@ 2006-04-25 16:00 ` Casey Schaufler
2006-04-25 16:21 ` Randy.Dunlap
2006-04-25 17:29 ` Stephen Smalley
1 sibling, 2 replies; 173+ messages in thread
From: Casey Schaufler @ 2006-04-25 16:00 UTC (permalink / raw)
To: James Morris, Casey Schaufler
Cc: Stephen Smalley, Theodore Ts'o, linux-kernel,
linux-security-module
--- James Morris <jmorris@namei.org> wrote:
> You are conflating the policies provided with
> SELinux systems with the
> mechanisms of SELinux.
You have defeated me. My unabridged Webster does
not define "conflating" or even conflat, and I
guess that I'm too unhip to be up on it's modern
usage. Before I disagree with you, I'd like to
know what I've been charged with!
> One of the important features of SELinux is its
> policy flexibility, with
> clean separation of policy and mechanism.
Except that every single time I'm meet with
SELinux developers they have emphasised how
important it is to use the Official Policies.
> SELinux provides the mechanisms
> to control all security relevant access of processes
> to data, and accesses between processes.
Truth.
> It is up to the policy to determine how much of that
> mechanism is
> utilized, according to desired security goals.
Yes. And a complete system policy is enormous.
500,000 rules and growing, last I heard.
> Targeted policy in fact does perform a
> usability-security tradeoff (as all
> real security systems must do),
In Orange Book terms this was known as policy
not applying to all objects.
> aimed at the relatively simple case of
> protecting systems with a few internet facing
> services. This is the
> default policy shipped with _millions_ of Fedora and
> RHEL systems, and
> represent, to the best of my knowledge, the first
> ever releases of general
> purpose operating systems with MAC enabled by
> default.
Except that MAC is NOT enabled by default, it is
available by default. Only those programs and objects
identified by the policy are constrained.
> The aims and limitations of targeted policy are very
> well documented.
I'm old, so I won't say they're "very well"
documented,
but they are documented. The limitations of the
targeted
policy rarely show up in the glossy, however.
> If you wished, you could load a simpler policy which
> can offer an
> equivalent level of protection offered by non-MAC
> schemes such as
> AppArmor. In fact, some work has been going on more
> generally in this
> area in Japan during the last couple of years.
Yup. The policy description would still be large.
> Other types of users will want stricter policies, to
> meet their security
> goals. The SELinux mechanism is general enough to
> cater to very high
> levels of protection and assurance.
Yes it is. It works, I admit. There are even
applications
I'd suggest it be used for.
> So, please, consider that the mechanism of SELinux
> is quite separate from
> the types of policies which may be deployed.
Can't do that. The mechanism require large, complex
policies.
> And that arguments regarding SELinux "complexity"
> often confuse these
> issues, as well as issues around tools and
> abstractions presented to
> users.
The underlying mechanisms are more complex than
Bell & LePadula MAC + Biba Integrity + POSIX Caps.
I am not trying to knock SELinux (too hard) in
this discussion. I do want to point out that many
of the arguements being used against alternatives
apply to SELinux as well. I do not understand why
SELinux developers feel so threatened by alternatives.
Casey Schaufler
casey@schaufler-ca.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 16:00 ` Casey Schaufler
@ 2006-04-25 16:21 ` Randy.Dunlap
2006-04-26 3:42 ` Casey Schaufler
2006-04-25 17:29 ` Stephen Smalley
1 sibling, 1 reply; 173+ messages in thread
From: Randy.Dunlap @ 2006-04-25 16:21 UTC (permalink / raw)
To: casey; +Cc: jmorris, sds, tytso, linux-kernel, linux-security-module
On Tue, 25 Apr 2006 09:00:36 -0700 (PDT) Casey Schaufler wrote:
>
>
> --- James Morris <jmorris@namei.org> wrote:
>
>
> > You are conflating the policies provided with
> > SELinux systems with the
> > mechanisms of SELinux.
>
> You have defeated me. My unabridged Webster does
> not define "conflating" or even conflat, and I
> guess that I'm too unhip to be up on it's modern
> usage. Before I disagree with you, I'd like to
> know what I've been charged with!
>
> > One of the important features of SELinux is its
> > policy flexibility, with
> > clean separation of policy and mechanism.
use that internet thing, e.g., www.dict.org, and
look at "conflate".
---
~Randy
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 23:52 ` Theodore Ts'o
2006-04-25 6:22 ` Arjan van de Ven
@ 2006-04-25 16:45 ` Stephen Smalley
2006-04-25 16:52 ` Arjan van de Ven
2006-04-25 18:34 ` Valdis.Kletnieks
1 sibling, 2 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-25 16:45 UTC (permalink / raw)
To: Theodore Ts'o
Cc: Neil Brown, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On Mon, 2006-04-24 at 23:52 +0000, Theodore Ts'o wrote:
> On Mon, Apr 24, 2006 at 05:07:56PM -0400, Stephen Smalley wrote:
> > Does it have any hope of stopping an attacker who has designed his
> > attack with full knowledge of AppArmor's design and implementation (no
> > security through obscurity)?
>
> Well, it also depends on your threat model, right? What capabilities
> are you assuming the attacker will have? Does the attacker have an
> account on the system? Or has the attacker just exploited a stack
> overrun in a network daemon, or a failure to check some input field
> coming from the network, and the goal is to stop the attacker from
> escalating that to gaining full root privs on the system.
AppArmor doesn't do a very good job there either; its mediation is very
incomplete (nothing over IPC or many other inter-process operations),
and its ambiguous identification of objects leaves it prone to
coordinated attacks. Why not just use a jail-style mechanism if that is
what you want, ala VServer or OpenVZ?
> There is a big difference between assuming the attacker has full
> knowledge of AppArmor's design and implementation, which granted, is a
> fair assumpion (no security through obsecurity) and assuming the
> attacker has full root privs, and still wanting to stop them (i.e.,
> mandatory access controls). You seem to be judging AppArmor with the
> goals of SELinux, and that's not necessarily a fair comparison.
But AA specifically emphasizes that it controls capabilities so that
even a uid 0 process is "confined" by it.
> If you restrict namespaces and chroot, then it solves that particular
> problem. It will be useless for software packages that use
> namespaces, such as for example if a hypothetical future version of a
> propietary source code management tool decided to use shared subtree
> support. There are however a huge number of software packages,
> including most commercial/propietary packages that have to work across
> a broad range of heterogenous systems, including AIX, Solaris, and
> Linux, that won't be using namespaces and shared subtrees anytime
> soon.
pam_namespace in Fedora Core. Not to mention that the restrictions you
mention only solve the problem within the jail, which is fine if we are
only talking about jail mechanisms. Not so good for any kind of real
MAC.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 4:25 ` Casey Schaufler
2006-04-25 7:50 ` James Morris
@ 2006-04-25 16:47 ` Stephen Smalley
1 sibling, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-25 16:47 UTC (permalink / raw)
To: casey; +Cc: Theodore Ts'o, linux-kernel, linux-security-module
On Mon, 2006-04-24 at 21:25 -0700, Casey Schaufler wrote:
>
> --- Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
>
> > Seems like a strawman. We aren't claiming that
> > SELinux is perfect, and
> > there is plenty of work ongoing on SELinux
> > usability. But a
> > fundamentally unsound mechanism is more dangerous
> > than one that is never
> > enabled; at least in the latter case, one knows
> > where one stands. It is
> > the illusory sense of security that accompanies
> > path-based access
> > control that is dangerous.
>
> I suggest that this logic be applied to
> the "strict policy", "targeted policy",
> and "user written policy" presentations
> of SELinux. You never know what the policy
> might be.
Whatever policy you have, that policy is at least analyzable, and tools
exist for analyzing it for information flow as well as for direct
relationships. In the absence of complete mediation and unambiguous
identifiers, you can't do any analysis at all, so you never know whether
you have achieved your goal.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 16:45 ` Stephen Smalley
@ 2006-04-25 16:52 ` Arjan van de Ven
2006-04-25 17:43 ` Seth Arnold
2006-04-25 18:34 ` Valdis.Kletnieks
1 sibling, 1 reply; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-25 16:52 UTC (permalink / raw)
To: Stephen Smalley
Cc: Theodore Ts'o, Neil Brown, Chris Wright, James Morris,
Andi Kleen, linux-kernel, linux-security-module
> But AA specifically emphasizes that it controls capabilities so that
> even a uid 0 process is "confined" by it.
a scary angle is that a compromised "confined" process can still
reconfigure all your networking to the point that it can forward and NAT
outside connections to any machine on the inside (if the machine acts a
firewall-like role where it can see outside and inside at the same time)
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 8:10 ` Neil Brown
2006-04-25 8:28 ` Al Viro
2006-04-25 12:42 ` James Carter
@ 2006-04-25 17:07 ` Stephen Smalley
2006-04-26 22:15 ` Some Concrete AppArmor Questions - was " Neil Brown
2 siblings, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-25 17:07 UTC (permalink / raw)
To: Neil Brown
Cc: Chris Wright, James Morris, Arjan van de Ven, Andi Kleen,
linux-kernel, linux-security-module
On Tue, 2006-04-25 at 18:10 +1000, Neil Brown wrote:
> But objects aren't the point. Paths are.
> The primary goal of AppArmor isn't to protect objects.
Ok, please document this throughout all AppArmor documentation and
literature. It will be a source of great encouragement to users.
> That is
> secondary. The primary goal is to stop applications from
> doing things that they weren't intended to do. i.e. it is to watch
> their behaviour and make sure it doesn't deviate from what is
> intended.
What is intended goes beyond what names are used - it involves the
actual objects. When /bin/su asks to open /etc/shadow, it wants the
real system shadow password file, not just any old file to
which /etc/shadow might happen to resolve. Further, even at this
"primary" goal, AppArmor does a poor job wrt to already existing
virtualization or jail mechanisms AFAICS.
> This will largely have the effect of protecting data, as protecting
> data is the intended secondary effect of AppArmor's primary mechanism
> which is behaviour control.
No, it won't protect the data. You can't have it both ways. Either you
are only controlling the use of paths and not concerned with the objects
(if so, please document as such, but I can't imagine Crispin et al
admitting to such a position), or you are controlling the objects and
thus protecting the data.
> I think this text is fairly vague, and could be taken to mean several
> things.
> I think the policies do define what resources can be accessed and does
> it using names. "Anything with name X can be accessed". Note that
> AppArmor profiles never say what cannot be accessed, only what can.
Um, that's problematic then. If I can't determine what cannot be
accessed, then I can never know whether I have achieved my protection
goals.
> In that sense they are not primarily protecting things so in a sense
> they are not protecting any given file. Nevertheless the net result
> is an increased level of data protection.
No, only the appearance of it.
> Maybe the documentation could be improved - that wouldn't be an
> uncommon situation.
Dollars to donuts that they won't be willing to document that AA doesn't
protect objects in their documentation.
> > If it isn't, then is anyone and everyone free to introduce other
> > path-based mechanisms in the kernel in the future? Why has that been
> > frowned upon in the past if there really isn't anything wrong with it?
>
> "path-based mechanisms" like open, unlink, mkdir, ....
> There are plenty of these in the kernel.
Pathname resolution is fine, obviously. Regenerating pathnames in the
kernel and using them as part of your mechanism is...interesting. Don't
confuse the userspace configuration and kernel-user interface with the
internal mechanisms. Should inotify be calling d_path internally for
reporting to userspace?
> "path-based mechanisms" like "You cannot truncate a file named /etc/shadow"?
> No, that would not be appropriate in the kernel as it is not well
> defined.
That is precisely what AppArmor does.
> However AppArmor doesn't (or shouldn't) do this. It might say "You
> cannot truncate a file that you found by looking up the name
> /etc/shadow", and I think that would be a valid and useful thing to
> do.
AA doesn't even do that - as most of the LSM hooks don't get the
vfsmount info propagated to them, they don't know what specific path
your application took to the file.
> It might not do what you want, but that all depends on what you
> want. The things you can ask AppArmor to do are still useful and
> meaningful even if they are not the things that you might ask SELinux
> to do.
I don't see why you wouldn't use a jail-style mechanism if that is what
you want.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 15:16 ` Joshua Brindle
2006-04-24 15:50 ` Tony Jones
@ 2006-04-25 17:12 ` Valdis.Kletnieks
2006-04-25 17:34 ` Tony Jones
1 sibling, 1 reply; 173+ messages in thread
From: Valdis.Kletnieks @ 2006-04-25 17:12 UTC (permalink / raw)
To: Joshua Brindle
Cc: Andi Kleen, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
[-- Attachment #1: Type: text/plain, Size: 785 bytes --]
On Mon, 24 Apr 2006 11:16:25 EDT, Joshua Brindle said:
> To make this much more real, the /usr/sbin/named policy that ships with
> apparmor has the following line:
> /** r,
> Thats right, named can read any file on the system, I suppose this is
> because the policy relies on named being chrooted. So if for any reason
> named doesn't chroot its been granted read access on the entire
> filesystem.
Somebody *please* tell me I hallucinated the posting that said AppArmor
restricts the use of chroot by confined processes...
In any case, the incredibly brittle behavior of this policy in the face
of chroot() failure (from the people who should *know* how to write AppArmor
policy, no less) is just proof of why making it simple for non-experts to
write policy is a Bad Idea....
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 16:00 ` Casey Schaufler
2006-04-25 16:21 ` Randy.Dunlap
@ 2006-04-25 17:29 ` Stephen Smalley
2006-04-26 3:56 ` Casey Schaufler
1 sibling, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-25 17:29 UTC (permalink / raw)
To: casey; +Cc: James Morris, Theodore Ts'o, linux-kernel,
linux-security-module
On Tue, 2006-04-25 at 09:00 -0700, Casey Schaufler wrote:
> The underlying mechanisms are more complex than
> Bell & LePadula MAC + Biba Integrity + POSIX Caps.
Until one also considers the set of trusted subjects in systems that
rely on such models. That's the point. Those subjects are free to
violate the "simple" models, at which point any analysis of the
effective policy of the system has to include them as well. SELinux/TE
just makes the real situation explicit in the policy, and enables you to
tailor the policy to the real needs of applications while still being
able to analyze the result.
> I am not trying to knock SELinux (too hard) in
> this discussion. I do want to point out that many
> of the arguements being used against alternatives
> apply to SELinux as well. I do not understand why
> SELinux developers feel so threatened by alternatives.
We're not threatened by alternatives. We're concerned about a
technically unsound approach. The arguments being raised against
pathname-based access control are about the soundness of that technical
approach, not whether there should be any alternatives to SELinux.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 17:12 ` Valdis.Kletnieks
@ 2006-04-25 17:34 ` Tony Jones
0 siblings, 0 replies; 173+ messages in thread
From: Tony Jones @ 2006-04-25 17:34 UTC (permalink / raw)
To: Valdis.Kletnieks
Cc: Joshua Brindle, Andi Kleen, Neil Brown, Stephen Smalley,
Chris Wright, James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
On Tue, Apr 25, 2006 at 01:12:37PM -0400, Valdis.Kletnieks@vt.edu wrote:
> On Mon, 24 Apr 2006 11:16:25 EDT, Joshua Brindle said:
>
> > To make this much more real, the /usr/sbin/named policy that ships with
> > apparmor has the following line:
> > /** r,
> > Thats right, named can read any file on the system, I suppose this is
> > because the policy relies on named being chrooted. So if for any reason
> > named doesn't chroot its been granted read access on the entire
> > filesystem.
>
> Somebody *please* tell me I hallucinated the posting that said AppArmor
> restricts the use of chroot by confined processes...
Nope. I don't believe you've been chomping on any 'shrooms. The profile must
grant the confined task 'capability sys_chroot', even if the task already has
that capability in it's effective set.
> In any case, the incredibly brittle behavior of this policy in the face
> of chroot() failure (from the people who should *know* how to write AppArmor
> policy, no less) is just proof of why making it simple for non-experts to
> write policy is a Bad Idea....
I believe this was addressed in another post in this thread.
But yes, without the ability to either generate an absolute pathname or to
force a chrooted task into a distinct subprofile there currently exists (as
mentioned in the overview and patch descriptions) an issue of name collision
within the one profile.
Improvements clearly need to be made. This was the purpose of posting for
feedback, but it's quite the claim to go from this to your above assertion of
"proof".
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 16:52 ` Arjan van de Ven
@ 2006-04-25 17:43 ` Seth Arnold
0 siblings, 0 replies; 173+ messages in thread
From: Seth Arnold @ 2006-04-25 17:43 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Stephen Smalley, Theodore Ts'o, Neil Brown, Chris Wright,
James Morris, Andi Kleen, linux-kernel, linux-security-module
[-- Attachment #1: Type: text/plain, Size: 767 bytes --]
On Tue, Apr 25, 2006 at 06:52:40PM +0200, Arjan van de Ven wrote:
> a scary angle is that a compromised "confined" process can still
> reconfigure all your networking to the point that it can forward and NAT
If you have decided to allow the process to use CAP_NET_ADMIN by adding
the text "capability net_admin," to the profile in question, I fail to
see how this is "scary" -- in fact, this is exactly what you have chosen
to allow this process to do.
One of our developers has a profile set of 827 profiles that we use for
testing system functionality and our tools; twenty of those profiles have
"capability net_admin" granted. The other 807 profiles do not have the
ability to reconfigure the network at will.
I hope this clears up your concern. Thanks Arjan
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 15:01 ` Stephen Smalley
@ 2006-04-25 18:11 ` Tony Jones
2006-04-25 21:25 ` Stephen Smalley
0 siblings, 1 reply; 173+ messages in thread
From: Tony Jones @ 2006-04-25 18:11 UTC (permalink / raw)
To: Stephen Smalley
Cc: Andi Kleen, jwcart2, Neil Brown, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Tue, Apr 25, 2006 at 11:01:05AM -0400, Stephen Smalley wrote:
> AppArmor doesn't control IPC (which has been noted previously), and it
> isn't clear how one generalizes its path-based scheme to handle all
> kinds of kernel operations.
Maybe it will have to grow to handle more operations. SELinux has grown in
terms of it's features and what it protects. Clearly you have benefitted
from being open sourced for an extended period of time. I'm sure you'd love
to debate the history of this :) but there doesn't seem much productive point.
But I agree, it isn't clear how the AA scheme applies to all forms of kernel
operations.
> mechanism. Which brings up an interesting topic of its own: If you
> want the AppArmor model, then why not just use existing jail-like or
> virtualization mechanisms? IIUC, Vservers and OpenVZ are already far
Because it presumes that the application can easily be configured to function
in a jail.
> more complete in their coverage than AppArmor and leverage existing
> kernel mechanisms like namespaces that at least have well-defined
> semantics. I expect that I could achieve a much higher degree of
> confidence in such a mechanism than in AppArmor. Why can't AppArmor
> just become a userspace tool for configuring namespaces and setting up
> the environment in which the application runs?
How do you propose handling in a namespace the ability to create new files.
I can see how you could perhaps create a fixed scratch area inside the
namespace, but what if the application wants to create /var/lib/foo/bar.xxx
You have obviously read the AppArmor docs. How would you propose to handle
(approximately) the expressiveness of AppArmor policy. Also what does
/srv/www/htdocs/**.html equate to when this namespace is configured for the
application. Does the task need to be torn down and restarted if you populate
more files?
The issue of namespaces being a better way of doing all of this has been raised
a couple of times. It is an interesting idea for sure. I responded to one of
the posts with the same (above) questions but havn't yet seen a reply.
Other LSM hooks are an option also. Clearly if we can add new hooks at more
optimal locations where pathnames are available it would be preferable to
the current scheme and (qualifier: the devil is in the details) probably
preferable to trying to pass vfsmounts fully into the existing hooks.
Tony
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 16:45 ` Stephen Smalley
2006-04-25 16:52 ` Arjan van de Ven
@ 2006-04-25 18:34 ` Valdis.Kletnieks
2006-04-25 18:48 ` Stephen Smalley
1 sibling, 1 reply; 173+ messages in thread
From: Valdis.Kletnieks @ 2006-04-25 18:34 UTC (permalink / raw)
To: Stephen Smalley
Cc: Theodore Ts'o, Neil Brown, Chris Wright, James Morris,
Arjan van de Ven, Andi Kleen, linux-kernel, linux-security-module
[-- Attachment #1: Type: text/plain, Size: 619 bytes --]
On Tue, 25 Apr 2006 12:45:33 EDT, Stephen Smalley said:
> pam_namespace in Fedora Core. Not to mention that the restrictions you
> mention only solve the problem within the jail, which is fine if we are
> only talking about jail mechanisms. Not so good for any kind of real
> MAC.
Umm.. Stephen? Where in Fedora Core is it? I'm running a Fedora Core Rawhide
right now, and it's not on my system, and 'yum provides pam_namespace.so'
doesn't find it either. There *is* stuff over in the -lspp branch, but it
(AFAIK) hasn't escaped into anything resembling general availability. Was this
what you were referencing?
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 18:34 ` Valdis.Kletnieks
@ 2006-04-25 18:48 ` Stephen Smalley
2006-04-25 18:56 ` Valdis.Kletnieks
0 siblings, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-25 18:48 UTC (permalink / raw)
To: Valdis.Kletnieks
Cc: Theodore Ts'o, Neil Brown, Chris Wright, James Morris,
Arjan van de Ven, Andi Kleen, linux-kernel, linux-security-module
On Tue, 2006-04-25 at 14:34 -0400, Valdis.Kletnieks@vt.edu wrote:
> On Tue, 25 Apr 2006 12:45:33 EDT, Stephen Smalley said:
>
> > pam_namespace in Fedora Core. Not to mention that the restrictions you
> > mention only solve the problem within the jail, which is fine if we are
> > only talking about jail mechanisms. Not so good for any kind of real
> > MAC.
>
> Umm.. Stephen? Where in Fedora Core is it? I'm running a Fedora Core Rawhide
> right now, and it's not on my system, and 'yum provides pam_namespace.so'
> doesn't find it either. There *is* stuff over in the -lspp branch, but it
> (AFAIK) hasn't escaped into anything resembling general availability. Was this
> what you were referencing?
Today's rawhide. 0.99.3.0-3. ChangeLog is:
* Tue Apr 25 2006 Tomas Mraz <tmraz@redhat.com> 0.99.3.0-3
- added pam_namespace module written by Janak Desai (per-user /tmp
support)
- new pam-redhat modules version
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 18:48 ` Stephen Smalley
@ 2006-04-25 18:56 ` Valdis.Kletnieks
0 siblings, 0 replies; 173+ messages in thread
From: Valdis.Kletnieks @ 2006-04-25 18:56 UTC (permalink / raw)
To: Stephen Smalley
Cc: Theodore Ts'o, Neil Brown, Chris Wright, James Morris,
Arjan van de Ven, Andi Kleen, linux-kernel, linux-security-module
[-- Attachment #1: Type: text/plain, Size: 1094 bytes --]
On Tue, 25 Apr 2006 14:48:46 EDT, Stephen Smalley said:
> On Tue, 2006-04-25 at 14:34 -0400, Valdis.Kletnieks@vt.edu wrote:
> > On Tue, 25 Apr 2006 12:45:33 EDT, Stephen Smalley said:
> >
> > > pam_namespace in Fedora Core. Not to mention that the restrictions you
> > > mention only solve the problem within the jail, which is fine if we are
> > > only talking about jail mechanisms. Not so good for any kind of real
> > > MAC.
> >
> > Umm.. Stephen? Where in Fedora Core is it? I'm running a Fedora Core Rawhide
> > right now, and it's not on my system, and 'yum provides pam_namespace.so'
> > doesn't find it either. There *is* stuff over in the -lspp branch, but it
> > (AFAIK) hasn't escaped into anything resembling general availability. Was
this
> > what you were referencing?
>
> Today's rawhide. 0.99.3.0-3. ChangeLog is:
> * Tue Apr 25 2006 Tomas Mraz <tmraz@redhat.com> 0.99.3.0-3
> - added pam_namespace module written by Janak Desai (per-user /tmp
> support)
> - new pam-redhat modules version
OK.. That one hasn't actually propagated out to where it's visible yet. :)
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-24 7:14 ` Arjan van de Ven
2006-04-24 8:11 ` Lars Marowsky-Bree
@ 2006-04-25 19:27 ` Seth Arnold
1 sibling, 0 replies; 173+ messages in thread
From: Seth Arnold @ 2006-04-25 19:27 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Neil Brown, Stephen Smalley, Chris Wright, James Morris,
Andi Kleen, linux-kernel, linux-security-module
[-- Attachment #1: Type: text/plain, Size: 522 bytes --]
On Mon, Apr 24, 2006 at 09:14:58AM +0200, Arjan van de Ven wrote:
> does apparmor at least (offer) to kill the app when this happens?
> (rationale: the app is hijacked, better kill it before it goes to do
> damage)
We have considered offering a "kill the process on failure" configuration
option; we certainly wouldn't want to force it on people, who might
simply be stopping their application from doing something annoying.
However, the code as currently posted, does not offer this feature.
Thanks for the suggestion
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 18:11 ` Tony Jones
@ 2006-04-25 21:25 ` Stephen Smalley
0 siblings, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-25 21:25 UTC (permalink / raw)
To: Tony Jones
Cc: Andi Kleen, jwcart2, Neil Brown, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Tue, 2006-04-25 at 11:11 -0700, Tony Jones wrote:
> Maybe it will have to grow to handle more operations. SELinux has grown in
> terms of it's features and what it protects. Clearly you have benefitted
> from being open sourced for an extended period of time. I'm sure you'd love
> to debate the history of this :) but there doesn't seem much productive point.
Well, for what it is worth, I think that even in its first public
release in 2000, SELinux provided mediation of more operations than AA
does even now, even if we exclude network controls from consideration
(since SubDomain had some form of network controls in the past that were
temporarily dropped due to LSM limitations).
> But I agree, it isn't clear how the AA scheme applies to all forms of kernel
> operations.
Yes, and this is the real point - it is a question of whether the
underlying model (if it can even be said to have one) generalizes. With
SELinux, there is a well-defined model and it does generalize. With AA,
I just don't see it.
> Because it presumes that the application can easily be configured to function
> in a jail.
I'd expect even more compatibility issues with AA-style access controls
than a jail/virtualization approach.
> How do you propose handling in a namespace the ability to create new files.
> I can see how you could perhaps create a fixed scratch area inside the
> namespace, but what if the application wants to create /var/lib/foo/bar.xxx
>
> You have obviously read the AppArmor docs. How would you propose to handle
> (approximately) the expressiveness of AppArmor policy. Also what does
> /srv/www/htdocs/**.html equate to when this namespace is configured for the
> application. Does the task need to be torn down and restarted if you populate
> more files?
>
> The issue of namespaces being a better way of doing all of this has been raised
> a couple of times. It is an interesting idea for sure. I responded to one of
> the posts with the same (above) questions but havn't yet seen a reply.
I don't know whether existing jail/virtualization solutions can fully
replicate your functionality, but be careful not to confuse the actual
requirements with your current implementation and UI. And you have to
weigh the gains in robustness against any potential loss in
expressiveness.
> Other LSM hooks are an option also. Clearly if we can add new hooks at more
> optimal locations where pathnames are available it would be preferable to
> the current scheme and (qualifier: the devil is in the details) probably
> preferable to trying to pass vfsmounts fully into the existing hooks.
Not sure what this would look like, but if your module still ends up
calling d_path or equivalent on every open, then it seems problematic
regardless.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 16:21 ` Randy.Dunlap
@ 2006-04-26 3:42 ` Casey Schaufler
2006-04-26 12:15 ` Stephen Smalley
0 siblings, 1 reply; 173+ messages in thread
From: Casey Schaufler @ 2006-04-26 3:42 UTC (permalink / raw)
To: Randy.Dunlap; +Cc: jmorris, sds, tytso, linux-kernel, linux-security-module
--- "Randy.Dunlap" <rdunlap@xenotime.net> wrote:
> use that internet thing, e.g., www.dict.org, and
> look at "conflate".
OK. I am not conflating the policy issues and the
mechanism issue of SELinux. The mechanisms of SELinux
lead to the policy issues. A complete set of policies
for an SELinux system require an unreasonable number
of rules. This violates the Third item of the TCB
principle, which is the the TCB must be small enough
to analyse. The mechanisms are pointless without the
rules.
Conflating my forehead!
Casey Schaufler
casey@schaufler-ca.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 17:29 ` Stephen Smalley
@ 2006-04-26 3:56 ` Casey Schaufler
2006-04-26 11:32 ` Stephen Smalley
0 siblings, 1 reply; 173+ messages in thread
From: Casey Schaufler @ 2006-04-26 3:56 UTC (permalink / raw)
To: Stephen Smalley
Cc: James Morris, Theodore Ts'o, linux-kernel,
linux-security-module
--- Stephen Smalley <sds@tycho.nsa.gov> wrote:
> On Tue, 2006-04-25 at 09:00 -0700, Casey Schaufler
> wrote:
> > The underlying mechanisms are more complex than
> > Bell & LePadula MAC + Biba Integrity + POSIX Caps.
>
> Until one also considers the set of trusted subjects
> in systems that
> rely on such models.
How so? It's pretty much the same set of subjects
as you'd find in SELinux.
> That's the point. Those subjects are free to
> violate the "simple" models, at which point any
> analysis of the
> effective policy of the system has to include them
> as well.
Yup, and you're going to have to provide analysis
of the subjects under SELinux as well. No way are
you going to convince anyone that a half-million
lines of policy definition are 100% error free.
> SELinux/TE
> just makes the real situation explicit in the
> policy, and enables you to
> tailor the policy to the real needs of applications
> while still being
> able to analyze the result.
This is what I don't get. How can you claim that
you can analyse a policy definition that big?
Further, I remember arguments to the effect of
a programmer being able to knock off the policy
for a program in 10 minutes. Having written and
analysed as many MLS systems as anyone on the
planet you'll excuse my scepicism. And poor speling.
Casey Schaufler
casey@schaufler-ca.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-26 3:56 ` Casey Schaufler
@ 2006-04-26 11:32 ` Stephen Smalley
0 siblings, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-26 11:32 UTC (permalink / raw)
To: casey; +Cc: James Morris, Theodore Ts'o, linux-kernel,
linux-security-module
On Tue, 2006-04-25 at 20:56 -0700, Casey Schaufler wrote:
>
> --- Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
> > On Tue, 2006-04-25 at 09:00 -0700, Casey Schaufler
> > wrote:
> > > The underlying mechanisms are more complex than
> > > Bell & LePadula MAC + Biba Integrity + POSIX Caps.
> >
> > Until one also considers the set of trusted subjects
> > in systems that
> > rely on such models.
>
> How so? It's pretty much the same set of subjects
> as you'd find in SELinux.
>
> > That's the point. Those subjects are free to
> > violate the "simple" models, at which point any
> > analysis of the
> > effective policy of the system has to include them
> > as well.
>
> Yup, and you're going to have to provide analysis
> of the subjects under SELinux as well. No way are
> you going to convince anyone that a half-million
> lines of policy definition are 100% error free.
>
> > SELinux/TE
> > just makes the real situation explicit in the
> > policy, and enables you to
> > tailor the policy to the real needs of applications
> > while still being
> > able to analyze the result.
>
> This is what I don't get. How can you claim that
> you can analyse a policy definition that big?
> Further, I remember arguments to the effect of
> a programmer being able to knock off the policy
> for a program in 10 minutes. Having written and
> analysed as many MLS systems as anyone on the
> planet you'll excuse my scepicism. And poor speling.
Perhaps we aren't communicating very well. There are already tools like
apol and slat that perform information flow analysis of SELinux policies
and that can be used to check properties.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-26 3:42 ` Casey Schaufler
@ 2006-04-26 12:15 ` Stephen Smalley
2006-04-27 0:21 ` Casey Schaufler
0 siblings, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-26 12:15 UTC (permalink / raw)
To: casey; +Cc: Randy.Dunlap, jmorris, tytso, linux-kernel, linux-security-module
On Tue, 2006-04-25 at 20:42 -0700, Casey Schaufler wrote:
>
> --- "Randy.Dunlap" <rdunlap@xenotime.net> wrote:
>
> > use that internet thing, e.g., www.dict.org, and
> > look at "conflate".
>
> OK. I am not conflating the policy issues and the
> mechanism issue of SELinux. The mechanisms of SELinux
> lead to the policy issues. A complete set of policies
> for an SELinux system require an unreasonable number
> of rules. This violates the Third item of the TCB
> principle, which is the the TCB must be small enough
> to analyse. The mechanisms are pointless without the
> rules.
>
> Conflating my forehead!
The policy is analyzable, and there are tools (apol and slat) that do
precisely that. Including information flow analysis and invariant
checking. What's your problem, again?
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-25 17:07 ` Stephen Smalley
@ 2006-04-26 22:15 ` Neil Brown
2006-04-26 23:06 ` Ken Brush
2006-04-27 11:02 ` Christoph Hellwig
0 siblings, 2 replies; 173+ messages in thread
From: Neil Brown @ 2006-04-26 22:15 UTC (permalink / raw)
To: Stephen Smalley
Cc: Chris Wright, James Morris, Arjan van de Ven, Andi Kleen,
linux-kernel, linux-security-module
I feel we have reached the stage where the questions/comments being
made are actually directly relevant to AppArmor. I'm afraid I cannot
proceed any further now because I am not a security expert.
I would like to summarise what I think are the key points that you
have raised, and hope that someone who has a deeper understanding of
these things might answer them, or point to answers.
1/ Does AppArmor's primary mechanism of confining an application to a
superset of it's expected behaviour actually achieve its secondary
gaol of protecting data?
Possibly it would be better to ask "When does ..." as I think it is
easy to imagine application/profile pairs that clearly cannot allow
harm, and application/profile pairs that clearly could allow harm.
2/ What advantages does AppArmor provide over techniques involving
virtualisation or gaol mechanisms? Are these advantages worth
while?
3/ Is AppArmour's approach of using d_path to get a filename from a
dentry valid and acceptable? If not, how can it get a path? Can
suitable hooks be provided so that AppArmor can get a path in an
acceptable way at the times when that is meaningful?
I believe that these are all good questions. The last one is the only
one that it really relevant to linux-kernel I believe, however answers
to the first two might tell us how important it is to answer that last
one.
Thanks for your input.
NeilBrown
.... yes, I am top posting. The mail I am responding to is below. I
have not added any commentary in there but have left it for easy
reference so you, dear readers, can decide for yourself whether the
questions I have provided above are relevant to the preceding
discussion.
On Tuesday April 25, sds@tycho.nsa.gov wrote:
> On Tue, 2006-04-25 at 18:10 +1000, Neil Brown wrote:
> > But objects aren't the point. Paths are.
> > The primary goal of AppArmor isn't to protect objects.
>
> Ok, please document this throughout all AppArmor documentation and
> literature. It will be a source of great encouragement to users.
>
> > That is
> > secondary. The primary goal is to stop applications from
> > doing things that they weren't intended to do. i.e. it is to watch
> > their behaviour and make sure it doesn't deviate from what is
> > intended.
>
> What is intended goes beyond what names are used - it involves the
> actual objects. When /bin/su asks to open /etc/shadow, it wants the
> real system shadow password file, not just any old file to
> which /etc/shadow might happen to resolve. Further, even at this
> "primary" goal, AppArmor does a poor job wrt to already existing
> virtualization or jail mechanisms AFAICS.
>
> > This will largely have the effect of protecting data, as protecting
> > data is the intended secondary effect of AppArmor's primary mechanism
> > which is behaviour control.
>
> No, it won't protect the data. You can't have it both ways. Either you
> are only controlling the use of paths and not concerned with the objects
> (if so, please document as such, but I can't imagine Crispin et al
> admitting to such a position), or you are controlling the objects and
> thus protecting the data.
>
> > I think this text is fairly vague, and could be taken to mean several
> > things.
> > I think the policies do define what resources can be accessed and does
> > it using names. "Anything with name X can be accessed". Note that
> > AppArmor profiles never say what cannot be accessed, only what can.
>
> Um, that's problematic then. If I can't determine what cannot be
> accessed, then I can never know whether I have achieved my protection
> goals.
>
> > In that sense they are not primarily protecting things so in a sense
> > they are not protecting any given file. Nevertheless the net result
> > is an increased level of data protection.
>
> No, only the appearance of it.
>
> > Maybe the documentation could be improved - that wouldn't be an
> > uncommon situation.
>
> Dollars to donuts that they won't be willing to document that AA doesn't
> protect objects in their documentation.
>
> > > If it isn't, then is anyone and everyone free to introduce other
> > > path-based mechanisms in the kernel in the future? Why has that been
> > > frowned upon in the past if there really isn't anything wrong with it?
> >
> > "path-based mechanisms" like open, unlink, mkdir, ....
> > There are plenty of these in the kernel.
>
> Pathname resolution is fine, obviously. Regenerating pathnames in the
> kernel and using them as part of your mechanism is...interesting. Don't
> confuse the userspace configuration and kernel-user interface with the
> internal mechanisms. Should inotify be calling d_path internally for
> reporting to userspace?
>
> > "path-based mechanisms" like "You cannot truncate a file named /etc/shadow"?
> > No, that would not be appropriate in the kernel as it is not well
> > defined.
>
> That is precisely what AppArmor does.
>
> > However AppArmor doesn't (or shouldn't) do this. It might say "You
> > cannot truncate a file that you found by looking up the name
> > /etc/shadow", and I think that would be a valid and useful thing to
> > do.
>
> AA doesn't even do that - as most of the LSM hooks don't get the
> vfsmount info propagated to them, they don't know what specific path
> your application took to the file.
>
> > It might not do what you want, but that all depends on what you
> > want. The things you can ask AppArmor to do are still useful and
> > meaningful even if they are not the things that you might ask SELinux
> > to do.
>
> I don't see why you wouldn't use a jail-style mechanism if that is what
> you want.
>
> --
> Stephen Smalley
> National Security Agency
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-26 22:15 ` Some Concrete AppArmor Questions - was " Neil Brown
@ 2006-04-26 23:06 ` Ken Brush
2006-04-27 4:15 ` Andi Kleen
2006-04-27 17:43 ` Stephen Smalley
2006-04-27 11:02 ` Christoph Hellwig
1 sibling, 2 replies; 173+ messages in thread
From: Ken Brush @ 2006-04-26 23:06 UTC (permalink / raw)
To: Neil Brown
Cc: Stephen Smalley, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On 4/26/06, Neil Brown <neilb@suse.de> wrote:
>
> I feel we have reached the stage where the questions/comments being
> made are actually directly relevant to AppArmor. I'm afraid I cannot
> proceed any further now because I am not a security expert.
>
> I would like to summarise what I think are the key points that you
> have raised, and hope that someone who has a deeper understanding of
> these things might answer them, or point to answers.
>
> 1/ Does AppArmor's primary mechanism of confining an application to a
> superset of it's expected behaviour actually achieve its secondary
> gaol of protecting data?
>
> Possibly it would be better to ask "When does ..." as I think it is
> easy to imagine application/profile pairs that clearly cannot allow
> harm, and application/profile pairs that clearly could allow harm.
Depends on the data. A properly constrained Apache webserver would be
prevented from accessing data it shouldn't.
> 2/ What advantages does AppArmor provide over techniques involving
> virtualisation or gaol mechanisms? Are these advantages worth
> while?
If you just wish to run every application in a chrooted jail. Would
you still need a MAC solution?
> 3/ Is AppArmour's approach of using d_path to get a filename from a
> dentry valid and acceptable? If not, how can it get a path? Can
> suitable hooks be provided so that AppArmor can get a path in an
> acceptable way at the times when that is meaningful?
I'll leave this for the others...
> I believe that these are all good questions. The last one is the only
> one that it really relevant to linux-kernel I believe, however answers
> to the first two might tell us how important it is to answer that last
> one.
>
> Thanks for your input.
>
> NeilBrown
>
[snipped]
-Ken
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-26 12:15 ` Stephen Smalley
@ 2006-04-27 0:21 ` Casey Schaufler
2006-04-27 14:47 ` Karl MacMillan
0 siblings, 1 reply; 173+ messages in thread
From: Casey Schaufler @ 2006-04-27 0:21 UTC (permalink / raw)
To: Stephen Smalley; +Cc: linux-kernel, linux-security-module
--- Stephen Smalley <sds@tycho.nsa.gov> wrote:
> On Tue, 2006-04-25 at 20:42 -0700, Casey Schaufler
> wrote:
> > Conflating my forehead!
>
> The policy is analyzable, and there are tools (apol
> and slat) that do precisely that.
Ok. I remain unconvinced, in part because the analysis
requires tools.
> Including information flow analysis
> and invariant checking.
Ok. Fair enough.
> What's your problem, again?
You keep asking that.
I seem to have fallen off topic, which happens
sometimes, and I apologize for falling into this
long standing and overly religeous debate. I
have failed to present my case with sufficient
clarity to prove convincing once again. Perhaps
one day I'll get it right. Perhaps one day I'll
figure out why I'm wrong.
Casey Schaufler
casey@schaufler-ca.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-26 23:06 ` Ken Brush
@ 2006-04-27 4:15 ` Andi Kleen
2006-04-27 6:52 ` Arjan van de Ven
2006-04-27 10:17 ` Chris Wright
2006-04-27 17:43 ` Stephen Smalley
1 sibling, 2 replies; 173+ messages in thread
From: Andi Kleen @ 2006-04-27 4:15 UTC (permalink / raw)
To: Ken Brush
Cc: Neil Brown, Stephen Smalley, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Thursday 27 April 2006 01:06, Ken Brush wrote:
> > 2/ What advantages does AppArmor provide over techniques involving
> > virtualisation or gaol mechanisms? Are these advantages worth
> > while?
I would guess the advantage is easier administration. e.g. I always
found it a PITA to synchronize files like /etc/resolv.conf and similar
files into chroots.
It's similar as to why managing a single machine is much easier
than a cluster. Chroots already get you many of the drawbacks from
a cluster. That said it has its places, but chroot is not always
the answer.
> If you just wish to run every application in a chrooted jail. Would
> you still need a MAC solution?
Current chroot is probably not strong enough - if someone gets root
inside it it is easy to escape.
> > 3/ Is AppArmour's approach of using d_path to get a filename from a
> > dentry valid and acceptable?
I suppose it needs at least to use the proper vfsmounts instead of
walking the global list. That would need better hooks. And probably
some caching (trying to match dentries directly?) to get better performance.
Regarding the basic use of pathnames I don't see a big problem. After
all the kernel uses dentries for everything too and dentries are
just a special form of path name too.
-Andi
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 4:15 ` Andi Kleen
@ 2006-04-27 6:52 ` Arjan van de Ven
2006-04-27 7:40 ` Chris Wright
2006-04-27 10:17 ` Chris Wright
1 sibling, 1 reply; 173+ messages in thread
From: Arjan van de Ven @ 2006-04-27 6:52 UTC (permalink / raw)
To: Andi Kleen
Cc: Ken Brush, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, linux-kernel, linux-security-module
On Thu, 2006-04-27 at 06:15 +0200, Andi Kleen wrote:
> On Thursday 27 April 2006 01:06, Ken Brush wrote:
>
> > > 2/ What advantages does AppArmor provide over techniques involving
> > > virtualisation or gaol mechanisms? Are these advantages worth
> > > while?
>
> I would guess the advantage is easier administration. e.g. I always
> found it a PITA to synchronize files like /etc/resolv.conf and similar
> files into chroots.
there's another option than just chroots; construct a namespace with
just the allowed files bind-mounted in. That is 100% scriptable and also
doesn't have the "stale files" problem
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 6:52 ` Arjan van de Ven
@ 2006-04-27 7:40 ` Chris Wright
0 siblings, 0 replies; 173+ messages in thread
From: Chris Wright @ 2006-04-27 7:40 UTC (permalink / raw)
To: Arjan van de Ven
Cc: Andi Kleen, Ken Brush, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, linux-kernel, linux-security-module
* Arjan van de Ven (arjan@infradead.org) wrote:
> On Thu, 2006-04-27 at 06:15 +0200, Andi Kleen wrote:
> > On Thursday 27 April 2006 01:06, Ken Brush wrote:
> >
> > > > 2/ What advantages does AppArmor provide over techniques involving
> > > > virtualisation or gaol mechanisms? Are these advantages worth
> > > > while?
> >
> > I would guess the advantage is easier administration. e.g. I always
> > found it a PITA to synchronize files like /etc/resolv.conf and similar
> > files into chroots.
>
> there's another option than just chroots; construct a namespace with
> just the allowed files bind-mounted in. That is 100% scriptable and also
> doesn't have the "stale files" problem
That doesn't support different access modes aside of DAC, which defeats
the point. So either way, there's a need for better infrastructure.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 4:15 ` Andi Kleen
2006-04-27 6:52 ` Arjan van de Ven
@ 2006-04-27 10:17 ` Chris Wright
2006-04-27 14:42 ` Karl MacMillan
2006-04-27 16:03 ` Stephen Smalley
1 sibling, 2 replies; 173+ messages in thread
From: Chris Wright @ 2006-04-27 10:17 UTC (permalink / raw)
To: Andi Kleen
Cc: Ken Brush, Neil Brown, Stephen Smalley, Chris Wright,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
* Andi Kleen (ak@suse.de) wrote:
> > > 3/ Is AppArmour's approach of using d_path to get a filename from a
> > > dentry valid and acceptable?
>
> I suppose it needs at least to use the proper vfsmounts instead of
> walking the global list. That would need better hooks. And probably
> some caching (trying to match dentries directly?) to get better performance.
Yes, walking the list is ugly. I think you'd wind up having to pin
those dentries in memory (or do what DTE tried with a shadow tree).
> Regarding the basic use of pathnames I don't see a big problem. After
> all the kernel uses dentries for everything too and dentries are
> just a special form of path name too.
The biggest issue with pathnames is they are non-determinstic,
esp. when recreated after the fact using d_path. So the pathname as
object argument makes sense when talking about objects (vfsmont/dentry),
not strings (d_path). Also, when mediating solely on pathname it's very
difficult to reason about the contents of the inode that's pointed to by
the pathname. This means that policy which allows a subject the ability
to write to the object whose handle is /tmp/my_unimportant_tmpfile may be
a security problem if somebody in the system was tricked into a simple 'ln
/etc/shadow /tmp/my_unimportant_tmpfile.' In this case it's surprising
that the same inode can have different permissions (esp. given traditional
DAC uid/gid and mode bits are kept in inode) depending upon path taken.
The AA stance is that the policy will protect the confined process from
doing such namespace manipulations eliminating the possibiilty of the
confined process and giving itself a mechanism to privilege escalation.
This is reasonable with the caveat that the channels available to the
confined process to collude with (or coerce) an unconfined process are
still pretty high-bandwidth. One could argue that having unconfined
processes is ill-advised. SELinux targeted policy has the same basic
issue (channel richness notwithstanding), which is why I'd expect truely
security sensitive environments would use a strict policy.
I guess it's worth noting the AA atack is stopped by SELinux, while the
opposite is also true. A 'cp /etc/shadow /tmp; mv /tmp/shadow /etc' done
by an unconfined process doesn't effect AA, while it kills the type
label on /etc/shadow and could be an effective policy breach. In each
case somewhat subtle (i.e. not explicit relabel or policy change) can
have holes.
thanks,
-chris
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-26 22:15 ` Some Concrete AppArmor Questions - was " Neil Brown
2006-04-26 23:06 ` Ken Brush
@ 2006-04-27 11:02 ` Christoph Hellwig
2006-04-27 11:05 ` Andi Kleen
1 sibling, 1 reply; 173+ messages in thread
From: Christoph Hellwig @ 2006-04-27 11:02 UTC (permalink / raw)
To: Neil Brown
Cc: Stephen Smalley, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On Thu, Apr 27, 2006 at 08:15:30AM +1000, Neil Brown wrote:
> 3/ Is AppArmour's approach of using d_path to get a filename from a
> dentry valid and acceptable?
Clear no, and that should have been obvious to the aa people from the
beginning. To make a path-based approach actually work as designed you
need to hook up higher, where the real path is available.
> If not, how can it get a path? Can
> suitable hooks be provided so that AppArmor can get a path in an
> acceptable way at the times when that is meaningful?
I think that's up to the aa people to find out.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 11:02 ` Christoph Hellwig
@ 2006-04-27 11:05 ` Andi Kleen
0 siblings, 0 replies; 173+ messages in thread
From: Andi Kleen @ 2006-04-27 11:05 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Neil Brown, Stephen Smalley, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Thursday 27 April 2006 13:02, Christoph Hellwig wrote:
> On Thu, Apr 27, 2006 at 08:15:30AM +1000, Neil Brown wrote:
> > 3/ Is AppArmour's approach of using d_path to get a filename from a
> > dentry valid and acceptable?
>
> Clear no, and that should have been obvious to the aa people from the
> beginning. To make a path-based approach actually work as designed you
> need to hook up higher, where the real path is available.
What do you mean with real path? Even in open the path can be quite weird
("dir1/../dir2/../dir3/..." etc.)
I suspect it will always need to work with sanitized paths.
Starting from the dentry for that is a quite reasonable, although
d_path indeed seems quite inefficient without any caching mechanism.
-Andi
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 10:17 ` Chris Wright
@ 2006-04-27 14:42 ` Karl MacMillan
2006-04-27 23:44 ` Chris Wright
2006-04-27 16:03 ` Stephen Smalley
1 sibling, 1 reply; 173+ messages in thread
From: Karl MacMillan @ 2006-04-27 14:42 UTC (permalink / raw)
To: Chris Wright
Cc: Andi Kleen, Ken Brush, Neil Brown, Stephen Smalley, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Thu, 2006-04-27 at 03:17 -0700, Chris Wright wrote:
> * Andi Kleen (ak@suse.de) wrote:
> > > > 3/ Is AppArmour's approach of using d_path to get a filename from a
> > > > dentry valid and acceptable?
> >
> > I suppose it needs at least to use the proper vfsmounts instead of
> > walking the global list. That would need better hooks. And probably
> > some caching (trying to match dentries directly?) to get better performance.
>
> Yes, walking the list is ugly. I think you'd wind up having to pin
> those dentries in memory (or do what DTE tried with a shadow tree).
>
> > Regarding the basic use of pathnames I don't see a big problem. After
> > all the kernel uses dentries for everything too and dentries are
> > just a special form of path name too.
>
> The biggest issue with pathnames is they are non-determinstic,
> esp. when recreated after the fact using d_path. So the pathname as
> object argument makes sense when talking about objects (vfsmont/dentry),
> not strings (d_path). Also, when mediating solely on pathname it's very
> difficult to reason about the contents of the inode that's pointed to by
> the pathname. This means that policy which allows a subject the ability
> to write to the object whose handle is /tmp/my_unimportant_tmpfile may be
> a security problem if somebody in the system was tricked into a simple 'ln
> /etc/shadow /tmp/my_unimportant_tmpfile.' In this case it's surprising
> that the same inode can have different permissions (esp. given traditional
> DAC uid/gid and mode bits are kept in inode) depending upon path taken.
>
> The AA stance is that the policy will protect the confined process from
> doing such namespace manipulations eliminating the possibiilty of the
> confined process and giving itself a mechanism to privilege escalation.
> This is reasonable with the caveat that the channels available to the
> confined process to collude with (or coerce) an unconfined process are
> still pretty high-bandwidth. One could argue that having unconfined
> processes is ill-advised. SELinux targeted policy has the same basic
> issue (channel richness notwithstanding), which is why I'd expect truely
> security sensitive environments would use a strict policy.
>
> I guess it's worth noting the AA atack is stopped by SELinux, while the
> opposite is also true. A 'cp /etc/shadow /tmp; mv /tmp/shadow /etc' done
> by an unconfined process doesn't effect AA, while it kills the type
> label on /etc/shadow and could be an effective policy breach. In each
> case somewhat subtle (i.e. not explicit relabel or policy change) can
> have holes.
>
While this is example of labeling issues with SELinux is correct for a
standard targeted policy, it does not represent an intrinsic problem
with the SELinux mechanism. A policy that has the appropriate
specialized domains for reading /etc/shadow and corresponding
type_transition rules can prevent this mislabeling. The solution may not
be very satisfying because of the changes it makes to how systems are
typically administered, but at least it does exist within the SELinux
model. The same cannot be said of the problems introduced by path-based
mechanisms.
Thanks,
Karl
> thanks,
> -chris
> -
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 0:21 ` Casey Schaufler
@ 2006-04-27 14:47 ` Karl MacMillan
0 siblings, 0 replies; 173+ messages in thread
From: Karl MacMillan @ 2006-04-27 14:47 UTC (permalink / raw)
To: casey; +Cc: Stephen Smalley, linux-kernel, linux-security-module
On Wed, 2006-04-26 at 17:21 -0700, Casey Schaufler wrote:
>
> --- Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
> > On Tue, 2006-04-25 at 20:42 -0700, Casey Schaufler
> > wrote:
>
> > > Conflating my forehead!
> >
> > The policy is analyzable, and there are tools (apol
> > and slat) that do precisely that.
>
> Ok. I remain unconvinced, in part because the analysis
> requires tools.
>
Not certain what you mean by requires - it is possible to do policy
analysis manually, though the tools certainly bring more rigor. Analysis
of SELinux policies is not simply possible in theory - it has been done
by us (Tresys) and others.
Karl
--
Karl MacMillan
Tresys Technology
www.tresys.com
> > Including information flow analysis
> > and invariant checking.
>
> Ok. Fair enough.
>
> > What's your problem, again?
>
> You keep asking that.
>
> I seem to have fallen off topic, which happens
> sometimes, and I apologize for falling into this
> long standing and overly religeous debate. I
> have failed to present my case with sufficient
> clarity to prove convincing once again. Perhaps
> one day I'll get it right. Perhaps one day I'll
> figure out why I'm wrong.
>
>
>
> Casey Schaufler
> casey@schaufler-ca.com
> -
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 10:17 ` Chris Wright
2006-04-27 14:42 ` Karl MacMillan
@ 2006-04-27 16:03 ` Stephen Smalley
2006-04-27 22:38 ` Chris Wright
1 sibling, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-27 16:03 UTC (permalink / raw)
To: Chris Wright
Cc: Karl MacMillan, Andi Kleen, Ken Brush, Neil Brown, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Thu, 2006-04-27 at 03:17 -0700, Chris Wright wrote:
> This means that policy which allows a subject the ability
> to write to the object whose handle is /tmp/my_unimportant_tmpfile may be
> a security problem if somebody in the system was tricked into a simple 'ln
> /etc/shadow /tmp/my_unimportant_tmpfile.' In this case it's surprising
> that the same inode can have different permissions (esp. given traditional
> DAC uid/gid and mode bits are kept in inode) depending upon path taken.
>
> The AA stance is that the policy will protect the confined process from
> doing such namespace manipulations eliminating the possibiilty of the
> confined process and giving itself a mechanism to privilege escalation.
> This is reasonable with the caveat that the channels available to the
> confined process to collude with (or coerce) an unconfined process are
> still pretty high-bandwidth. One could argue that having unconfined
> processes is ill-advised. SELinux targeted policy has the same basic
> issue (channel richness notwithstanding), which is why I'd expect truely
> security sensitive environments would use a strict policy.
Even in the absence of any "unconfined" processes, the potential for
collusion among multiple "confined" processes (via coordinated attack)
shouldn't be overlooked. Thus, the base mechanism needs to be resilient
in the face of such collusion.
> I guess it's worth noting the AA atack is stopped by SELinux, while the
> opposite is also true. A 'cp /etc/shadow /tmp; mv /tmp/shadow /etc' done
> by an unconfined process doesn't effect AA, while it kills the type
> label on /etc/shadow and could be an effective policy breach. In each
> case somewhat subtle (i.e. not explicit relabel or policy change) can
> have holes.
Not sure about the example here, as the type in that case would actually
be lost upon the cp by the unconfined process to the /tmp location, in
which case you have an issue for both AA and SELinux - the data has
become accessible under a different name and label which may now be
accessible beyond the original intent. If you had used appropriate
options to cp to preserve the attribute, then it would have preserved
the type throughout the transaction. Of course, the real problem here
is that you have an unconfined process copying the data at all, at which
point you have no real guarantees about it, and the loss in label is the
least of your worries.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-26 23:06 ` Ken Brush
2006-04-27 4:15 ` Andi Kleen
@ 2006-04-27 17:43 ` Stephen Smalley
2006-04-27 17:58 ` Ken Brush
1 sibling, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-27 17:43 UTC (permalink / raw)
To: Ken Brush
Cc: Neil Brown, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On Wed, 2006-04-26 at 16:06 -0700, Ken Brush wrote:
> On 4/26/06, Neil Brown <neilb@suse.de> wrote:
> >
> > I feel we have reached the stage where the questions/comments being
> > made are actually directly relevant to AppArmor. I'm afraid I cannot
> > proceed any further now because I am not a security expert.
> >
> > I would like to summarise what I think are the key points that you
> > have raised, and hope that someone who has a deeper understanding of
> > these things might answer them, or point to answers.
> >
> > 1/ Does AppArmor's primary mechanism of confining an application to a
> > superset of it's expected behaviour actually achieve its secondary
> > gaol of protecting data?
> >
> > Possibly it would be better to ask "When does ..." as I think it is
> > easy to imagine application/profile pairs that clearly cannot allow
> > harm, and application/profile pairs that clearly could allow harm.
>
> Depends on the data. A properly constrained Apache webserver would be
> prevented from accessing data it shouldn't.
No, it wouldn't. The question itself is flawed - it presumes that AA
does confine the application to its expected behavior. But with
incomplete mediation and ambiguous identifiers, there is no such
guarantee. No profile will meet the "clearly cannot allow harm"
definition, because not all operations are controlled by it and of the
operations that are controlled, the actual objects are not clearly
identified, so harm is still possible.
> > 2/ What advantages does AppArmor provide over techniques involving
> > virtualisation or gaol mechanisms? Are these advantages worth
> > while?
>
> If you just wish to run every application in a chrooted jail. Would
> you still need a MAC solution?
If your goal is purely isolation, then virtualization may fit your
needs. If you want to support controlled sharing of data while still
ensuring that certain confidentiality and integrity goals are met, then
you want a MAC mechanism. But AA really isn't a MAC mechanism, despite
what its documentation may say.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 17:43 ` Stephen Smalley
@ 2006-04-27 17:58 ` Ken Brush
2006-04-28 11:28 ` Stephen Smalley
0 siblings, 1 reply; 173+ messages in thread
From: Ken Brush @ 2006-04-27 17:58 UTC (permalink / raw)
To: Stephen Smalley
Cc: Neil Brown, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On 4/27/06, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> On Wed, 2006-04-26 at 16:06 -0700, Ken Brush wrote:
> > On 4/26/06, Neil Brown <neilb@suse.de> wrote:
> > >
> > > I feel we have reached the stage where the questions/comments being
> > > made are actually directly relevant to AppArmor. I'm afraid I cannot
> > > proceed any further now because I am not a security expert.
> > >
> > > I would like to summarise what I think are the key points that you
> > > have raised, and hope that someone who has a deeper understanding of
> > > these things might answer them, or point to answers.
> > >
> > > 1/ Does AppArmor's primary mechanism of confining an application to a
> > > superset of it's expected behaviour actually achieve its secondary
> > > gaol of protecting data?
> > >
> > > Possibly it would be better to ask "When does ..." as I think it is
> > > easy to imagine application/profile pairs that clearly cannot allow
> > > harm, and application/profile pairs that clearly could allow harm.
> >
> > Depends on the data. A properly constrained Apache webserver would be
> > prevented from accessing data it shouldn't.
>
> No, it wouldn't. The question itself is flawed - it presumes that AA
> does confine the application to its expected behavior.
I can confine a process to my idea of it's expected behavior.
> But with
> incomplete mediation and ambiguous identifiers, there is no such
> guarantee. No profile will meet the "clearly cannot allow harm"
> definition, because not all operations are controlled by it and of the
> operations that are controlled, the actual objects are not clearly
> identified, so harm is still possible.
>
I can guarantee that if my profile does not allow write access to /etc
that apache's write to "/etc/new_file" will not be allowed.
The argument that somehow someone would setup a soft link or something
so that apache could write to /etc via indirection is not my primary
concern. That is systematic of a more concerted attack and a very
determined attacker. Or at the very least, a mistake on my part. And
in that case, I cannot protect myself from myself.
> > > 2/ What advantages does AppArmor provide over techniques involving
> > > virtualisation or gaol mechanisms? Are these advantages worth
> > > while?
> >
> > If you just wish to run every application in a chrooted jail. Would
> > you still need a MAC solution?
>
> If your goal is purely isolation, then virtualization may fit your
> needs. If you want to support controlled sharing of data while still
> ensuring that certain confidentiality and integrity goals are met, then
> you want a MAC mechanism. But AA really isn't a MAC mechanism, despite
> what its documentation may say.
I have no requirements like that. I just would prefer that when people
try to exploit my internet services, that the programs are not allowed
to do things that I would rather it not do. AA seems to fulfill that
requirement.
-Ken
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 16:03 ` Stephen Smalley
@ 2006-04-27 22:38 ` Chris Wright
2006-04-28 13:00 ` Stephen Smalley
0 siblings, 1 reply; 173+ messages in thread
From: Chris Wright @ 2006-04-27 22:38 UTC (permalink / raw)
To: Stephen Smalley
Cc: Chris Wright, Karl MacMillan, Andi Kleen, Ken Brush, Neil Brown,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
* Stephen Smalley (sds@tycho.nsa.gov) wrote:
> Even in the absence of any "unconfined" processes, the potential for
> collusion among multiple "confined" processes (via coordinated attack)
> shouldn't be overlooked. Thus, the base mechanism needs to be resilient
> in the face of such collusion.
Yes, good point.
> > I guess it's worth noting the AA atack is stopped by SELinux, while the
> > opposite is also true. A 'cp /etc/shadow /tmp; mv /tmp/shadow /etc' done
> > by an unconfined process doesn't effect AA, while it kills the type
> > label on /etc/shadow and could be an effective policy breach. In each
> > case somewhat subtle (i.e. not explicit relabel or policy change) can
> > have holes.
>
> Not sure about the example here, as the type in that case would actually
> be lost upon the cp by the unconfined process to the /tmp location, in
> which case you have an issue for both AA and SELinux - the data has
> become accessible under a different name and label which may now be
> accessible beyond the original intent.
Point is, names matter as much as inodes do. And it's possible to
get improperly labelled data in canonical location for object (i.e.
/etc/shadow). Certainly requires unconfined help, but real people do
things like that w/out fully understanding the impact. You can fix the
normal tools, but not all one-off admin tools.
> If you had used appropriate
> options to cp to preserve the attribute, then it would have preserved
> the type throughout the transaction.
Hehe, why would I do that if I'm trying to get unconfined process to
break the label? ;-)
> Of course, the real problem here
> is that you have an unconfined process copying the data at all, at which
> point you have no real guarantees about it, and the loss in label is the
> least of your worries.
That's my point. You can't meaningfully reason about the security of
the system with unconfined processes.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 14:42 ` Karl MacMillan
@ 2006-04-27 23:44 ` Chris Wright
2006-04-28 13:02 ` Stephen Smalley
0 siblings, 1 reply; 173+ messages in thread
From: Chris Wright @ 2006-04-27 23:44 UTC (permalink / raw)
To: Karl MacMillan
Cc: Chris Wright, Andi Kleen, Ken Brush, Neil Brown, Stephen Smalley,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
* Karl MacMillan (kmacmillan@tresys.com) wrote:
> While this is example of labeling issues with SELinux is correct for a
> standard targeted policy, it does not represent an intrinsic problem
> with the SELinux mechanism. A policy that has the appropriate
> specialized domains for reading /etc/shadow and corresponding
> type_transition rules can prevent this mislabeling. The solution may not
> be very satisfying because of the changes it makes to how systems are
> typically administered, but at least it does exist within the SELinux
> model. The same cannot be said of the problems introduced by path-based
> mechanisms.
Indeed, I tried to be quite specific to targeted policy. The point
is that having unconfined domains makes it very challenging to reason
about the security of the system. So, while comprehensive strict policy
addresses that, it's also what nearly guarantees turning security off
for most normal general purpose machines ;-)
thanks,
-chris
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 17:58 ` Ken Brush
@ 2006-04-28 11:28 ` Stephen Smalley
2006-04-28 11:47 ` Andi Kleen
0 siblings, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-28 11:28 UTC (permalink / raw)
To: Ken Brush
Cc: Neil Brown, Chris Wright, James Morris, Arjan van de Ven,
Andi Kleen, linux-kernel, linux-security-module
On Thu, 2006-04-27 at 10:58 -0700, Ken Brush wrote:
> > No, it wouldn't. The question itself is flawed - it presumes that AA
> > does confine the application to its expected behavior.
>
> I can confine a process to my idea of it's expected behavior.
Um, only if your idea is limited to authorized capabilities and paths.
If you actually want to circumscribe the full behavior of the program
(e.g. IPC, inter-process operations), you don't have the necessary
enforcement mechanism.
> I can guarantee that if my profile does not allow write access to /etc
> that apache's write to "/etc/new_file" will not be allowed.
If it uses that path as the argument, then yes (although to be clear, AA
operates at file level and skips directory write/search checking, IIUC
from the code - see aa_filter_mask). But you don't know whether or not
it can write to the same file via another path that is included in its
profile.
> The argument that somehow someone would setup a soft link or something
> so that apache could write to /etc via indirection is not my primary
> concern. That is systematic of a more concerted attack and a very
> determined attacker. Or at the very least, a mistake on my part. And
> in that case, I cannot protect myself from myself.
So you are only worried about script kiddies? Further, once someone
crafts an exploit specifically targeting AA, knowing full well its
limitations, that exploit will become fodder for the kiddies as well.
If a security mechanism only prevents attacks that weren't designed
against it, what good is it aside from a temporary stopgap?
> I have no requirements like that. I just would prefer that when people
> try to exploit my internet services, that the programs are not allowed
> to do things that I would rather it not do. AA seems to fulfill that
> requirement.
Why can't you use existing virtualization solutions ala Vservers or
OpenVZ or whatever?
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-28 11:28 ` Stephen Smalley
@ 2006-04-28 11:47 ` Andi Kleen
2006-04-28 12:28 ` Stephen Smalley
0 siblings, 1 reply; 173+ messages in thread
From: Andi Kleen @ 2006-04-28 11:47 UTC (permalink / raw)
To: Stephen Smalley
Cc: Ken Brush, Neil Brown, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Friday 28 April 2006 13:28, Stephen Smalley wrote:
> So you are only worried about script kiddies? Further, once someone
> crafts an exploit specifically targeting AA, knowing full well its
> limitations, that exploit will become fodder for the kiddies as well.
> If a security mechanism only prevents attacks that weren't designed
> against it, what good is it aside from a temporary stopgap?
The same could be said about selinux. Or what are you doing
to e.g. stop DOS attacks? Nothing is 100% water tight. The question
is just if the subsets of controls it implements matches the requirements of
the administrator. These requirements both include easiness of use
and security. Usually there is a tradeoff there and it's not the
same for everybody.
> > I have no requirements like that. I just would prefer that when people
> > try to exploit my internet services, that the programs are not allowed
> > to do things that I would rather it not do. AA seems to fulfill that
> > requirement.
>
> Why can't you use existing virtualization solutions ala Vservers or
> OpenVZ or whatever?
I guess he doesn't want to administrate a "cluster" of machines with many
/s, just a single box.
-Andi
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-28 11:47 ` Andi Kleen
@ 2006-04-28 12:28 ` Stephen Smalley
0 siblings, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-28 12:28 UTC (permalink / raw)
To: Andi Kleen
Cc: Karl MacMillan, Ken Brush, Neil Brown, Chris Wright, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Fri, 2006-04-28 at 13:47 +0200, Andi Kleen wrote:
> On Friday 28 April 2006 13:28, Stephen Smalley wrote:
>
> > So you are only worried about script kiddies? Further, once someone
> > crafts an exploit specifically targeting AA, knowing full well its
> > limitations, that exploit will become fodder for the kiddies as well.
> > If a security mechanism only prevents attacks that weren't designed
> > against it, what good is it aside from a temporary stopgap?
>
> The same could be said about selinux. Or what are you doing
> to e.g. stop DOS attacks? Nothing is 100% water tight. The question
> is just if the subsets of controls it implements matches the requirements of
> the administrator. These requirements both include easiness of use
> and security. Usually there is a tradeoff there and it's not the
> same for everybody.
I can't say I follow your reasoning. AA and SELinux are both access
control mechanisms; DOS attacks are largely outside the scope of either.
They are both concerned with preventing unauthorized disclosure of
information (confidentiality) and unauthorized modification of data
(integrity), not with ensuring availability of service. Neither will be
perfect in achieving such goals, but we can legitimately ask whether one
mechanism is so fundamentally flawed as to never be able to achieve the
goals in the face of an adversary with full knowledge of the mechanism.
And I think that AA qualifies here, again due to incomplete mediation
(so the attacker knows precisely where to strike) and ambiguous
identifiers (so the attacker knows precisely how to overcome the
intended protection).
Let's suppose that SELinux and AA are both widely deployed and used, and
attackers therefore craft attacks targeting each of them. In the
SELinux case, let's say they find a flaw in the policy configuration,
and exploit it. Solution? Improve the policy configuration. No
mechanism change required. In the AA case, same issue applies to
situations where only the profile is in error. But if the attacker
exploits the absence of mediation of a given operation in AA, or
exploits the use of ambiguous identifiers, then there is no fix for AA
without revisiting the base mechanism, and in the latter case at least,
revisiting the design. See the difference? That's not to say that
people won't find flaws in each, but the question is whether one is
fundamentally limited by design, and whether this means that ultimately
AA will cease to be relevant as a protection mechanism because attackers
will simply evolve to attack its inherent limitations. I don't see an
evolutionary path for AA; it is a dead end by its own design.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 22:38 ` Chris Wright
@ 2006-04-28 13:00 ` Stephen Smalley
0 siblings, 0 replies; 173+ messages in thread
From: Stephen Smalley @ 2006-04-28 13:00 UTC (permalink / raw)
To: Chris Wright
Cc: Karl MacMillan, Andi Kleen, Ken Brush, Neil Brown, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Thu, 2006-04-27 at 15:38 -0700, Chris Wright wrote:
> * Stephen Smalley (sds@tycho.nsa.gov) wrote:
> > Not sure about the example here, as the type in that case would actually
> > be lost upon the cp by the unconfined process to the /tmp location, in
> > which case you have an issue for both AA and SELinux - the data has
> > become accessible under a different name and label which may now be
> > accessible beyond the original intent.
>
> Point is, names matter as much as inodes do. And it's possible to
> get improperly labelled data in canonical location for object (i.e.
> /etc/shadow). Certainly requires unconfined help, but real people do
> things like that w/out fully understanding the impact. You can fix the
> normal tools, but not all one-off admin tools.
The names don't matter as much as the real security properties of the
data, but I do agree that mislabeling of data is an issue, particularly
for a gradual rollout of MAC where we have to deal with the fact that
not everything will be confined and not all of userspace will be
properly instrumented. However, I'd argue that this can be addressed,
in the short term through userspace tools like restorecond that leverage
inotify and in the long term through ever expanding application of MAC
to the system (as that becomes more feasible via the introduction of
appropriate tools and infrastructure to make management feasible, which
is already in progress). Addressing it by introducing a flawed
mechanism into the kernel seems like a bad idea to me.
> > Of course, the real problem here
> > is that you have an unconfined process copying the data at all, at which
> > point you have no real guarantees about it, and the loss in label is the
> > least of your worries.
>
> That's my point. You can't meaningfully reason about the security of
> the system with unconfined processes.
Precisely. And this is something that we recognize and are working
toward eliminating - the targeted policy is just a way of transitioning
MAC into Linux gradually until we have the necessary infrastructure and
tools to make it truly manageable. Whereas other approaches seem to
presume that unconfined processes will always be present, and in fact,
will be the majority of the system.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-27 23:44 ` Chris Wright
@ 2006-04-28 13:02 ` Stephen Smalley
2006-04-28 15:49 ` Casey Schaufler
0 siblings, 1 reply; 173+ messages in thread
From: Stephen Smalley @ 2006-04-28 13:02 UTC (permalink / raw)
To: Chris Wright
Cc: Karl MacMillan, Andi Kleen, Ken Brush, Neil Brown, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
On Thu, 2006-04-27 at 16:44 -0700, Chris Wright wrote:
> * Karl MacMillan (kmacmillan@tresys.com) wrote:
> > While this is example of labeling issues with SELinux is correct for a
> > standard targeted policy, it does not represent an intrinsic problem
> > with the SELinux mechanism. A policy that has the appropriate
> > specialized domains for reading /etc/shadow and corresponding
> > type_transition rules can prevent this mislabeling. The solution may not
> > be very satisfying because of the changes it makes to how systems are
> > typically administered, but at least it does exist within the SELinux
> > model. The same cannot be said of the problems introduced by path-based
> > mechanisms.
>
> Indeed, I tried to be quite specific to targeted policy. The point
> is that having unconfined domains makes it very challenging to reason
> about the security of the system. So, while comprehensive strict policy
> addresses that, it's also what nearly guarantees turning security off
> for most normal general purpose machines ;-)
But this is a temporary situation, until we have the infrastructure and
tools developed to make MAC truly manageable by typical end users. Not
an inherent problem.
--
Stephen Smalley
National Security Agency
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-28 13:02 ` Stephen Smalley
@ 2006-04-28 15:49 ` Casey Schaufler
2006-04-28 16:04 ` Stephen Hemminger
2006-04-28 16:56 ` Karl MacMillan
0 siblings, 2 replies; 173+ messages in thread
From: Casey Schaufler @ 2006-04-28 15:49 UTC (permalink / raw)
To: Stephen Smalley, Chris Wright
Cc: Karl MacMillan, Andi Kleen, Ken Brush, Neil Brown, James Morris,
Arjan van de Ven, linux-kernel, linux-security-module
--- Stephen Smalley <sds@tycho.nsa.gov> wrote:
> But this is a temporary situation, until we have the
> infrastructure and
> tools developed to make MAC truly manageable by
> typical end users. Not
> an inherent problem.
Oh come on! I've been hearing that saw continueously
since 1987. Mandatory MAC (as opposed to targeted MAC)
is hard on sysadmins. It will remain so. SELinux,
Trusted Solaris, Trusted IRIX, and anyone else are all
a pain in the bum and will remain so. Tools are going
to help only to a limited extent, they never make all
the pain go away. Smarter people than I have been
working on the problem for 20 years and I believe that
it's safe to say there is no magic wand that will
make the problems all go away.
I like MAC. I like the Iron Fist approach to software
security. I just don't believe that there's a glove
with velvet thick enough to please the masses.
Casey Schaufler
casey@schaufler-ca.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-28 15:49 ` Casey Schaufler
@ 2006-04-28 16:04 ` Stephen Hemminger
2006-04-28 21:49 ` James Morris
2006-04-28 16:56 ` Karl MacMillan
1 sibling, 1 reply; 173+ messages in thread
From: Stephen Hemminger @ 2006-04-28 16:04 UTC (permalink / raw)
To: linux-kernel
On Fri, 28 Apr 2006 08:49:27 -0700 (PDT)
Casey Schaufler <casey@schaufler-ca.com> wrote:
>
>
> --- Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
>
> > But this is a temporary situation, until we have the
> > infrastructure and
> > tools developed to make MAC truly manageable by
> > typical end users. Not
> > an inherent problem.
>
> Oh come on! I've been hearing that saw continueously
> since 1987. Mandatory MAC (as opposed to targeted MAC)
> is hard on sysadmins. It will remain so. SELinux,
> Trusted Solaris, Trusted IRIX, and anyone else are all
> a pain in the bum and will remain so. Tools are going
> to help only to a limited extent, they never make all
> the pain go away. Smarter people than I have been
> working on the problem for 20 years and I believe that
> it's safe to say there is no magic wand that will
> make the problems all go away.
>
> I like MAC. I like the Iron Fist approach to software
> security. I just don't believe that there's a glove
> with velvet thick enough to please the masses.
>
The problem I see looking from the outside at this discussion is that
SELinux and AppArmor have two different goals. AppArmor like no-execute
is more targeted at preventing an existing application with well defined
behavior from doing something wrong. Like other tools of this type:
virus scanners, etc; it works to prevent the known good applications
from turning rogue. The problem is that listing all the allowed behavior
for all applications would be impossible.
SELinux on the other hand takes a real security view of the world. If
you have ever worked with real security environment with "need to
know", you will understand that it is hard to keep secure and requires
too many restrictions for normal users.
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-28 15:49 ` Casey Schaufler
2006-04-28 16:04 ` Stephen Hemminger
@ 2006-04-28 16:56 ` Karl MacMillan
1 sibling, 0 replies; 173+ messages in thread
From: Karl MacMillan @ 2006-04-28 16:56 UTC (permalink / raw)
To: casey
Cc: Stephen Smalley, Chris Wright, Andi Kleen, Ken Brush, Neil Brown,
James Morris, Arjan van de Ven, linux-kernel,
linux-security-module
On Fri, 2006-04-28 at 08:49 -0700, Casey Schaufler wrote:
>
> --- Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
>
> > But this is a temporary situation, until we have the
> > infrastructure and
> > tools developed to make MAC truly manageable by
> > typical end users. Not
> > an inherent problem.
>
> Oh come on! I've been hearing that saw continueously
> since 1987. Mandatory MAC (as opposed to targeted MAC)
> is hard on sysadmins. It will remain so. SELinux,
> Trusted Solaris, Trusted IRIX, and anyone else are all
> a pain in the bum and will remain so.
Grouping SELinux with previous trusted systems doesn't make sense to me.
Administering non-MLS SELinux systems is already easier than
administering traditional MAC systems like Trusted Solaris and Trusted
IRIX. Much of the pain from tradition MAC systems comes from the
mismatch between MLS and the real world of unix and unix administration.
I know that you will disagree with this because you believe that MLS and
BIBA are simplier than TE, but that doesn't match my experience or the
feedback we get from our customers.
Karl
--
Karl MacMillan
Tresys Technology
www.tresys.com
> Tools are going
> to help only to a limited extent, they never make all
> the pain go away. Smarter people than I have been
> working on the problem for 20 years and I believe that
> it's safe to say there is no magic wand that will
> make the problems all go away.
>
> I like MAC. I like the Iron Fist approach to software
> security. I just don't believe that there's a glove
> with velvet thick enough to please the masses.
>
>
> Casey Schaufler
> casey@schaufler-ca.com
^ permalink raw reply [flat|nested] 173+ messages in thread
* Re: Some Concrete AppArmor Questions - was Re: [RFC][PATCH 0/11] security: AppArmor - Overview
2006-04-28 16:04 ` Stephen Hemminger
@ 2006-04-28 21:49 ` James Morris
0 siblings, 0 replies; 173+ messages in thread
From: James Morris @ 2006-04-28 21:49 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: linux-kernel
On Fri, 28 Apr 2006, Stephen Hemminger wrote:
> SELinux on the other hand takes a real security view of the world. If
> you have ever worked with real security environment with "need to
> know", you will understand that it is hard to keep secure and requires
> too many restrictions for normal users.
It depends on the type of SELinux policy you have loaded. The one which
most people use, "targeted policy", is aimed at confining network facing
services while allowing the local user level stuff to run generally
without confinement.
- James
--
James Morris
<jmorris@namei.org>
^ permalink raw reply [flat|nested] 173+ messages in thread
end of thread, other threads:[~2006-04-28 21:49 UTC | newest]
Thread overview: 173+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-19 17:49 [RFC][PATCH 0/11] security: AppArmor - Overview Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 1/11] security: AppArmor - Integrate into kbuild Tony Jones
2006-04-19 17:57 ` Arjan van de Ven
2006-04-19 18:10 ` Tony Jones
2006-04-19 18:35 ` Valdis.Kletnieks
2006-04-19 19:55 ` Adrian Bunk
2006-04-19 20:52 ` Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 2/11] security: AppArmor - Core headers Tony Jones
2006-04-19 18:01 ` Arjan van de Ven
2006-04-20 17:43 ` Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 3/11] security: AppArmor - LSM interface Tony Jones
2006-04-19 18:05 ` Arjan van de Ven
2006-04-19 17:49 ` [RFC][PATCH 4/11] security: AppArmor - Core access controls Tony Jones
2006-04-19 18:10 ` Arjan van de Ven
2006-04-19 18:57 ` Crispin Cowan
2006-04-19 23:05 ` Rik van Riel
2006-04-19 23:18 ` Seth Arnold
2006-04-19 23:21 ` Rik van Riel
2006-04-19 23:50 ` Crispin Cowan
2006-04-20 12:33 ` Stephen Smalley
2006-04-20 16:27 ` Lars Marowsky-Bree
2006-04-20 17:39 ` Tony Jones
2006-04-19 19:32 ` Jan Engelhardt
2006-04-19 19:50 ` Stephen Smalley
2006-04-20 9:40 ` Al Viro
2006-04-20 11:40 ` Serge E. Hallyn
2006-04-20 21:39 ` Tony Jones
2006-04-19 17:49 ` [RFC][PATCH 5/11] security: AppArmor - Filesystem Tony Jones
2006-04-21 21:13 ` Amy Griffis
2006-04-19 17:49 ` [RFC][PATCH 6/11] security: AppArmor - Userspace interface Tony Jones
2006-04-20 21:39 ` Pavel Machek
2006-04-21 18:01 ` Tony Jones
2006-04-21 18:41 ` Pavel Machek
2006-04-19 17:50 ` [RFC][PATCH 7/11] security: AppArmor - Misc (capabilities, data structures) Tony Jones
2006-04-19 18:16 ` Stephen Hemminger
2006-04-19 17:50 ` [RFC][PATCH 8/11] security: AppArmor - Pathname matching submodule Tony Jones
2006-04-19 17:50 ` [RFC][PATCH 9/11] security: AppArmor - Audit changes Tony Jones
2006-04-21 21:21 ` Amy Griffis
2006-04-22 0:13 ` Steve Grubb
2006-04-22 0:19 ` Tony Jones
2006-04-19 17:50 ` [RFC][PATCH 10/11] security: AppArmor - Add flags to d_path Tony Jones
2006-04-19 22:12 ` Christoph Hellwig
2006-04-20 5:36 ` Tony Jones
2006-04-20 8:26 ` Arjan van de Ven
2006-04-20 16:43 ` Tony Jones
2006-04-20 17:04 ` Christoph Hellwig
2006-04-20 17:50 ` Tony Jones
2006-04-21 12:16 ` Stephen Smalley
2006-04-24 13:05 ` Alan Cox
2006-04-19 17:50 ` [RFC][PATCH 11/11] security: AppArmor - Export namespace semaphore Tony Jones
2006-04-19 22:10 ` Christoph Hellwig
2006-04-20 12:39 ` Stephen Smalley
2006-04-20 12:46 ` Serge E. Hallyn
2006-04-20 12:05 ` Stephen Smalley
2006-04-20 13:21 ` Serge E. Hallyn
2006-04-20 12:48 ` Stephen Smalley
2006-04-20 12:58 ` Stephen Smalley
2006-04-20 22:11 ` Linda A. Walsh
2006-04-20 23:05 ` Christoph Hellwig
2006-04-21 1:29 ` Linda A. Walsh
2006-04-21 2:09 ` Chris Wright
2006-04-21 5:10 ` Linda Walsh
2006-04-23 12:11 ` Arjan van de Ven
2006-04-21 14:02 ` Stephen Smalley
2006-04-20 19:45 ` Tony Jones
2006-04-20 20:16 ` Serge E. Hallyn
2006-04-20 20:22 ` James Morris
2006-04-20 21:50 ` Linda Walsh
2006-04-20 21:56 ` Al Viro
2006-04-20 23:54 ` James Morris
2006-04-21 13:59 ` Stephen Smalley
2006-04-19 18:14 ` [RFC][PATCH 0/11] security: AppArmor - Overview Arjan van de Ven
2006-04-19 22:32 ` Andi Kleen
2006-04-19 23:00 ` grundig
2006-04-19 23:38 ` Andi Kleen
2006-04-20 1:32 ` Crispin Cowan
2006-04-20 13:00 ` grundig
2006-04-20 13:09 ` Serge E. Hallyn
2006-04-20 13:15 ` Al Viro
2006-04-21 0:11 ` Tony Jones
2006-04-24 13:01 ` Alan Cox
2006-04-20 8:42 ` Arjan van de Ven
2006-04-20 19:26 ` Crispin Cowan
2006-04-20 19:27 ` Chris Wright
2006-04-21 12:18 ` Stephen Smalley
2006-04-21 17:30 ` Chris Wright
2006-04-21 18:07 ` Stephen Smalley
2006-04-21 20:06 ` Valdis.Kletnieks
2006-04-21 20:35 ` Stephen Smalley
2006-04-21 20:44 ` Stephen Smalley
2006-04-21 21:38 ` Dave Neuer
2006-04-22 10:01 ` Thomas Bleher
2006-04-24 4:18 ` Neil Brown
2006-04-24 7:03 ` Theodore Ts'o
2006-04-24 13:04 ` Pavel Machek
2006-04-24 13:43 ` Joshua Brindle
2006-04-24 21:07 ` Stephen Smalley
2006-04-24 23:52 ` Theodore Ts'o
2006-04-25 6:22 ` Arjan van de Ven
2006-04-25 16:45 ` Stephen Smalley
2006-04-25 16:52 ` Arjan van de Ven
2006-04-25 17:43 ` Seth Arnold
2006-04-25 18:34 ` Valdis.Kletnieks
2006-04-25 18:48 ` Stephen Smalley
2006-04-25 18:56 ` Valdis.Kletnieks
2006-04-25 4:25 ` Casey Schaufler
2006-04-25 7:50 ` James Morris
2006-04-25 12:46 ` Theodore Ts'o
2006-04-25 15:06 ` Stephen Smalley
2006-04-25 16:00 ` Casey Schaufler
2006-04-25 16:21 ` Randy.Dunlap
2006-04-26 3:42 ` Casey Schaufler
2006-04-26 12:15 ` Stephen Smalley
2006-04-27 0:21 ` Casey Schaufler
2006-04-27 14:47 ` Karl MacMillan
2006-04-25 17:29 ` Stephen Smalley
2006-04-26 3:56 ` Casey Schaufler
2006-04-26 11:32 ` Stephen Smalley
2006-04-25 16:47 ` Stephen Smalley
2006-04-24 7:14 ` Arjan van de Ven
2006-04-24 8:11 ` Lars Marowsky-Bree
2006-04-25 19:27 ` Seth Arnold
2006-04-24 13:11 ` Joshua Brindle
2006-04-24 13:26 ` Andi Kleen
2006-04-24 13:39 ` Joshua Brindle
2006-04-24 15:16 ` Joshua Brindle
2006-04-24 15:50 ` Tony Jones
2006-04-24 17:03 ` Joshua Brindle
2006-04-25 17:12 ` Valdis.Kletnieks
2006-04-25 17:34 ` Tony Jones
2006-04-24 13:52 ` Alan Cox
2006-04-24 14:09 ` Andi Kleen
2006-04-24 20:45 ` Stephen Smalley
2006-04-25 8:10 ` Neil Brown
2006-04-25 8:28 ` Al Viro
2006-04-25 12:42 ` James Carter
2006-04-25 12:43 ` Andi Kleen
2006-04-25 14:50 ` James Carter
2006-04-25 15:01 ` Stephen Smalley
2006-04-25 18:11 ` Tony Jones
2006-04-25 21:25 ` Stephen Smalley
2006-04-25 17:07 ` Stephen Smalley
2006-04-26 22:15 ` Some Concrete AppArmor Questions - was " Neil Brown
2006-04-26 23:06 ` Ken Brush
2006-04-27 4:15 ` Andi Kleen
2006-04-27 6:52 ` Arjan van de Ven
2006-04-27 7:40 ` Chris Wright
2006-04-27 10:17 ` Chris Wright
2006-04-27 14:42 ` Karl MacMillan
2006-04-27 23:44 ` Chris Wright
2006-04-28 13:02 ` Stephen Smalley
2006-04-28 15:49 ` Casey Schaufler
2006-04-28 16:04 ` Stephen Hemminger
2006-04-28 21:49 ` James Morris
2006-04-28 16:56 ` Karl MacMillan
2006-04-27 16:03 ` Stephen Smalley
2006-04-27 22:38 ` Chris Wright
2006-04-28 13:00 ` Stephen Smalley
2006-04-27 17:43 ` Stephen Smalley
2006-04-27 17:58 ` Ken Brush
2006-04-28 11:28 ` Stephen Smalley
2006-04-28 11:47 ` Andi Kleen
2006-04-28 12:28 ` Stephen Smalley
2006-04-27 11:02 ` Christoph Hellwig
2006-04-27 11:05 ` Andi Kleen
2006-04-20 11:29 ` Serge E. Hallyn
2006-04-20 13:24 ` Christoph Hellwig
2006-04-20 22:32 ` Linda A. Walsh
2006-04-20 12:17 ` Stephen Smalley
2006-04-20 15:38 ` Joshua Brindle
2006-04-20 19:57 ` Crispin Cowan
2006-04-21 13:34 ` Stephen Smalley
2006-04-22 12:27 ` Pavel Machek
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).