]> git.pld-linux.org Git - packages/kernel.git/blame - apparmor-2.6.20.3-v405-fullseries.diff
- applies
[packages/kernel.git] / apparmor-2.6.20.3-v405-fullseries.diff
CommitLineData
443f61e5 1 fs/namespace.c | 3
2 include/linux/audit.h | 5
3 include/linux/mnt_namespace.h | 3
4 kernel/audit.c | 6
5 security/Kconfig | 1
6 security/Makefile | 1
7 security/apparmor/Kbuild | 10
8 security/apparmor/Kconfig | 9
9 security/apparmor/Makefile | 28
10 security/apparmor/apparmor.h | 356 +++++
11 security/apparmor/apparmorfs.c | 432 +++++++
12 security/apparmor/capabilities.c | 71 +
13 security/apparmor/inline.h | 393 ++++++
14 security/apparmor/list.c | 268 ++++
15 security/apparmor/lsm.c | 894 ++++++++++++++
16 security/apparmor/main.c | 1702 ++++++++++++++++++++++++++++
17 security/apparmor/match/Kbuild | 6
18 security/apparmor/match/Makefile | 5
19 security/apparmor/match/match.h | 132 ++
20 security/apparmor/match/match_default.c | 57
21 security/apparmor/match/match_pcre.c | 169 ++
22 security/apparmor/match/pcre_exec.c | 1945 ++++++++++++++++++++++++++++++++
23 security/apparmor/match/pcre_exec.h | 308 +++++
24 security/apparmor/match/pcre_tables.h | 184 +++
25 security/apparmor/module_interface.c | 845 +++++++++++++
26 security/apparmor/module_interface.h | 37
27 security/apparmor/procattr.c | 332 +++++
28 security/apparmor/shared.h | 46
29 28 files changed, 8245 insertions(+), 3 deletions(-)
30Index: b/include/linux/audit.h
31===================================================================
32--- a/include/linux/audit.h
33+++ b/include/linux/audit.h
34@@ -110,6 +110,8 @@
35 #define AUDIT_LAST_KERN_ANOM_MSG 1799
36 #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */
37
38+#define AUDIT_SD 1500 /* AppArmor (SubDomain) audit */
39+
40 #define AUDIT_KERNEL 2000 /* Asynchronous audit record. NOT A REQUEST. */
41
42 /* Rule flags */
43@@ -478,6 +480,9 @@ extern void audit_log(struct audit_
44 __attribute__((format(printf,4,5)));
45
46 extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
47+extern void audit_log_vformat(struct audit_buffer *ab,
48+ const char *fmt, va_list args)
49+ __attribute__((format(printf,2,0)));
50 extern void audit_log_format(struct audit_buffer *ab,
51 const char *fmt, ...)
52 __attribute__((format(printf,2,3)));
53Index: b/kernel/audit.c
54===================================================================
55--- a/kernel/audit.c
56+++ b/kernel/audit.c
57@@ -956,8 +956,7 @@ static inline int audit_expand(struct au
58 * will be called a second time. Currently, we assume that a printk
59 * can't format message larger than 1024 bytes, so we don't either.
60 */
61-static void audit_log_vformat(struct audit_buffer *ab, const char *fmt,
62- va_list args)
63+void audit_log_vformat(struct audit_buffer *ab, const char *fmt, va_list args)
64 {
65 int len, avail;
66 struct sk_buff *skb;
67@@ -1213,3 +1212,6 @@ EXPORT_SYMBOL(audit_log_start);
68 EXPORT_SYMBOL(audit_log_end);
69 EXPORT_SYMBOL(audit_log_format);
70 EXPORT_SYMBOL(audit_log);
71+EXPORT_SYMBOL_GPL(audit_log_vformat);
72+EXPORT_SYMBOL_GPL(audit_log_untrustedstring);
73+EXPORT_SYMBOL_GPL(audit_log_d_path);
74Index: b/fs/namespace.c
75===================================================================
76--- a/fs/namespace.c
77+++ b/fs/namespace.c
78@@ -37,7 +37,8 @@ static int event;
79 static struct list_head *mount_hashtable __read_mostly;
80 static int hash_mask __read_mostly, hash_bits __read_mostly;
81 static struct kmem_cache *mnt_cache __read_mostly;
82-static struct rw_semaphore namespace_sem;
83+struct rw_semaphore namespace_sem;
84+EXPORT_SYMBOL_GPL(namespace_sem);
85
86 /* /sys/fs */
87 decl_subsys(fs, NULL, NULL);
88Index: b/include/linux/mnt_namespace.h
89===================================================================
90--- a/include/linux/mnt_namespace.h
91+++ b/include/linux/mnt_namespace.h
92@@ -6,6 +6,9 @@
93 #include <linux/sched.h>
94 #include <linux/nsproxy.h>
95
96+/* exported for AppArmor (SubDomain) */
97+extern struct rw_semaphore namespace_sem;
98+
99 struct mnt_namespace {
100 atomic_t count;
101 struct vfsmount * root;
102Index: b/security/Makefile
103===================================================================
104--- a/security/Makefile
105+++ b/security/Makefile
106@@ -4,6 +4,7 @@
107
108 obj-$(CONFIG_KEYS) += keys/
109 subdir-$(CONFIG_SECURITY_SELINUX) += selinux
110+obj-$(CONFIG_SECURITY_APPARMOR) += commoncap.o apparmor/
111
112 # if we don't select a security model, use the default capabilities
113 ifneq ($(CONFIG_SECURITY),y)
114Index: b/security/Kconfig
115===================================================================
116--- a/security/Kconfig
117+++ b/security/Kconfig
118@@ -94,6 +94,7 @@ config SECURITY_ROOTPLUG
119 If you are unsure how to answer this question, answer N.
120
121 source security/selinux/Kconfig
122+source security/apparmor/Kconfig
123
124 endmenu
125
126Index: b/security/apparmor/Kbuild
127===================================================================
128--- /dev/null
129+++ b/security/apparmor/Kbuild
130@@ -0,0 +1,10 @@
131+# Makefile for AppArmor Linux Security Module
132+#
133+EXTRA_CFLAGS += -DAPPARMOR_VERSION=\"${APPARMOR_VER}\"
134+
135+obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
136+
137+apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o capabilities.o \
138+ module_interface.o
139+
140+obj-$(CONFIG_SECURITY_APPARMOR) += match/
141Index: b/security/apparmor/Kconfig
142===================================================================
143--- /dev/null
144+++ b/security/apparmor/Kconfig
145@@ -0,0 +1,9 @@
146+config SECURITY_APPARMOR
147+ tristate "AppArmor support"
148+ depends on SECURITY!=n
149+ help
150+ This enables the AppArmor security module.
151+ Required userspace tools (if they are not included in your
152+ distribution) and further information may be found at
153+ <http://forge.novell.com/modules/xfmod/project/?apparmor>
154+ If you are unsure how to answer this question, answer N.
155Index: b/security/apparmor/Makefile
156===================================================================
157--- /dev/null
158+++ b/security/apparmor/Makefile
159@@ -0,0 +1,28 @@
160+# Makefile for AppArmor Linux Security Module
161+#
162+# kernel build Makefile is the Kbuild file
163+
164+REPO_VERSION := $(shell if [ -x /usr/bin/svn ] ; then \
165+ /usr/bin/svn info . 2> /dev/null | grep "^Last Changed Rev:" | sed "s/^Last Changed Rev: //" ; \
166+ fi)
167+
168+ifeq ("${REPO_VERSION}", "")
169+REPO_VERSION := "unknown"
170+endif
171+
172+KERNELVER := $(shell uname -r)
173+
174+KERNELDIR := /lib/modules/${KERNELVER}/build
175+
176+all:
177+ $(MAKE) -C $(KERNELDIR) M=`pwd` modules CONFIG_SECURITY_APPARMOR=m \
178+ APPARMOR_VER=${REPO_VERSION}
179+ mv apparmor.ko apparmor-${KERNELVER}.ko
180+ mv match/aamatch_pcre.ko aamatch_pcre-${KERNELVER}.ko
181+
182+clean:
183+ rm -f *~ *.o *.ko *.mod.c .*.cmd Module{s,}.symvers \
184+ match/*~ match/*.o match/*.ko match/.*.cmd match/*.mod.c
185+ rm -rf .tmp_versions
186+
187+
188Index: b/security/apparmor/apparmor.h
189===================================================================
190--- /dev/null
191+++ b/security/apparmor/apparmor.h
192@@ -0,0 +1,356 @@
193+/*
194+ * Copyright (C) 1998-2005 Novell/SUSE
195+ *
196+ * This program is free software; you can redistribute it and/or
197+ * modify it under the terms of the GNU General Public License as
198+ * published by the Free Software Foundation, version 2 of the
199+ * License.
200+ *
201+ * AppArmor internal prototypes
202+ */
203+
204+#ifndef __APPARMOR_H
205+#define __APPARMOR_H
206+
207+#include <linux/fs.h> /* Include for defn of iattr */
208+#include <linux/binfmts.h> /* defn of linux_binprm */
209+#include <linux/rcupdate.h>
210+
211+#include "shared.h"
212+
213+/* Control parameters (0 or 1), settable thru module/boot flags or
214+ * via /sys/kernel/security/apparmor/control */
215+extern int apparmor_complain;
216+extern int apparmor_debug;
217+extern int apparmor_audit;
218+extern int apparmor_logsyscall;
219+
220+/* PIPEFS_MAGIC */
221+#include <linux/pipe_fs_i.h>
222+/* from net/socket.c */
223+#define SOCKFS_MAGIC 0x534F434B
224+/* from inotify.c */
225+#define INOTIFYFS_MAGIC 0xBAD1DEA
226+
227+#define VALID_FSTYPE(inode) ((inode)->i_sb->s_magic != PIPEFS_MAGIC && \
228+ (inode)->i_sb->s_magic != SOCKFS_MAGIC && \
229+ (inode)->i_sb->s_magic != INOTIFYFS_MAGIC)
230+
231+#define PROFILE_COMPLAIN(_profile) \
232+ (apparmor_complain == 1 || ((_profile) && (_profile)->flags.complain))
233+
234+#define SUBDOMAIN_COMPLAIN(_sd) \
235+ (apparmor_complain == 1 || \
236+ ((_sd) && (_sd)->active && (_sd)->active->flags.complain))
237+
238+#define PROFILE_AUDIT(_profile) \
239+ (apparmor_audit == 1 || ((_profile) && (_profile)->flags.audit))
240+
241+#define SUBDOMAIN_AUDIT(_sd) \
242+ (apparmor_audit == 1 || \
243+ ((_sd) && (_sd)->active && (_sd)->active->flags.audit))
244+
245+/*
246+ * DEBUG remains global (no per profile flag) since it is mostly used in sysctl
247+ * which is not related to profile accesses.
248+ */
249+
250+#define AA_DEBUG(fmt, args...) \
251+ do { \
252+ if (apparmor_debug) \
253+ printk(KERN_DEBUG "AppArmor: " fmt, ##args); \
254+ } while (0)
255+#define AA_INFO(fmt, args...) printk(KERN_INFO "AppArmor: " fmt, ##args)
256+#define AA_WARN(fmt, args...) printk(KERN_WARNING "AppArmor: " fmt, ##args)
257+#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args)
258+
259+
260+/* apparmor logged syscall reject caching */
261+enum aasyscall {
262+ AA_SYSCALL_PTRACE,
263+ AA_SYSCALL_SYSCTL_WRITE,
264+ AA_SYSCALL_MOUNT,
265+ AA_SYSCALL_UMOUNT
266+};
267+
268+#define AA_SYSCALL_TO_MASK(X) (1 << (X))
269+
270+
271+/* basic AppArmor data structures */
272+
273+struct flagval {
274+ int debug;
275+ int complain;
276+ int audit;
277+};
278+
279+enum entry_match_type {
280+ aa_entry_literal,
281+ aa_entry_tailglob,
282+ aa_entry_pattern,
283+ aa_entry_invalid
284+};
285+
286+/* struct aa_entry - file ACL *
287+ * @filename: filename controlled by this ACL
288+ * @mode: permissions granted by ACL
289+ * @type: type of match to perform against @filename
290+ * @extradata: any extra data needed by an extended matching type
291+ * @list: list the ACL is on
292+ * @listp: permission partitioned lists this ACL is on.
293+ *
294+ * Each entry describes a file and an allowed access mode.
295+ */
296+struct aa_entry {
297+ char *filename;
298+ int mode; /* mode is 'or' of READ, WRITE, EXECUTE,
299+ * INHERIT, UNCONSTRAINED, and LIBRARY
300+ * (meaning don't prefetch). */
301+
302+ enum entry_match_type type;
303+ void *extradata;
304+
305+ struct list_head list;
306+ struct list_head listp[POS_AA_FILE_MAX + 1];
307+};
308+
309+#define AA_SECURE_EXEC_NEEDED 0x00000001
310+
311+#define AA_EXEC_MODIFIER_MASK(mask) ((mask) & AA_EXEC_MODIFIERS)
312+#define AA_EXEC_MASK(mask) ((mask) & (AA_MAY_EXEC | AA_EXEC_MODIFIERS))
313+#define AA_EXEC_UNSAFE_MASK(mask) ((mask) & (AA_MAY_EXEC | AA_EXEC_MODIFIERS |\
314+ AA_EXEC_UNSAFE))
315+
316+/* struct aaprofile - basic confinement data
317+ * @parent: non refcounted pointer to parent profile
318+ * @name: the profiles name
319+ * @file_entry: file ACL
320+ * @file_entryp: vector of file ACL by permission granted
321+ * @list: list this profile is on
322+ * @sub: profiles list of subprofiles (HATS)
323+ * @flags: flags controlling profile behavior
324+ * @null_profile: if needed per profile learning and null confinement profile
325+ * @isstale: flag to indicate the profile is stale
326+ * @num_file_entries: number of file entries the profile contains
327+ * @num_file_pentries: number of file entries for each partitioned list
328+ * @capabilities: capabilities granted by the process
329+ * @rcu: rcu head used when freeing the profile
330+ * @count: reference count of the profile
331+ *
332+ * The AppArmor profile contains the basic confinement data. Each profile
333+ * has a name and potentially a list of profile entries. The profiles are
334+ * connected in a list
335+ */
336+struct aaprofile {
337+ struct aaprofile *parent;
338+ char *name;
339+
340+ struct list_head file_entry;
341+ struct list_head file_entryp[POS_AA_FILE_MAX + 1];
342+ struct list_head list;
343+ struct list_head sub;
344+ struct flagval flags;
345+ struct aaprofile *null_profile;
346+ int isstale;
347+
348+ int num_file_entries;
349+ int num_file_pentries[POS_AA_FILE_MAX + 1];
350+
351+ kernel_cap_t capabilities;
352+
353+ struct rcu_head rcu;
354+
355+ struct kref count;
356+};
357+
358+enum aafile_type {
359+ aa_file_default,
360+ aa_file_shmem
361+};
362+
363+/**
364+ * aafile - file pointer confinement data
365+ *
366+ * Data structure assigned to each open file (by apparmor_file_alloc_security)
367+ */
368+struct aafile {
369+ enum aafile_type type;
370+ struct aaprofile *profile;
371+};
372+
373+/**
374+ * struct subdomain - primary label for confined tasks
375+ * @active: the current active profile
376+ * @hat_magic: the magic token controling the ability to leave a hat
377+ * @list: list this subdomain is on
378+ * @task: task that the subdomain confines
379+ * @cached_caps: caps that have previously generated log entries
380+ * @cached_syscalls: mediated syscalls that have previously been logged
381+ *
382+ * Contains the tasks current active profile (which could change due to
383+ * change_hat). Plus the hat_magic needed during change_hat.
384+ *
385+ * N.B AppArmor's previous product name SubDomain was derived from the name
386+ * of this structure/concept (changehat reducing a task into a sub-domain).
387+ */
388+struct subdomain {
389+ struct aaprofile *active; /* The current active profile */
390+ u32 hat_magic; /* used with change_hat */
391+ struct list_head list; /* list of subdomains */
392+ struct task_struct *task;
393+
394+ kernel_cap_t cached_caps;
395+ unsigned int cached_syscalls;
396+};
397+
398+typedef int (*aa_iter) (struct subdomain *, void *);
399+
400+/* aa_path_data
401+ * temp (cookie) data used by aa_path_* functions, see inline.h
402+ */
403+struct aa_path_data {
404+ struct dentry *root, *dentry;
405+ struct mnt_namespace *mnt_namespace;
406+ struct list_head *head, *pos;
407+ int errno;
408+};
409+
410+#define AA_SUBDOMAIN(sec) ((struct subdomain*)(sec))
411+#define AA_PROFILE(sec) ((struct aaprofile*)(sec))
412+
413+/* Lock protecting access to 'struct subdomain' accesses */
414+extern spinlock_t sd_lock;
415+
416+extern struct aaprofile *null_complain_profile;
417+
418+/* aa_audit - AppArmor auditing structure
419+ * Structure is populated by access control code and passed to aa_audit which
420+ * provides for a single point of logging.
421+ */
422+
423+struct aa_audit {
424+ unsigned short type, flags;
425+ unsigned int result;
426+ gfp_t gfp_mask;
427+ int error_code;
428+
429+ const char *name;
430+ unsigned int ival;
431+ union {
432+ const void *pval;
433+ va_list vaval;
434+ };
435+};
436+
437+/* audit types */
438+#define AA_AUDITTYPE_FILE 1
439+#define AA_AUDITTYPE_DIR 2
440+#define AA_AUDITTYPE_ATTR 3
441+#define AA_AUDITTYPE_XATTR 4
442+#define AA_AUDITTYPE_LINK 5
443+#define AA_AUDITTYPE_CAP 6
444+#define AA_AUDITTYPE_MSG 7
445+#define AA_AUDITTYPE_SYSCALL 8
446+#define AA_AUDITTYPE__END 9
447+
448+/* audit flags */
449+#define AA_AUDITFLAG_AUDITSS_SYSCALL 1 /* log syscall context */
450+#define AA_AUDITFLAG_LOGERR 2 /* log operations that failed due to
451+ non permission errors */
452+
453+#define HINT_UNKNOWN_HAT "unknown_hat"
454+#define HINT_FORK "fork"
455+#define HINT_MANDPROF "missing_mandatory_profile"
456+#define HINT_CHGPROF "changing_profile"
457+
458+#define LOG_HINT(p, gfp, hint, fmt, args...) \
459+ do {\
460+ aa_audit_message(p, gfp, 0, \
461+ "LOGPROF-HINT " hint " " fmt, ##args);\
462+ } while(0)
463+
464+/* directory op type, for aa_perm_dir */
465+enum aa_diroptype {
466+ aa_dir_mkdir,
467+ aa_dir_rmdir
468+};
469+
470+/* xattr op type, for aa_xattr */
471+enum aa_xattroptype {
472+ aa_xattr_get,
473+ aa_xattr_set,
474+ aa_xattr_list,
475+ aa_xattr_remove
476+};
477+
478+#define BASE_PROFILE(p) ((p)->parent ? (p)->parent : (p))
479+#define IN_SUBPROFILE(p) ((p)->parent)
480+
481+/* main.c */
482+extern int alloc_null_complain_profile(void);
483+extern void free_null_complain_profile(void);
484+extern int attach_nullprofile(struct aaprofile *profile);
485+extern int aa_audit_message(struct aaprofile *active, gfp_t gfp, int,
486+ const char *, ...);
487+extern int aa_audit_syscallreject(struct aaprofile *active, gfp_t gfp,
488+ enum aasyscall call);
489+extern int aa_audit(struct aaprofile *active, const struct aa_audit *);
490+extern char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt);
491+
492+extern int aa_attr(struct aaprofile *active, struct dentry *dentry,
493+ struct iattr *iattr);
494+extern int aa_xattr(struct aaprofile *active, struct dentry *dentry,
495+ const char *xattr, enum aa_xattroptype xattroptype);
496+extern int aa_capability(struct aaprofile *active, int cap);
497+extern int aa_perm(struct aaprofile *active, struct dentry *dentry,
498+ struct vfsmount *mnt, int mask);
499+extern int aa_perm_nameidata(struct aaprofile *active, struct nameidata *nd,
500+ int mask);
501+extern int aa_perm_dentry(struct aaprofile *active, struct dentry *dentry,
502+ int mask);
503+extern int aa_perm_dir(struct aaprofile *active, struct dentry *dentry,
504+ enum aa_diroptype diroptype);
505+extern int aa_link(struct aaprofile *active,
506+ struct dentry *link, struct dentry *target);
507+extern int aa_fork(struct task_struct *p);
508+extern int aa_register(struct linux_binprm *bprm);
509+extern void aa_release(struct task_struct *p);
510+extern int aa_change_hat(const char *id, u32 hat_magic);
511+extern int aa_associate_filp(struct file *filp);
512+
513+/* list.c */
514+extern struct aaprofile *aa_profilelist_find(const char *name);
515+extern int aa_profilelist_add(struct aaprofile *profile);
516+extern struct aaprofile *aa_profilelist_remove(const char *name);
517+extern void aa_profilelist_release(void);
518+extern struct aaprofile *aa_profilelist_replace(struct aaprofile *profile);
519+extern void aa_profile_dump(struct aaprofile *);
520+extern void aa_profilelist_dump(void);
521+extern void aa_subdomainlist_add(struct subdomain *);
522+extern void aa_subdomainlist_remove(struct subdomain *);
523+extern void aa_subdomainlist_iterate(aa_iter, void *);
524+extern void aa_subdomainlist_iterateremove(aa_iter, void *);
525+extern void aa_subdomainlist_release(void);
526+
527+/* module_interface.c */
528+extern ssize_t aa_file_prof_add(void *, size_t);
529+extern ssize_t aa_file_prof_repl(void *, size_t);
530+extern ssize_t aa_file_prof_remove(const char *, size_t);
531+extern void free_aaprofile(struct aaprofile *profile);
532+extern void free_aaprofile_kref(struct kref *kref);
533+
534+/* procattr.c */
535+extern size_t aa_getprocattr(struct aaprofile *active, char *str, size_t size);
536+extern int aa_setprocattr_changehat(char *hatinfo, size_t infosize);
537+extern int aa_setprocattr_setprofile(struct task_struct *p, char *profilename,
538+ size_t profilesize);
539+
540+/* apparmorfs.c */
541+extern int create_apparmorfs(void);
542+extern void destroy_apparmorfs(void);
543+
544+/* capabilities.c */
545+extern const char *capability_to_name(unsigned int cap);
546+extern const char *syscall_to_name(enum aasyscall call);
547+
548+#endif /* __APPARMOR_H */
549Index: b/security/apparmor/apparmorfs.c
550===================================================================
551--- /dev/null
552+++ b/security/apparmor/apparmorfs.c
553@@ -0,0 +1,432 @@
554+/*
555+ * Copyright (C) 2005 Novell/SUSE
556+ *
557+ * This program is free software; you can redistribute it and/or
558+ * modify it under the terms of the GNU General Public License as
559+ * published by the Free Software Foundation, version 2 of the
560+ * License.
561+ *
562+ * AppArmor filesystem (part of securityfs)
563+ */
564+
565+#include <linux/security.h>
566+#include <linux/vmalloc.h>
567+#include <linux/module.h>
568+#include <linux/seq_file.h>
569+#include <asm/uaccess.h>
570+
571+#include "apparmor.h"
572+#include "inline.h"
573+#include "match/match.h"
574+
575+#define SECFS_AA "apparmor"
576+static struct dentry *aafs_dentry = NULL;
577+
578+/* profile */
579+extern struct seq_operations apparmorfs_profiles_op;
580+static int aa_prof_open(struct inode *inode, struct file *file);
581+static int aa_prof_release(struct inode *inode, struct file *file);
582+
583+static struct file_operations apparmorfs_profiles_fops = {
584+ .open = aa_prof_open,
585+ .read = seq_read,
586+ .llseek = seq_lseek,
587+ .release = aa_prof_release,
588+};
589+
590+/* matching */
591+static ssize_t aa_matching_read(struct file *file, char __user *buf,
592+ size_t size, loff_t *ppos);
593+
594+static struct file_operations apparmorfs_matching_fops = {
595+ .read = aa_matching_read,
596+};
597+
598+
599+/* interface */
600+static ssize_t aa_profile_load(struct file *f, const char __user *buf,
601+ size_t size, loff_t *pos);
602+static ssize_t aa_profile_replace(struct file *f, const char __user *buf,
603+ size_t size, loff_t *pos);
604+static ssize_t aa_profile_remove(struct file *f, const char __user *buf,
605+ size_t size, loff_t *pos);
606+
607+static struct file_operations apparmorfs_profile_load = {
608+ .write = aa_profile_load
609+};
610+
611+static struct file_operations apparmorfs_profile_replace = {
612+ .write = aa_profile_replace
613+};
614+
615+static struct file_operations apparmorfs_profile_remove = {
616+ .write = aa_profile_remove
617+};
618+
619+
620+/* control */
621+static u64 aa_control_get(void *data);
622+static void aa_control_set(void *data, u64 val);
623+
624+DEFINE_SIMPLE_ATTRIBUTE(apparmorfs_control_fops, aa_control_get,
625+ aa_control_set, "%lld\n");
626+
627+
628+
629+/* table of static entries */
630+
631+static struct root_entry {
632+ const char *name;
633+ int mode;
634+ int access;
635+ struct file_operations *fops;
636+ void *data;
637+
638+ /* internal fields */
639+ struct dentry *dentry;
640+ int parent_index;
641+} root_entries[] = {
642+ /* our root, normally /sys/kernel/security/apparmor */
643+ {SECFS_AA, S_IFDIR, 0550}, /* DO NOT EDIT/MOVE */
644+
645+ /* interface for obtaining list of profiles currently loaded */
646+ {"profiles", S_IFREG, 0440, &apparmorfs_profiles_fops,
647+ NULL},
648+
649+ /* interface for obtaining matching features supported */
650+ {"matching", S_IFREG, 0440, &apparmorfs_matching_fops,
651+ NULL},
652+
653+ /* interface for loading/removing/replacing profiles */
654+ {".load", S_IFREG, 0640, &apparmorfs_profile_load,
655+ NULL},
656+ {".replace", S_IFREG, 0640, &apparmorfs_profile_replace,
657+ NULL},
658+ {".remove", S_IFREG, 0640, &apparmorfs_profile_remove,
659+ NULL},
660+
661+ /* interface for setting binary config values */
662+ {"control", S_IFDIR, 0550},
663+ {"complain", S_IFREG, 0640, &apparmorfs_control_fops,
664+ &apparmor_complain},
665+ {"audit", S_IFREG, 0640, &apparmorfs_control_fops,
666+ &apparmor_audit},
667+ {"debug", S_IFREG, 0640, &apparmorfs_control_fops,
668+ &apparmor_debug},
669+ {"logsyscall", S_IFREG, 0640, &apparmorfs_control_fops,
670+ &apparmor_logsyscall},
671+ {NULL, S_IFDIR, 0},
672+
673+ /* root end */
674+ {NULL, S_IFDIR, 0}
675+};
676+
677+#define AAFS_DENTRY root_entries[0].dentry
678+
679+static const unsigned int num_entries =
680+ sizeof(root_entries) / sizeof(struct root_entry);
681+
682+
683+
684+static int aa_prof_open(struct inode *inode, struct file *file)
685+{
686+ return seq_open(file, &apparmorfs_profiles_op);
687+}
688+
689+
690+static int aa_prof_release(struct inode *inode, struct file *file)
691+{
692+ return seq_release(inode, file);
693+}
694+
695+static ssize_t aa_matching_read(struct file *file, char __user *buf,
696+ size_t size, loff_t *ppos)
697+{
698+ const char *matching = aamatch_features();
699+
700+ return simple_read_from_buffer(buf, size, ppos, matching,
701+ strlen(matching));
702+}
703+
704+static char *aa_simple_write_to_buffer(const char __user *userbuf,
705+ size_t alloc_size, size_t copy_size,
706+ loff_t *pos, const char *msg)
707+{
708+ struct aaprofile *active;
709+ char *data;
710+
711+ if (*pos != 0) {
712+ /* only writes from pos 0, that is complete writes */
713+ data = ERR_PTR(-ESPIPE);
714+ goto out;
715+ }
716+
717+ /* Don't allow confined processes to load/replace/remove profiles.
718+ * No sane person would add rules allowing this to a profile
719+ * but we enforce the restriction anyways.
720+ */
721+ rcu_read_lock();
722+ active = get_activeptr_rcu();
723+ if (active) {
724+ AA_WARN("REJECTING access to profile %s (%s(%d) "
725+ "profile %s active %s)\n",
726+ msg, current->comm, current->pid,
727+ BASE_PROFILE(active)->name, active->name);
728+
729+ data = ERR_PTR(-EPERM);
730+ goto out;
731+ }
732+ rcu_read_unlock();
733+
734+ data = vmalloc(alloc_size);
735+ if (data == NULL) {
736+ data = ERR_PTR(-ENOMEM);
737+ goto out;
738+ }
739+
740+ if (copy_from_user(data, userbuf, copy_size)) {
741+ vfree(data);
742+ data = ERR_PTR(-EFAULT);
743+ goto out;
744+ }
745+
746+out:
747+ return data;
748+}
749+
750+static ssize_t aa_profile_load(struct file *f, const char __user *buf,
751+ size_t size, loff_t *pos)
752+{
753+ char *data;
754+ ssize_t error;
755+
756+ data = aa_simple_write_to_buffer(buf, size, size, pos, "load");
757+
758+ if (!IS_ERR(data)) {
759+ error = aa_file_prof_add(data, size);
760+ vfree(data);
761+ } else {
762+ error = PTR_ERR(data);
763+ }
764+
765+ return error;
766+}
767+
768+static ssize_t aa_profile_replace(struct file *f, const char __user *buf,
769+ size_t size, loff_t *pos)
770+{
771+ char *data;
772+ ssize_t error;
773+
774+ data = aa_simple_write_to_buffer(buf, size, size, pos, "replacement");
775+
776+ if (!IS_ERR(data)) {
777+ error = aa_file_prof_repl(data, size);
778+ vfree(data);
779+ } else {
780+ error = PTR_ERR(data);
781+ }
782+
783+ return error;
784+}
785+
786+static ssize_t aa_profile_remove(struct file *f, const char __user *buf,
787+ size_t size, loff_t *pos)
788+{
789+ char *data;
790+ ssize_t error;
791+
792+ /* aa_file_prof_remove needs a null terminated string so 1 extra
793+ * byte is allocated and null the copied data is then null terminated
794+ */
795+ data = aa_simple_write_to_buffer(buf, size+1, size, pos, "removal");
796+
797+ if (!IS_ERR(data)) {
798+ data[size] = 0;
799+ error = aa_file_prof_remove(data, size);
800+ vfree(data);
801+ } else {
802+ error = PTR_ERR(data);
803+ }
804+
805+ return error;
806+}
807+
808+static u64 aa_control_get(void *data)
809+{
810+ return *(int *)data;
811+}
812+
813+static void aa_control_set(void *data, u64 val)
814+{
815+ if (val > 1)
816+ val = 1;
817+
818+ *(int*)data = (int)val;
819+}
820+
821+static void clear_apparmorfs(void)
822+{
823+ unsigned int i;
824+
825+ for (i=0; i < num_entries;i++) {
826+ unsigned int index;
827+
828+ if (root_entries[i].mode == S_IFDIR) {
829+ if (root_entries[i].name)
830+ /* defer dir free till all sub-entries freed */
831+ continue;
832+ else
833+ /* cleanup parent */
834+ index = root_entries[i].parent_index;
835+ } else {
836+ index = i;
837+ }
838+
839+ if (root_entries[index].dentry) {
840+ securityfs_remove(root_entries[index].dentry);
841+
842+ AA_DEBUG("%s: deleted apparmorfs entry name=%s "
843+ "dentry=%p\n",
844+ __FUNCTION__,
845+ root_entries[index].name,
846+ root_entries[index].dentry);
847+
848+ root_entries[index].dentry = NULL;
849+ root_entries[index].parent_index = 0;
850+ }
851+ }
852+}
853+
854+static int populate_apparmorfs(struct dentry *root)
855+{
856+ unsigned int i, parent_index, depth;
857+
858+ for (i = 0; i < num_entries; i++) {
859+ root_entries[i].dentry = NULL;
860+ root_entries[i].parent_index = 0;
861+ }
862+
863+ /* 1. Verify entry 0 is valid [sanity check] */
864+ if (num_entries == 0 ||
865+ !root_entries[0].name ||
866+ strcmp(root_entries[0].name, SECFS_AA) != 0 ||
867+ root_entries[0].mode != S_IFDIR) {
868+ AA_ERROR("%s: root entry 0 is not SECFS_AA/dir\n",
869+ __FUNCTION__);
870+ goto error;
871+ }
872+
873+ /* 2. Build back pointers */
874+ parent_index = 0;
875+ depth = 1;
876+
877+ for (i = 1; i < num_entries; i++) {
878+ root_entries[i].parent_index = parent_index;
879+
880+ if (root_entries[i].name &&
881+ root_entries[i].mode == S_IFDIR) {
882+ depth++;
883+ parent_index = i;
884+ } else if (!root_entries[i].name) {
885+ if (root_entries[i].mode != S_IFDIR || depth == 0) {
886+ AA_ERROR("%s: root_entry %d invalid (%u %d)",
887+ __FUNCTION__, i,
888+ root_entries[i].mode,
889+ root_entries[i].parent_index);
890+ goto error;
891+ }
892+
893+ depth--;
894+ parent_index = root_entries[parent_index].parent_index;
895+ }
896+ }
897+
898+ if (depth != 0) {
899+ AA_ERROR("%s: root_entry table not correctly terminated\n",
900+ __FUNCTION__);
901+ goto error;
902+ }
903+
904+ /* 3. Create root (parent=NULL) */
905+ root_entries[0].dentry = securityfs_create_file(
906+ root_entries[0].name,
907+ root_entries[0].mode |
908+ root_entries[0].access,
909+ NULL, NULL, NULL);
910+
911+ if (IS_ERR(root_entries[0].dentry))
912+ goto error;
913+ else
914+ AA_DEBUG("%s: created securityfs/apparmor [dentry=%p]\n",
915+ __FUNCTION__, root_entries[0].dentry);
916+
917+
918+ /* 4. create remaining nodes */
919+ for (i = 1; i < num_entries; i++) {
920+ struct dentry *parent;
921+ void *data = NULL;
922+ struct file_operations *fops = NULL;
923+
924+ /* end of directory ? */
925+ if (!root_entries[i].name)
926+ continue;
927+
928+ parent = root_entries[root_entries[i].parent_index].dentry;
929+
930+ if (root_entries[i].mode != S_IFDIR) {
931+ data = root_entries[i].data;
932+ fops = root_entries[i].fops;
933+ }
934+
935+ root_entries[i].dentry = securityfs_create_file(
936+ root_entries[i].name,
937+ root_entries[i].mode |
938+ root_entries[i].access,
939+ parent,
940+ data,
941+ fops);
942+
943+ if (IS_ERR(root_entries[i].dentry))
944+ goto cleanup_error;
945+
946+ AA_DEBUG("%s: added apparmorfs entry "
947+ "name=%s mode=%x dentry=%p [parent %p]\n",
948+ __FUNCTION__, root_entries[i].name,
949+ root_entries[i].mode|root_entries[i].access,
950+ root_entries[i].dentry, parent);
951+ }
952+
953+ return 0;
954+
955+cleanup_error:
956+ clear_apparmorfs();
957+
958+error:
959+ return -EINVAL;
960+}
961+
962+int create_apparmorfs(void)
963+{
964+ int error = 0;
965+
966+ if (AAFS_DENTRY) {
967+ error = -EEXIST;
968+ AA_ERROR("%s: AppArmor securityfs already exists\n",
969+ __FUNCTION__);
970+ } else {
971+ error = populate_apparmorfs(aafs_dentry);
972+ if (error != 0) {
973+ AA_ERROR("%s: Error populating AppArmor securityfs\n",
974+ __FUNCTION__);
975+ }
976+ }
977+
978+ return error;
979+}
980+
981+void destroy_apparmorfs(void)
982+{
983+ if (AAFS_DENTRY)
984+ clear_apparmorfs();
985+}
986Index: b/security/apparmor/capabilities.c
987===================================================================
988--- /dev/null
989+++ b/security/apparmor/capabilities.c
990@@ -0,0 +1,71 @@
991+/*
992+ * Copyright (C) 2005 Novell/SUSE
993+ *
994+ * This program is free software; you can redistribute it and/or
995+ * modify it under the terms of the GNU General Public License as
996+ * published by the Free Software Foundation, version 2 of the
997+ * License.
998+ *
999+ * AppArmor capability definitions
1000+ */
1001+
1002+#include "apparmor.h"
1003+
1004+static const char *cap_names[] = {
1005+ "chown",
1006+ "dac_override",
1007+ "dac_read_search",
1008+ "fowner",
1009+ "fsetid",
1010+ "kill",
1011+ "setgid",
1012+ "setuid",
1013+ "setpcap",
1014+ "linux_immutable",
1015+ "net_bind_service",
1016+ "net_broadcast",
1017+ "net_admin",
1018+ "net_raw",
1019+ "ipc_lock",
1020+ "ipc_owner",
1021+ "sys_module",
1022+ "sys_rawio",
1023+ "sys_chroot",
1024+ "sys_ptrace",
1025+ "sys_pacct",
1026+ "sys_admin",
1027+ "sys_boot",
1028+ "sys_nice",
1029+ "sys_resource",
1030+ "sys_time",
1031+ "sys_tty_config",
1032+ "mknod",
1033+ "lease",
1034+ "audit_write",
1035+ "audit_control"
1036+};
1037+
1038+const char *capability_to_name(unsigned int cap)
1039+{
1040+ const char *name;
1041+
1042+ name = (cap < (sizeof(cap_names) / sizeof(char *))
1043+ ? cap_names[cap] : "invalid-capability");
1044+
1045+ return name;
1046+}
1047+
1048+static const char *syscall_names[] = {
1049+ "ptrace",
1050+ "sysctl (write)",
1051+ "mount",
1052+ "umount"
1053+};
1054+
1055+const char *syscall_to_name(enum aasyscall call)
1056+{
1057+ const char *name;
1058+ name = (call < (sizeof(syscall_names) / sizeof(char *))
1059+ ? syscall_names[call] : "invalid-syscall");
1060+ return name;
1061+}
1062Index: b/security/apparmor/inline.h
1063===================================================================
1064--- /dev/null
1065+++ b/security/apparmor/inline.h
1066@@ -0,0 +1,393 @@
1067+/*
1068+ * Copyright (C) 2005 Novell/SUSE
1069+ *
1070+ * This program is free software; you can redistribute it and/or
1071+ * modify it under the terms of the GNU General Public License as
1072+ * published by the Free Software Foundation, version 2 of the
1073+ * License.
1074+ */
1075+
1076+#ifndef __INLINE_H
1077+#define __INLINE_H
1078+
1079+#include <linux/mnt_namespace.h>
1080+
1081+static inline int __aa_is_confined(struct subdomain *sd)
1082+{
1083+ return (sd && sd->active);
1084+}
1085+
1086+/**
1087+ * aa_is_confined
1088+ * Determine whether current task contains a valid profile (confined).
1089+ * Return %1 if confined, %0 otherwise.
1090+ */
1091+static inline int aa_is_confined(void)
1092+{
1093+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
1094+ return __aa_is_confined(sd);
1095+}
1096+
1097+static inline int __aa_sub_defined(struct subdomain *sd)
1098+{
1099+ return __aa_is_confined(sd) && !list_empty(&BASE_PROFILE(sd->active)->sub);
1100+}
1101+
1102+/**
1103+ * aa_sub_defined - check to see if current task has any subprofiles
1104+ * Return 1 if true, 0 otherwise
1105+ */
1106+static inline int aa_sub_defined(void)
1107+{
1108+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
1109+ return __aa_sub_defined(sd);
1110+}
1111+
1112+/**
1113+ * get_aaprofile - increment refcount on profile @p
1114+ * @p: profile
1115+ */
1116+static inline struct aaprofile *get_aaprofile(struct aaprofile *p)
1117+{
1118+ if (p)
1119+ kref_get(&(BASE_PROFILE(p)->count));
1120+
1121+ return p;
1122+}
1123+
1124+/**
1125+ * put_aaprofile - decrement refcount on profile @p
1126+ * @p: profile
1127+ */
1128+static inline void put_aaprofile(struct aaprofile *p)
1129+{
1130+ if (p)
1131+ kref_put(&BASE_PROFILE(p)->count, free_aaprofile_kref);
1132+}
1133+
1134+/**
1135+ * get_task_activeptr_rcu - get pointer to @tsk's active profile.
1136+ * @tsk: task to get active profile from
1137+ *
1138+ * Requires rcu_read_lock is held
1139+ */
1140+static inline struct aaprofile *get_task_activeptr_rcu(struct task_struct *tsk)
1141+{
1142+ struct subdomain *sd = AA_SUBDOMAIN(tsk->security);
1143+ struct aaprofile *active = NULL;
1144+
1145+ if (sd)
1146+ active = (struct aaprofile *) rcu_dereference(sd->active);
1147+
1148+ return active;
1149+}
1150+
1151+/**
1152+ * get_activeptr_rcu - get pointer to current task's active profile
1153+ * Requires rcu_read_lock is held
1154+ */
1155+static inline struct aaprofile *get_activeptr_rcu(void)
1156+{
1157+ return get_task_activeptr_rcu(current);
1158+}
1159+
1160+/**
1161+ * get_task_active_aaprofile - get a reference to tsk's active profile.
1162+ * @tsk: the task to get the active profile reference for
1163+ */
1164+static inline struct aaprofile *get_task_active_aaprofile(struct task_struct *tsk)
1165+{
1166+ struct aaprofile *active;
1167+
1168+ rcu_read_lock();
1169+ active = get_aaprofile(get_task_activeptr_rcu(tsk));
1170+ rcu_read_unlock();
1171+
1172+ return active;
1173+}
1174+
1175+/**
1176+ * get_active_aaprofile - get a reference to the current tasks active profile
1177+ */
1178+static inline struct aaprofile *get_active_aaprofile(void)
1179+{
1180+ return get_task_active_aaprofile(current);
1181+}
1182+
1183+/**
1184+ * cap_is_cached - check if @cap access has already been logged for current
1185+ * @cap: capability to test if cached
1186+ */
1187+static inline int cap_is_cached(int cap)
1188+{
1189+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
1190+ return cap_raised(sd->cached_caps, cap);
1191+}
1192+
1193+/**
1194+ * add_to_cached_caps - add a capability to the tasks logged capabilities cache
1195+ * @cap: the capability to add
1196+ */
1197+static inline void add_to_cached_caps(int cap)
1198+{
1199+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
1200+ sd->cached_caps = cap_combine(sd->cached_caps, CAP_TO_MASK(cap));
1201+}
1202+
1203+/**
1204+ * clear_cached_caps - clear the tasks logged capabilities cache
1205+ */
1206+static inline void clear_cached_caps(struct subdomain *sd)
1207+{
1208+ sd->cached_caps = CAP_EMPTY_SET;
1209+}
1210+
1211+/**
1212+ * syscall_is_cached - check if @call access has already been logged
1213+ * @call: syscall to test if cached
1214+ */
1215+static inline int syscall_is_cached(enum aasyscall call)
1216+{
1217+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
1218+ return sd->cached_syscalls & AA_SYSCALL_TO_MASK(call);
1219+}
1220+
1221+/**
1222+ * add_to_cached_syscalls - add a syscall to the tasks logged syscalls cache
1223+ * @call: the syscall to add
1224+ */
1225+static inline void add_to_cached_syscalls(enum aasyscall call)
1226+{
1227+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
1228+ sd->cached_syscalls |= AA_SYSCALL_TO_MASK(call);
1229+}
1230+
1231+/**
1232+ * clear_cached_syscalls - clear the tasks logged syscalls cache
1233+ */
1234+static inline void clear_cached_syscalls(struct subdomain *sd)
1235+{
1236+ sd->cached_syscalls = 0;
1237+}
1238+
1239+/**
1240+ * aa_switch - change subdomain to use a new profile
1241+ * @sd: subdomain to switch the active profile on
1242+ * @newactive: new active profile
1243+ *
1244+ * aa_switch handles the changing of a subdomain's active profile. The
1245+ * sd_lock must be held to ensure consistency against other writers.
1246+ * Some write paths (ex. aa_register) require sd->active not to change
1247+ * over several operations, so the calling function is responsible
1248+ * for grabing the sd_lock to meet its consistency constraints before
1249+ * calling aa_switch
1250+ */
1251+static inline void aa_switch(struct subdomain *sd, struct aaprofile *newactive)
1252+{
1253+ struct aaprofile *oldactive = sd->active;
1254+
1255+ /* noop if NULL */
1256+ rcu_assign_pointer(sd->active, get_aaprofile(newactive));
1257+ clear_cached_caps(sd);
1258+ clear_cached_syscalls(sd);
1259+ put_aaprofile(oldactive);
1260+}
1261+
1262+/**
1263+ * aa_switch_unconfined - change subdomain to be unconfined (no profile)
1264+ * @sd: subdomain to switch
1265+ *
1266+ * aa_switch_unconfined handles the removal of a subdomain's active profile.
1267+ * The sd_lock must be held to ensure consistency against other writers.
1268+ * Like aa_switch the sd_lock is used to maintain consistency.
1269+ */
1270+static inline void aa_switch_unconfined(struct subdomain *sd)
1271+{
1272+ aa_switch(sd, NULL);
1273+
1274+ /* reset magic in case we were in a subhat before */
1275+ sd->hat_magic = 0;
1276+}
1277+
1278+/**
1279+ * alloc_subdomain - allocate a new subdomain
1280+ * @tsk: task struct
1281+ *
1282+ * Allocate a new subdomain including a backpointer to it's referring task.
1283+ */
1284+static inline struct subdomain *alloc_subdomain(struct task_struct *tsk)
1285+{
1286+ struct subdomain *sd;
1287+
1288+ sd = kzalloc(sizeof(struct subdomain), GFP_KERNEL);
1289+ if (!sd)
1290+ goto out;
1291+
1292+ /* back pointer to task */
1293+ sd->task = tsk;
1294+
1295+ /* any readers of the list must make sure that they can handle
1296+ * case where sd->active is not yet set (null)
1297+ */
1298+ aa_subdomainlist_add(sd);
1299+
1300+out:
1301+ return sd;
1302+}
1303+
1304+/**
1305+ * free_subdomain - Free a subdomain previously allocated by alloc_subdomain
1306+ * @sd: subdomain
1307+ */
1308+static inline void free_subdomain(struct subdomain *sd)
1309+{
1310+ aa_subdomainlist_remove(sd);
1311+ kfree(sd);
1312+}
1313+
1314+/**
1315+ * alloc_aaprofile - Allocate, initialize and return a new zeroed profile.
1316+ * Returns NULL on failure.
1317+ */
1318+static inline struct aaprofile *alloc_aaprofile(void)
1319+{
1320+ struct aaprofile *profile;
1321+
1322+ profile = (struct aaprofile *)kzalloc(sizeof(struct aaprofile),
1323+ GFP_KERNEL);
1324+ AA_DEBUG("%s(%p)\n", __FUNCTION__, profile);
1325+ if (profile) {
1326+ int i;
1327+
1328+ INIT_LIST_HEAD(&profile->list);
1329+ INIT_LIST_HEAD(&profile->sub);
1330+ INIT_LIST_HEAD(&profile->file_entry);
1331+ for (i = 0; i <= POS_AA_FILE_MAX; i++) {
1332+ INIT_LIST_HEAD(&profile->file_entryp[i]);
1333+ }
1334+ INIT_RCU_HEAD(&profile->rcu);
1335+ kref_init(&profile->count);
1336+ }
1337+ return profile;
1338+}
1339+
1340+/**
1341+ * aa_put_name
1342+ * @name: name to release.
1343+ *
1344+ * Release space (free_page) allocated to hold pathname
1345+ * name may be NULL (checked for by free_page)
1346+ */
1347+static inline void aa_put_name(const char *name)
1348+{
1349+ free_page((unsigned long)name);
1350+}
1351+
1352+/** __aa_find_profile
1353+ * @name: name of profile to find
1354+ * @head: list to search
1355+ *
1356+ * Return reference counted copy of profile. NULL if not found
1357+ * Caller must hold any necessary locks
1358+ */
1359+static inline struct aaprofile *__aa_find_profile(const char *name,
1360+ struct list_head *head)
1361+{
1362+ struct aaprofile *p;
1363+
1364+ if (!name || !head)
1365+ return NULL;
1366+
1367+ AA_DEBUG("%s: finding profile %s\n", __FUNCTION__, name);
1368+ list_for_each_entry(p, head, list) {
1369+ if (!strcmp(p->name, name)) {
1370+ /* return refcounted object */
1371+ p = get_aaprofile(p);
1372+ return p;
1373+ } else {
1374+ AA_DEBUG("%s: skipping %s\n", __FUNCTION__, p->name);
1375+ }
1376+ }
1377+ return NULL;
1378+}
1379+
1380+/** __aa_path_begin
1381+ * @rdentry: filesystem root dentry (searching for vfsmnts matching this)
1382+ * @dentry: dentry object to obtain pathname from (relative to matched vfsmnt)
1383+ *
1384+ * Setup data for iterating over vfsmounts (in current tasks namespace).
1385+ */
1386+static inline void __aa_path_begin(struct dentry *rdentry,
1387+ struct dentry *dentry,
1388+ struct aa_path_data *data)
1389+{
1390+ data->dentry = dentry;
1391+ data->root = dget(rdentry->d_sb->s_root);
1392+ data->mnt_namespace = current->nsproxy->mnt_ns;
1393+ data->head = &data->mnt_namespace->list;
1394+ data->pos = data->head->next;
1395+ prefetch(data->pos->next);
1396+ data->errno = 0;
1397+
1398+ down_read(&namespace_sem);
1399+}
1400+
1401+/** aa_path_begin
1402+ * @dentry: filesystem root dentry and object to obtain pathname from
1403+ *
1404+ * Utility function for calling _aa_path_begin for when the dentry we are
1405+ * looking for and the root are the same (this is the usual case).
1406+ */
1407+static inline void aa_path_begin(struct dentry *dentry,
1408+ struct aa_path_data *data)
1409+{
1410+ __aa_path_begin(dentry, dentry, data);
1411+}
1412+
1413+/** aa_path_end
1414+ * @data: data object previously initialized by aa_path_begin
1415+ *
1416+ * End iterating over vfsmounts.
1417+ * If an error occured in begin or get, it is returned. Otherwise 0.
1418+ */
1419+static inline int aa_path_end(struct aa_path_data *data)
1420+{
1421+ up_read(&namespace_sem);
1422+ dput(data->root);
1423+
1424+ return data->errno;
1425+}
1426+
1427+/** aa_path_getname
1428+ * @data: data object previously initialized by aa_path_begin
1429+ *
1430+ * Return the next mountpoint which has the same root dentry as data->root.
1431+ * If no more mount points exist (or in case of error) NULL is returned
1432+ * (caller should call aa_path_end() and inspect return code to differentiate)
1433+ */
1434+static inline char *aa_path_getname(struct aa_path_data *data)
1435+{
1436+ char *name = NULL;
1437+ struct vfsmount *mnt;
1438+
1439+ while (data->pos != data->head) {
1440+ mnt = list_entry(data->pos, struct vfsmount, mnt_list);
1441+
1442+ /* advance to next -- so that it is done before we break */
1443+ data->pos = data->pos->next;
1444+ prefetch(data->pos->next);
1445+
1446+ if (mnt->mnt_root == data->root) {
1447+ name = aa_get_name(data->dentry, mnt);
1448+ if (IS_ERR(name)) {
1449+ data->errno = PTR_ERR(name);
1450+ name = NULL;
1451+ }
1452+ break;
1453+ }
1454+ }
1455+
1456+ return name;
1457+}
1458+
1459+#endif /* __INLINE_H__ */
1460Index: b/security/apparmor/list.c
1461===================================================================
1462--- /dev/null
1463+++ b/security/apparmor/list.c
1464@@ -0,0 +1,268 @@
1465+/*
1466+ * Copyright (C) 1998-2005 Novell/SUSE
1467+ *
1468+ * This program is free software; you can redistribute it and/or
1469+ * modify it under the terms of the GNU General Public License as
1470+ * published by the Free Software Foundation, version 2 of the
1471+ * License.
1472+ *
1473+ * AppArmor Profile List Management
1474+ */
1475+
1476+#include <linux/seq_file.h>
1477+#include "apparmor.h"
1478+#include "inline.h"
1479+
1480+/* list of all profiles and lock */
1481+static LIST_HEAD(profile_list);
1482+static rwlock_t profile_lock = RW_LOCK_UNLOCKED;
1483+
1484+/* list of all subdomains and lock */
1485+static LIST_HEAD(subdomain_list);
1486+static rwlock_t subdomain_lock = RW_LOCK_UNLOCKED;
1487+
1488+/**
1489+ * aa_profilelist_find
1490+ * @name: profile name (program name)
1491+ *
1492+ * Search the profile list for profile @name. Return refcounted profile on
1493+ * success, NULL on failure.
1494+ */
1495+struct aaprofile *aa_profilelist_find(const char *name)
1496+{
1497+ struct aaprofile *p = NULL;
1498+ if (name) {
1499+ read_lock(&profile_lock);
1500+ p = __aa_find_profile(name, &profile_list);
1501+ read_unlock(&profile_lock);
1502+ }
1503+ return p;
1504+}
1505+
1506+/**
1507+ * aa_profilelist_add - add new profile to list
1508+ * @profile: new profile to add to list
1509+ *
1510+ * NOTE: Caller must allocate necessary reference count that will be used
1511+ * by the profile_list. This is because profile allocation alloc_aaprofile()
1512+ * returns an unreferenced object with a initial count of %1.
1513+ *
1514+ * Return %1 on success, %0 on failure (already exists)
1515+ */
1516+int aa_profilelist_add(struct aaprofile *profile)
1517+{
1518+ struct aaprofile *old_profile;
1519+ int ret = 0;
1520+
1521+ if (!profile)
1522+ goto out;
1523+
1524+ write_lock(&profile_lock);
1525+ old_profile = __aa_find_profile(profile->name, &profile_list);
1526+ if (old_profile) {
1527+ put_aaprofile(old_profile);
1528+ goto out;
1529+ }
1530+
1531+ list_add(&profile->list, &profile_list);
1532+ ret = 1;
1533+ out:
1534+ write_unlock(&profile_lock);
1535+ return ret;
1536+}
1537+
1538+/**
1539+ * aa_profilelist_remove - remove a profile from the list by name
1540+ * @name: name of profile to be removed
1541+ *
1542+ * If the profile exists remove profile from list and return its reference.
1543+ * The reference count on profile is not decremented and should be decremented
1544+ * when the profile is no longer needed
1545+ */
1546+struct aaprofile *aa_profilelist_remove(const char *name)
1547+{
1548+ struct aaprofile *profile = NULL;
1549+ struct aaprofile *p, *tmp;
1550+
1551+ if (!name)
1552+ goto out;
1553+
1554+ write_lock(&profile_lock);
1555+ list_for_each_entry_safe(p, tmp, &profile_list, list) {
1556+ if (!strcmp(p->name, name)) {
1557+ list_del_init(&p->list);
1558+ /* mark old profile as stale */
1559+ p->isstale = 1;
1560+ profile = p;
1561+ break;
1562+ }
1563+ }
1564+ write_unlock(&profile_lock);
1565+
1566+out:
1567+ return profile;
1568+}
1569+
1570+/**
1571+ * aa_profilelist_replace - replace a profile on the list
1572+ * @profile: new profile
1573+ *
1574+ * Replace a profile on the profile list. Find the old profile by name in
1575+ * the list, and replace it with the new profile. NOTE: Caller must allocate
1576+ * necessary initial reference count for new profile as aa_profilelist_add().
1577+ *
1578+ * This is an atomic list operation. Returns the old profile (which is still
1579+ * refcounted) if there was one, or NULL.
1580+ */
1581+struct aaprofile *aa_profilelist_replace(struct aaprofile *profile)
1582+{
1583+ struct aaprofile *oldprofile;
1584+
1585+ write_lock(&profile_lock);
1586+ oldprofile = __aa_find_profile(profile->name, &profile_list);
1587+ if (oldprofile) {
1588+ list_del_init(&oldprofile->list);
1589+ /* mark old profile as stale */
1590+ oldprofile->isstale = 1;
1591+
1592+ /* __aa_find_profile incremented count, so adjust down */
1593+ put_aaprofile(oldprofile);
1594+ }
1595+
1596+ list_add(&profile->list, &profile_list);
1597+ write_unlock(&profile_lock);
1598+
1599+ return oldprofile;
1600+}
1601+
1602+/**
1603+ * aa_profilelist_release - Remove all profiles from profile_list
1604+ */
1605+void aa_profilelist_release(void)
1606+{
1607+ struct aaprofile *p, *tmp;
1608+
1609+ write_lock(&profile_lock);
1610+ list_for_each_entry_safe(p, tmp, &profile_list, list) {
1611+ list_del_init(&p->list);
1612+ put_aaprofile(p);
1613+ }
1614+ write_unlock(&profile_lock);
1615+}
1616+
1617+/**
1618+ * aa_subdomainlist_add - Add subdomain to subdomain_list
1619+ * @sd: new subdomain
1620+ */
1621+void aa_subdomainlist_add(struct subdomain *sd)
1622+{
1623+ unsigned long flags;
1624+
1625+ if (!sd) {
1626+ AA_INFO("%s: bad subdomain\n", __FUNCTION__);
1627+ return;
1628+ }
1629+
1630+ write_lock_irqsave(&subdomain_lock, flags);
1631+ /* new subdomains must be added to the end of the list due to a
1632+ * subtle interaction between fork and profile replacement.
1633+ */
1634+ list_add_tail(&sd->list, &subdomain_list);
1635+ write_unlock_irqrestore(&subdomain_lock, flags);
1636+}
1637+
1638+/**
1639+ * aa_subdomainlist_remove - Remove subdomain from subdomain_list
1640+ * @sd: subdomain to be removed
1641+ */
1642+void aa_subdomainlist_remove(struct subdomain *sd)
1643+{
1644+ unsigned long flags;
1645+
1646+ if (sd) {
1647+ write_lock_irqsave(&subdomain_lock, flags);
1648+ list_del_init(&sd->list);
1649+ write_unlock_irqrestore(&subdomain_lock, flags);
1650+ }
1651+}
1652+
1653+/**
1654+ * aa_subdomainlist_iterate - iterate over the subdomain list applying @func
1655+ * @func: method to be called for each element
1656+ * @cookie: user passed data
1657+ *
1658+ * Iterate over subdomain list applying @func, stop when @func returns
1659+ * non zero
1660+ */
1661+void aa_subdomainlist_iterate(aa_iter func, void *cookie)
1662+{
1663+ struct subdomain *node;
1664+ int ret = 0;
1665+ unsigned long flags;
1666+
1667+ read_lock_irqsave(&subdomain_lock, flags);
1668+ list_for_each_entry(node, &subdomain_list, list) {
1669+ ret = (*func) (node, cookie);
1670+ if (ret != 0)
1671+ break;
1672+ }
1673+ read_unlock_irqrestore(&subdomain_lock, flags);
1674+}
1675+
1676+/**
1677+ * aa_subdomainlist_release - Remove all subdomains from subdomain_list
1678+ */
1679+void aa_subdomainlist_release(void)
1680+{
1681+ struct subdomain *node, *tmp;
1682+ unsigned long flags;
1683+
1684+ write_lock_irqsave(&subdomain_lock, flags);
1685+ list_for_each_entry_safe(node, tmp, &subdomain_list, list) {
1686+ list_del_init(&node->list);
1687+ }
1688+ write_unlock_irqrestore(&subdomain_lock, flags);
1689+}
1690+
1691+/* seq_file helper routines
1692+ * Used by apparmorfs.c to iterate over profile_list
1693+ */
1694+static void *p_start(struct seq_file *f, loff_t *pos)
1695+{
1696+ struct aaprofile *node;
1697+ loff_t l = *pos;
1698+
1699+ read_lock(&profile_lock);
1700+ list_for_each_entry(node, &profile_list, list)
1701+ if (!l--)
1702+ return node;
1703+ return NULL;
1704+}
1705+
1706+static void *p_next(struct seq_file *f, void *p, loff_t *pos)
1707+{
1708+ struct list_head *lh = ((struct aaprofile *)p)->list.next;
1709+ (*pos)++;
1710+ return lh == &profile_list ?
1711+ NULL : list_entry(lh, struct aaprofile, list);
1712+}
1713+
1714+static void p_stop(struct seq_file *f, void *v)
1715+{
1716+ read_unlock(&profile_lock);
1717+}
1718+
1719+static int seq_show_profile(struct seq_file *f, void *v)
1720+{
1721+ struct aaprofile *profile = (struct aaprofile *)v;
1722+ seq_printf(f, "%s (%s)\n", profile->name,
1723+ PROFILE_COMPLAIN(profile) ? "complain" : "enforce");
1724+ return 0;
1725+}
1726+
1727+struct seq_operations apparmorfs_profiles_op = {
1728+ .start = p_start,
1729+ .next = p_next,
1730+ .stop = p_stop,
1731+ .show = seq_show_profile,
1732+};
1733Index: b/security/apparmor/lsm.c
1734===================================================================
1735--- /dev/null
1736+++ b/security/apparmor/lsm.c
1737@@ -0,0 +1,894 @@
1738+/*
1739+ * Copyright (C) 2002-2005 Novell/SUSE
1740+ *
1741+ * This program is free software; you can redistribute it and/or
1742+ * modify it under the terms of the GNU General Public License as
1743+ * published by the Free Software Foundation, version 2 of the
1744+ * License.
1745+ *
1746+ * http://forge.novell.com/modules/xfmod/project/?apparmor
1747+ *
1748+ * Immunix AppArmor LSM interface
1749+ */
1750+
1751+#include <linux/security.h>
1752+#include <linux/module.h>
1753+#include <linux/mm.h>
1754+#include <linux/mman.h>
1755+
1756+#include "apparmor.h"
1757+#include "inline.h"
1758+
1759+/* struct subdomain write update lock (read side is RCU). */
1760+spinlock_t sd_lock = SPIN_LOCK_UNLOCKED;
1761+
1762+/* Flag values, also controllable via apparmorfs/control.
1763+ * We explicitly do not allow these to be modifiable when exported via
1764+ * /sys/modules/parameters, as we want to do additional mediation and
1765+ * don't want to add special path code. */
1766+
1767+/* Complain mode -- in complain mode access failures result in auditing only
1768+ * and task is allowed access. audit events are processed by userspace to
1769+ * generate policy. Default is 'enforce' (0).
1770+ * Value is also togglable per profile and referenced when global value is
1771+ * enforce.
1772+ */
1773+int apparmor_complain = 0;
1774+module_param_named(complain, apparmor_complain, int, S_IRUSR);
1775+MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode");
1776+
1777+/* Debug mode */
1778+int apparmor_debug = 0;
1779+module_param_named(debug, apparmor_debug, int, S_IRUSR);
1780+MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode");
1781+
1782+/* Audit mode */
1783+int apparmor_audit = 0;
1784+module_param_named(audit, apparmor_audit, int, S_IRUSR);
1785+MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode");
1786+
1787+/* Syscall logging mode */
1788+int apparmor_logsyscall = 0;
1789+module_param_named(logsyscall, apparmor_logsyscall, int, S_IRUSR);
1790+MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode");
1791+
1792+#ifndef MODULE
1793+static int __init aa_getopt_complain(char *str)
1794+{
1795+ get_option(&str, &apparmor_complain);
1796+ return 1;
1797+}
1798+__setup("apparmor_complain=", aa_getopt_complain);
1799+
1800+static int __init aa_getopt_debug(char *str)
1801+{
1802+ get_option(&str, &apparmor_debug);
1803+ return 1;
1804+}
1805+__setup("apparmor_debug=", aa_getopt_debug);
1806+
1807+static int __init aa_getopt_audit(char *str)
1808+{
1809+ get_option(&str, &apparmor_audit);
1810+ return 1;
1811+}
1812+__setup("apparmor_audit=", aa_getopt_audit);
1813+
1814+static int __init aa_getopt_logsyscall(char *str)
1815+{
1816+ get_option(&str, &apparmor_logsyscall);
1817+ return 1;
1818+}
1819+__setup("apparmor_logsyscall=", aa_getopt_logsyscall);
1820+#endif
1821+
1822+static int apparmor_ptrace(struct task_struct *parent,
1823+ struct task_struct *child)
1824+{
1825+ int error;
1826+ struct aaprofile *active;
1827+
1828+ error = cap_ptrace(parent, child);
1829+
1830+ active = get_task_active_aaprofile(parent);
1831+
1832+ if (!error && active)
1833+ error = aa_audit_syscallreject(active, GFP_ATOMIC,
1834+ AA_SYSCALL_PTRACE);
1835+
1836+ put_aaprofile(active);
1837+
1838+ return error;
1839+}
1840+
1841+static int apparmor_capget(struct task_struct *target,
1842+ kernel_cap_t *effective,
1843+ kernel_cap_t *inheritable,
1844+ kernel_cap_t *permitted)
1845+{
1846+ return cap_capget(target, effective, inheritable, permitted);
1847+}
1848+
1849+static int apparmor_capset_check(struct task_struct *target,
1850+ kernel_cap_t *effective,
1851+ kernel_cap_t *inheritable,
1852+ kernel_cap_t *permitted)
1853+{
1854+ return cap_capset_check(target, effective, inheritable, permitted);
1855+}
1856+
1857+static void apparmor_capset_set(struct task_struct *target,
1858+ kernel_cap_t *effective,
1859+ kernel_cap_t *inheritable,
1860+ kernel_cap_t *permitted)
1861+{
1862+ cap_capset_set(target, effective, inheritable, permitted);
1863+ return;
1864+}
1865+
1866+static int apparmor_capable(struct task_struct *tsk, int cap)
1867+{
1868+ int error;
1869+
1870+ /* cap_capable returns 0 on success, else -EPERM */
1871+ error = cap_capable(tsk, cap);
1872+
1873+ if (error == 0) {
1874+ struct aaprofile *active;
1875+
1876+ active = get_task_active_aaprofile(tsk);
1877+
1878+ if (active)
1879+ error = aa_capability(active, cap);
1880+
1881+ put_aaprofile(active);
1882+ }
1883+
1884+ return error;
1885+}
1886+
1887+static int apparmor_sysctl(struct ctl_table *table, int op)
1888+{
1889+ int error = 0;
1890+ struct aaprofile *active;
1891+
1892+ active = get_active_aaprofile();
1893+
1894+ if ((op & 002) && active && !capable(CAP_SYS_ADMIN))
1895+ error = aa_audit_syscallreject(active, GFP_ATOMIC,
1896+ AA_SYSCALL_SYSCTL_WRITE);
1897+
1898+ put_aaprofile(active);
1899+
1900+ return error;
1901+}
1902+
1903+static int apparmor_syslog(int type)
1904+{
1905+ return cap_syslog(type);
1906+}
1907+
1908+static int apparmor_netlink_send(struct sock *sk, struct sk_buff *skb)
1909+{
1910+ return cap_netlink_send(sk, skb);
1911+}
1912+
1913+static int apparmor_netlink_recv(struct sk_buff *skb, int cap)
1914+{
1915+ return cap_netlink_recv(skb, cap);
1916+}
1917+
1918+static void apparmor_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
1919+{
1920+ cap_bprm_apply_creds(bprm, unsafe);
1921+ return;
1922+}
1923+
1924+static int apparmor_bprm_set_security(struct linux_binprm *bprm)
1925+{
1926+ /* handle capability bits with setuid, etc */
1927+ cap_bprm_set_security(bprm);
1928+ /* already set based on script name */
1929+ if (bprm->sh_bang)
1930+ return 0;
1931+ return aa_register(bprm);
1932+}
1933+
1934+static int apparmor_bprm_secureexec(struct linux_binprm *bprm)
1935+{
1936+ int ret = cap_bprm_secureexec(bprm);
1937+
1938+ if (ret == 0 &&
1939+ (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) {
1940+ AA_DEBUG("%s: secureexec required for %s\n",
1941+ __FUNCTION__, bprm->filename);
1942+ ret = 1;
1943+ }
1944+
1945+ return ret;
1946+}
1947+
1948+static int apparmor_sb_mount(char *dev_name, struct nameidata *nd, char *type,
1949+ unsigned long flags, void *data)
1950+{
1951+ int error = 0;
1952+ struct aaprofile *active;
1953+
1954+ active = get_active_aaprofile();
1955+
1956+ if (active)
1957+ error = aa_audit_syscallreject(active, GFP_ATOMIC,
1958+ AA_SYSCALL_MOUNT);
1959+
1960+ put_aaprofile(active);
1961+
1962+ return error;
1963+}
1964+
1965+static int apparmor_umount(struct vfsmount *mnt, int flags)
1966+{
1967+ int error = 0;
1968+ struct aaprofile *active;
1969+
1970+ active = get_active_aaprofile();
1971+
1972+ if (active)
1973+ error = aa_audit_syscallreject(active, GFP_ATOMIC,
1974+ AA_SYSCALL_UMOUNT);
1975+
1976+ put_aaprofile(active);
1977+
1978+ return error;
1979+}
1980+
1981+static int apparmor_inode_mkdir(struct inode *inode, struct dentry *dentry,
1982+ int mask)
1983+{
1984+ struct aaprofile *active;
1985+ int error = 0;
1986+
1987+ active = get_active_aaprofile();
1988+
1989+ if (active)
1990+ error = aa_perm_dir(active, dentry, aa_dir_mkdir);
1991+
1992+ put_aaprofile(active);
1993+
1994+ return error;
1995+}
1996+
1997+static int apparmor_inode_rmdir(struct inode *inode, struct dentry *dentry)
1998+{
1999+ struct aaprofile *active;
2000+ int error = 0;
2001+
2002+ active = get_active_aaprofile();
2003+
2004+ if (active)
2005+ error = aa_perm_dir(active, dentry, aa_dir_rmdir);
2006+
2007+ put_aaprofile(active);
2008+
2009+ return error;
2010+}
2011+
2012+static int apparmor_inode_create(struct inode *inode, struct dentry *dentry,
2013+ int mask)
2014+{
2015+ struct aaprofile *active;
2016+ int error = 0;
2017+
2018+ active = get_active_aaprofile();
2019+
2020+ /* At a minimum, need write perm to create */
2021+ if (active)
2022+ error = aa_perm_dentry(active, dentry, MAY_WRITE);
2023+
2024+ put_aaprofile(active);
2025+
2026+ return error;
2027+}
2028+
2029+static int apparmor_inode_link(struct dentry *old_dentry, struct inode *inode,
2030+ struct dentry *new_dentry)
2031+{
2032+ int error = 0;
2033+ struct aaprofile *active;
2034+
2035+ active = get_active_aaprofile();
2036+
2037+ if (active)
2038+ error = aa_link(active, new_dentry, old_dentry);
2039+
2040+ put_aaprofile(active);
2041+
2042+ return error;
2043+}
2044+
2045+static int apparmor_inode_unlink(struct inode *inode, struct dentry *dentry)
2046+{
2047+ struct aaprofile *active;
2048+ int error = 0;
2049+
2050+ active = get_active_aaprofile();
2051+
2052+ if (active)
2053+ error = aa_perm_dentry(active, dentry, MAY_WRITE);
2054+
2055+ put_aaprofile(active);
2056+
2057+ return error;
2058+}
2059+
2060+static int apparmor_inode_mknod(struct inode *inode, struct dentry *dentry,
2061+ int mode, dev_t dev)
2062+{
2063+ struct aaprofile *active;
2064+ int error = 0;
2065+
2066+ active = get_active_aaprofile();
2067+
2068+ if (active)
2069+ error = aa_perm_dentry(active, dentry, MAY_WRITE);
2070+
2071+ put_aaprofile(active);
2072+
2073+ return error;
2074+}
2075+
2076+static int apparmor_inode_rename(struct inode *old_inode,
2077+ struct dentry *old_dentry,
2078+ struct inode *new_inode,
2079+ struct dentry *new_dentry)
2080+{
2081+ struct aaprofile *active;
2082+ int error = 0;
2083+
2084+ active = get_active_aaprofile();
2085+
2086+ if (active) {
2087+ error = aa_perm_dentry(active, old_dentry, MAY_READ |
2088+ MAY_WRITE);
2089+
2090+ if (!error)
2091+ error = aa_perm_dentry(active, new_dentry,
2092+ MAY_WRITE);
2093+ }
2094+
2095+ put_aaprofile(active);
2096+
2097+ return error;
2098+}
2099+
2100+static int apparmor_inode_permission(struct inode *inode, int mask,
2101+ struct nameidata *nd)
2102+{
2103+ int error = 0;
2104+
2105+ /* Do not perform check on pipes or sockets
2106+ * Same as apparmor_file_permission
2107+ */
2108+ if (VALID_FSTYPE(inode)) {
2109+ struct aaprofile *active;
2110+
2111+ active = get_active_aaprofile();
2112+ if (active)
2113+ error = aa_perm_nameidata(active, nd, mask);
2114+ put_aaprofile(active);
2115+ }
2116+
2117+ return error;
2118+}
2119+
2120+static int apparmor_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2121+{
2122+ int error = 0;
2123+
2124+ if (VALID_FSTYPE(dentry->d_inode)) {
2125+ struct aaprofile *active;
2126+
2127+ active = get_active_aaprofile();
2128+ /*
2129+ * Mediate any attempt to change attributes of a file
2130+ * (chmod, chown, chgrp, etc)
2131+ */
2132+ if (active)
2133+ error = aa_attr(active, dentry, iattr);
2134+
2135+ put_aaprofile(active);
2136+ }
2137+
2138+ return error;
2139+}
2140+
2141+static int apparmor_inode_setxattr(struct dentry *dentry, char *name,
2142+ void *value, size_t size, int flags)
2143+{
2144+ int error = 0;
2145+
2146+ if (VALID_FSTYPE(dentry->d_inode)) {
2147+ struct aaprofile *active;
2148+
2149+ active = get_active_aaprofile();
2150+ if (active)
2151+ error = aa_xattr(active, dentry, name, aa_xattr_set);
2152+ put_aaprofile(active);
2153+ }
2154+
2155+ return error;
2156+}
2157+
2158+static int apparmor_inode_getxattr(struct dentry *dentry, char *name)
2159+{
2160+ int error = 0;
2161+
2162+ if (VALID_FSTYPE(dentry->d_inode)) {
2163+ struct aaprofile *active;
2164+
2165+ active = get_active_aaprofile();
2166+ if (active)
2167+ error = aa_xattr(active, dentry, name, aa_xattr_get);
2168+ put_aaprofile(active);
2169+ }
2170+
2171+ return error;
2172+}
2173+static int apparmor_inode_listxattr(struct dentry *dentry)
2174+{
2175+ int error = 0;
2176+
2177+ if (VALID_FSTYPE(dentry->d_inode)) {
2178+ struct aaprofile *active;
2179+
2180+ active = get_active_aaprofile();
2181+ if (active)
2182+ error = aa_xattr(active, dentry, NULL, aa_xattr_list);
2183+ put_aaprofile(active);
2184+ }
2185+
2186+ return error;
2187+}
2188+
2189+static int apparmor_inode_removexattr(struct dentry *dentry, char *name)
2190+{
2191+ int error = 0;
2192+
2193+ if (VALID_FSTYPE(dentry->d_inode)) {
2194+ struct aaprofile *active;
2195+
2196+ active = get_active_aaprofile();
2197+ if (active)
2198+ error = aa_xattr(active, dentry, name,
2199+ aa_xattr_remove);
2200+ put_aaprofile(active);
2201+ }
2202+
2203+ return error;
2204+}
2205+
2206+static int apparmor_file_permission(struct file *file, int mask)
2207+{
2208+ struct aaprofile *active;
2209+ struct aafile *aaf;
2210+ int error = 0;
2211+
2212+ aaf = (struct aafile *)file->f_security;
2213+ /* bail out early if this isn't a mediated file */
2214+ if (!aaf || !VALID_FSTYPE(file->f_dentry->d_inode))
2215+ goto out;
2216+
2217+ active = get_active_aaprofile();
2218+ if (active && aaf->profile != active)
2219+ error = aa_perm(active, file->f_dentry, file->f_vfsmnt,
2220+ mask & (MAY_EXEC | MAY_WRITE | MAY_READ));
2221+ put_aaprofile(active);
2222+
2223+out:
2224+ return error;
2225+}
2226+
2227+static int apparmor_file_alloc_security(struct file *file)
2228+{
2229+ struct aaprofile *active;
2230+ int error = 0;
2231+
2232+ active = get_active_aaprofile();
2233+ if (active) {
2234+ struct aafile *aaf;
2235+ aaf = kmalloc(sizeof(struct aafile), GFP_KERNEL);
2236+
2237+ if (aaf) {
2238+ aaf->type = aa_file_default;
2239+ aaf->profile = get_aaprofile(active);
2240+ } else {
2241+ error = -ENOMEM;
2242+ }
2243+ file->f_security = aaf;
2244+ }
2245+ put_aaprofile(active);
2246+
2247+ return error;
2248+}
2249+
2250+static void apparmor_file_free_security(struct file *file)
2251+{
2252+ struct aafile *aaf = (struct aafile *)file->f_security;
2253+
2254+ if (aaf) {
2255+ put_aaprofile(aaf->profile);
2256+ kfree(aaf);
2257+ }
2258+}
2259+
2260+static inline int aa_mmap(struct file *file, unsigned long prot,
2261+ unsigned long flags)
2262+{
2263+ int error = 0, mask = 0;
2264+ struct aaprofile *active;
2265+ struct aafile *aaf;
2266+
2267+ active = get_active_aaprofile();
2268+ if (!active || !file ||
2269+ !(aaf = (struct aafile *)file->f_security) ||
2270+ aaf->type == aa_file_shmem)
2271+ goto out;
2272+
2273+ if (prot & PROT_READ)
2274+ mask |= MAY_READ;
2275+
2276+ /* Private mappings don't require write perms since they don't
2277+ * write back to the files */
2278+ if (prot & PROT_WRITE && !(flags & MAP_PRIVATE))
2279+ mask |= MAY_WRITE;
2280+ if (prot & PROT_EXEC)
2281+ mask |= AA_EXEC_MMAP;
2282+
2283+ AA_DEBUG("%s: 0x%x\n", __FUNCTION__, mask);
2284+
2285+ if (mask)
2286+ error = aa_perm(active, file->f_dentry, file->f_vfsmnt, mask);
2287+
2288+ put_aaprofile(active);
2289+
2290+out:
2291+ return error;
2292+}
2293+
2294+static int apparmor_file_mmap(struct file *file, unsigned long reqprot,
2295+ unsigned long prot, unsigned long flags)
2296+{
2297+ return aa_mmap(file, prot, flags);
2298+}
2299+
2300+static int apparmor_file_mprotect(struct vm_area_struct *vma,
2301+ unsigned long reqprot, unsigned long prot)
2302+{
2303+ return aa_mmap(vma->vm_file, prot,
2304+ !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0);
2305+}
2306+
2307+static int apparmor_task_alloc_security(struct task_struct *p)
2308+{
2309+ return aa_fork(p);
2310+}
2311+
2312+static void apparmor_task_free_security(struct task_struct *p)
2313+{
2314+ aa_release(p);
2315+}
2316+
2317+static int apparmor_task_post_setuid(uid_t id0, uid_t id1, uid_t id2,
2318+ int flags)
2319+{
2320+ return cap_task_post_setuid(id0, id1, id2, flags);
2321+}
2322+
2323+static void apparmor_task_reparent_to_init(struct task_struct *p)
2324+{
2325+ cap_task_reparent_to_init(p);
2326+ return;
2327+}
2328+
2329+static int apparmor_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr,
2330+ int shmflg)
2331+{
2332+ struct aafile *aaf = (struct aafile *)shp->shm_file->f_security;
2333+
2334+ if (aaf)
2335+ aaf->type = aa_file_shmem;
2336+
2337+ return 0;
2338+}
2339+
2340+static int apparmor_getprocattr(struct task_struct *p, char *name, void *value,
2341+ size_t size)
2342+{
2343+ int error;
2344+ struct aaprofile *active;
2345+ char *str = value;
2346+
2347+ /* AppArmor only supports the "current" process attribute */
2348+ if (strcmp(name, "current") != 0) {
2349+ error = -EINVAL;
2350+ goto out;
2351+ }
2352+
2353+ /* must be task querying itself or admin */
2354+ if (current != p && !capable(CAP_SYS_ADMIN)) {
2355+ error = -EPERM;
2356+ goto out;
2357+ }
2358+
2359+ active = get_task_active_aaprofile(p);
2360+ error = aa_getprocattr(active, str, size);
2361+ put_aaprofile(active);
2362+
2363+out:
2364+ return error;
2365+}
2366+
2367+static int apparmor_setprocattr(struct task_struct *p, char *name, void *value,
2368+ size_t size)
2369+{
2370+ const char *cmd_changehat = "changehat ",
2371+ *cmd_setprofile = "setprofile ";
2372+
2373+ int error = -EACCES; /* default to a perm denied */
2374+ char *cmd = (char *)value;
2375+
2376+ /* only support messages to current */
2377+ if (strcmp(name, "current") != 0) {
2378+ error = -EINVAL;
2379+ goto out;
2380+ }
2381+
2382+ if (!size) {
2383+ error = -ERANGE;
2384+ goto out;
2385+ }
2386+
2387+ /* CHANGE HAT -- switch task into a subhat (subprofile) if defined */
2388+ if (size > strlen(cmd_changehat) &&
2389+ strncmp(cmd, cmd_changehat, strlen(cmd_changehat)) == 0) {
2390+ char *hatinfo = cmd + strlen(cmd_changehat);
2391+ size_t infosize = size - strlen(cmd_changehat);
2392+
2393+ /* Only the current process may change it's hat */
2394+ if (current != p) {
2395+ AA_WARN("%s: Attempt by foreign task %s(%d) "
2396+ "[user %d] to changehat of task %s(%d)\n",
2397+ __FUNCTION__,
2398+ current->comm,
2399+ current->pid,
2400+ current->uid,
2401+ p->comm,
2402+ p->pid);
2403+
2404+ error = -EACCES;
2405+ goto out;
2406+ }
2407+
2408+ error = aa_setprocattr_changehat(hatinfo, infosize);
2409+ if (error == 0)
2410+ /* success, set return to #bytes in orig request */
2411+ error = size;
2412+
2413+ /* SET NEW PROFILE */
2414+ } else if (size > strlen(cmd_setprofile) &&
2415+ strncmp(cmd, cmd_setprofile, strlen(cmd_setprofile)) == 0) {
2416+ struct aaprofile *active;
2417+
2418+ /* only an unconfined process with admin capabilities
2419+ * may change the profile of another task
2420+ */
2421+
2422+ if (!capable(CAP_SYS_ADMIN)) {
2423+ AA_WARN("%s: Unprivileged attempt by task %s(%d) "
2424+ "[user %d] to assign profile to task %s(%d)\n",
2425+ __FUNCTION__,
2426+ current->comm,
2427+ current->pid,
2428+ current->uid,
2429+ p->comm,
2430+ p->pid);
2431+ error = -EACCES;
2432+ goto out;
2433+ }
2434+
2435+ active = get_active_aaprofile();
2436+ if (!active) {
2437+ char *profile = cmd + strlen(cmd_setprofile);
2438+ size_t profilesize = size - strlen(cmd_setprofile);
2439+
2440+ error = aa_setprocattr_setprofile(p, profile, profilesize);
2441+ if (error == 0)
2442+ /* success,
2443+ * set return to #bytes in orig request
2444+ */
2445+ error = size;
2446+ } else {
2447+ AA_WARN("%s: Attempt by confined task %s(%d) "
2448+ "[user %d] to assign profile to task %s(%d)\n",
2449+ __FUNCTION__,
2450+ current->comm,
2451+ current->pid,
2452+ current->uid,
2453+ p->comm,
2454+ p->pid);
2455+
2456+ error = -EACCES;
2457+ }
2458+ put_aaprofile(active);
2459+ } else {
2460+ /* unknown operation */
2461+ AA_WARN("%s: Unknown setprocattr command '%.*s' by task %s(%d) "
2462+ "[user %d] for task %s(%d)\n",
2463+ __FUNCTION__,
2464+ size < 16 ? (int)size : 16,
2465+ cmd,
2466+ current->comm,
2467+ current->pid,
2468+ current->uid,
2469+ p->comm,
2470+ p->pid);
2471+
2472+ error = -EINVAL;
2473+ }
2474+
2475+out:
2476+ return error;
2477+}
2478+
2479+struct security_operations apparmor_ops = {
2480+ .ptrace = apparmor_ptrace,
2481+ .capget = apparmor_capget,
2482+ .capset_check = apparmor_capset_check,
2483+ .capset_set = apparmor_capset_set,
2484+ .sysctl = apparmor_sysctl,
2485+ .capable = apparmor_capable,
2486+ .syslog = apparmor_syslog,
2487+
2488+ .netlink_send = apparmor_netlink_send,
2489+ .netlink_recv = apparmor_netlink_recv,
2490+
2491+ .bprm_apply_creds = apparmor_bprm_apply_creds,
2492+ .bprm_set_security = apparmor_bprm_set_security,
2493+ .bprm_secureexec = apparmor_bprm_secureexec,
2494+
2495+ .sb_mount = apparmor_sb_mount,
2496+ .sb_umount = apparmor_umount,
2497+
2498+ .inode_mkdir = apparmor_inode_mkdir,
2499+ .inode_rmdir = apparmor_inode_rmdir,
2500+ .inode_create = apparmor_inode_create,
2501+ .inode_link = apparmor_inode_link,
2502+ .inode_unlink = apparmor_inode_unlink,
2503+ .inode_mknod = apparmor_inode_mknod,
2504+ .inode_rename = apparmor_inode_rename,
2505+ .inode_permission = apparmor_inode_permission,
2506+ .inode_setattr = apparmor_inode_setattr,
2507+ .inode_setxattr = apparmor_inode_setxattr,
2508+ .inode_getxattr = apparmor_inode_getxattr,
2509+ .inode_listxattr = apparmor_inode_listxattr,
2510+ .inode_removexattr = apparmor_inode_removexattr,
2511+ .file_permission = apparmor_file_permission,
2512+ .file_alloc_security = apparmor_file_alloc_security,
2513+ .file_free_security = apparmor_file_free_security,
2514+ .file_mmap = apparmor_file_mmap,
2515+ .file_mprotect = apparmor_file_mprotect,
2516+
2517+ .task_alloc_security = apparmor_task_alloc_security,
2518+ .task_free_security = apparmor_task_free_security,
2519+ .task_post_setuid = apparmor_task_post_setuid,
2520+ .task_reparent_to_init = apparmor_task_reparent_to_init,
2521+
2522+ .shm_shmat = apparmor_shm_shmat,
2523+
2524+ .getprocattr = apparmor_getprocattr,
2525+ .setprocattr = apparmor_setprocattr,
2526+};
2527+
2528+static int __init apparmor_init(void)
2529+{
2530+ int error;
2531+ const char *complainmsg = ": complainmode enabled";
2532+
2533+ if ((error = create_apparmorfs())) {
2534+ AA_ERROR("Unable to activate AppArmor filesystem\n");
2535+ goto createfs_out;
2536+ }
2537+
2538+ if ((error = alloc_null_complain_profile())){
2539+ AA_ERROR("Unable to allocate null complain profile\n");
2540+ goto alloc_out;
2541+ }
2542+
2543+ if ((error = register_security(&apparmor_ops))) {
2544+ AA_ERROR("Unable to load AppArmor\n");
2545+ goto register_security_out;
2546+ }
2547+
2548+ AA_INFO("AppArmor initialized%s\n",
2549+ apparmor_complain ? complainmsg : "");
2550+ aa_audit_message(NULL, GFP_KERNEL, 0,
2551+ "AppArmor initialized%s\n",
2552+ apparmor_complain ? complainmsg : "");
2553+
2554+ return error;
2555+
2556+register_security_out:
2557+ free_null_complain_profile();
2558+
2559+alloc_out:
2560+ (void)destroy_apparmorfs();
2561+
2562+createfs_out:
2563+ return error;
2564+
2565+}
2566+
2567+static int apparmor_exit_removeall_iter(struct subdomain *sd, void *cookie)
2568+{
2569+ /* spin_lock(&sd_lock) held here */
2570+
2571+ if (__aa_is_confined(sd)) {
2572+ AA_DEBUG("%s: Dropping profiles %s(%d) "
2573+ "profile %s(%p) active %s(%p)\n",
2574+ __FUNCTION__,
2575+ sd->task->comm, sd->task->pid,
2576+ BASE_PROFILE(sd->active)->name,
2577+ BASE_PROFILE(sd->active),
2578+ sd->active->name, sd->active);
2579+ aa_switch_unconfined(sd);
2580+ }
2581+
2582+ return 0;
2583+}
2584+
2585+static void __exit apparmor_exit(void)
2586+{
2587+ unsigned long flags;
2588+
2589+ /* Remove profiles from the global profile list.
2590+ * This is just for tidyness as there is no way to reference this
2591+ * list once the AppArmor lsm hooks are detached (below)
2592+ */
2593+ aa_profilelist_release();
2594+
2595+ /* Remove profiles from active tasks
2596+ * If this is not done, if module is reloaded after being removed,
2597+ * old profiles (still refcounted in memory) will become 'magically'
2598+ * reattached
2599+ */
2600+
2601+ spin_lock_irqsave(&sd_lock, flags);
2602+ aa_subdomainlist_iterate(apparmor_exit_removeall_iter, NULL);
2603+ spin_unlock_irqrestore(&sd_lock, flags);
2604+
2605+ /* Free up list of active subdomain */
2606+ aa_subdomainlist_release();
2607+
2608+ free_null_complain_profile();
2609+
2610+ destroy_apparmorfs();
2611+
2612+ if (unregister_security(&apparmor_ops))
2613+ AA_WARN("Unable to properly unregister AppArmor\n");
2614+
2615+ /* delay for an rcu cycle to make ensure that profiles pending
2616+ * destruction in the rcu callback are freed.
2617+ */
2618+ synchronize_rcu();
2619+
2620+ AA_INFO("AppArmor protection removed\n");
2621+ aa_audit_message(NULL, GFP_KERNEL, 0,
2622+ "AppArmor protection removed\n");
2623+}
2624+
2625+module_init(apparmor_init);
2626+module_exit(apparmor_exit);
2627+
2628+MODULE_VERSION(APPARMOR_VERSION);
2629+MODULE_DESCRIPTION("AppArmor process confinement");
2630+MODULE_AUTHOR("Tony Jones <tonyj@suse.de>");
2631+MODULE_LICENSE("GPL");
2632Index: b/security/apparmor/main.c
2633===================================================================
2634--- /dev/null
2635+++ b/security/apparmor/main.c
2636@@ -0,0 +1,1702 @@
2637+/*
2638+ * Copyright (C) 2002-2005 Novell/SUSE
2639+ *
2640+ * This program is free software; you can redistribute it and/or
2641+ * modify it under the terms of the GNU General Public License as
2642+ * published by the Free Software Foundation, version 2 of the
2643+ * License.
2644+ *
2645+ * AppArmor Core
2646+ */
2647+
2648+#include <linux/security.h>
2649+#include <linux/namei.h>
2650+#include <linux/audit.h>
2651+
2652+#include "apparmor.h"
2653+#include "match/match.h"
2654+
2655+#include "inline.h"
2656+
2657+/* NULL complain profile
2658+ *
2659+ * Used when in complain mode, to emit Permitting messages for non-existant
2660+ * profiles and hats. This is necessary because of selective mode, in which
2661+ * case we need a complain null_profile and enforce null_profile
2662+ *
2663+ * The null_complain_profile cannot be statically allocated, because it
2664+ * can be associated to files which keep their reference even if apparmor is
2665+ * unloaded
2666+ */
2667+struct aaprofile *null_complain_profile;
2668+
2669+/***************************
2670+ * Private utility functions
2671+ **************************/
2672+
2673+/**
2674+ * dentry_xlate_error
2675+ * @dentry: pointer to dentry
2676+ * @error: error number
2677+ * @dtype: type of dentry
2678+ *
2679+ * Display error message when a dentry translation error occured
2680+ */
2681+static void dentry_xlate_error(struct dentry *dentry, int error, char *dtype)
2682+{
2683+ const unsigned int len = 16;
2684+ char buf[len];
2685+
2686+ if (dentry->d_inode) {
2687+ snprintf(buf, len, "%lu", dentry->d_inode->i_ino);
2688+ } else {
2689+ strncpy(buf, "<negative>", len);
2690+ buf[len-1]=0;
2691+ }
2692+
2693+ AA_ERROR("An error occured while translating %s %p "
2694+ "inode# %s to a pathname. Error %d\n",
2695+ dtype,
2696+ dentry,
2697+ buf,
2698+ error);
2699+}
2700+
2701+/**
2702+ * aa_taskattr_access
2703+ * @procrelname: name of file to check permission
2704+ *
2705+ * Determine if request is for write access to /proc/self/attr/current
2706+ * This file is the usermode iterface for changing it's hat.
2707+ */
2708+static inline int aa_taskattr_access(const char *procrelname)
2709+{
2710+ char buf[sizeof("/attr/current") + 10];
2711+ const int maxbuflen = sizeof(buf);
2712+ /* assumption, 32bit pid (10 decimal digits incl \0) */
2713+
2714+ snprintf(buf, maxbuflen, "%d/attr/current", current->pid);
2715+ buf[maxbuflen - 1] = 0;
2716+
2717+ return strcmp(buf, procrelname) == 0;
2718+}
2719+
2720+/**
2721+ * aa_file_mode - get full mode for file entry from profile
2722+ * @profile: profile
2723+ * @name: filename
2724+ */
2725+static inline int aa_file_mode(struct aaprofile *profile, const char *name)
2726+{
2727+ struct aa_entry *entry;
2728+ int mode = 0;
2729+
2730+ AA_DEBUG("%s: %s\n", __FUNCTION__, name);
2731+ if (!name) {
2732+ AA_DEBUG("%s: no name\n", __FUNCTION__);
2733+ goto out;
2734+ }
2735+
2736+ if (!profile) {
2737+ AA_DEBUG("%s: no profile\n", __FUNCTION__);
2738+ goto out;
2739+ }
2740+ list_for_each_entry(entry, &profile->file_entry, list) {
2741+ if (aamatch_match(name, entry->filename,
2742+ entry->type, entry->extradata))
2743+ mode |= entry->mode;
2744+ }
2745+out:
2746+ return mode;
2747+}
2748+
2749+/**
2750+ * aa_get_execmode - calculate what qualifier to apply to an exec
2751+ * @active: profile to search
2752+ * @name: name of file to exec
2753+ * @xmod: pointer to a execution mode bit for the rule that was matched
2754+ * if the rule has no execuition qualifier {pui} then
2755+ * %AA_MAY_EXEC is returned indicating a naked x
2756+ * if the has an exec qualifier then only the qualifier bit {pui}
2757+ * is returned (%AA_MAY_EXEC) is not set.
2758+ * @unsafe: true if secure_exec should be overriden
2759+ * Returns %0 (false):
2760+ * if unable to find profile or there are conflicting pattern matches.
2761+ * *xmod - is not modified
2762+ * *unsafe - is not modified
2763+ *
2764+ * Returns %1 (true):
2765+ * if exec rule matched
2766+ * if the rule has an execution mode qualifier {pui} then
2767+ * *xmod = the execution qualifier of the rule {pui}
2768+ * else
2769+ * *xmod = %AA_MAY_EXEC
2770+ * unsafe = presence of unsage flag
2771+ */
2772+static inline int aa_get_execmode(struct aaprofile *active, const char *name,
2773+ int *xmod, int *unsafe)
2774+{
2775+ struct aa_entry *entry;
2776+ struct aa_entry *match = NULL;
2777+
2778+ int pattern_match_invalid = 0, rc = 0;
2779+
2780+ /* search list of profiles with 'x' permission
2781+ * this will also include entries with 'p', 'u' and 'i'
2782+ * qualifiers.
2783+ *
2784+ * If we find a pattern match we will keep looking for an exact match
2785+ * If we find conflicting pattern matches we will flag (while still
2786+ * looking for an exact match). If all we have is a conflict, FALSE
2787+ * is returned.
2788+ */
2789+
2790+ list_for_each_entry(entry, &active->file_entryp[POS_AA_MAY_EXEC],
2791+ listp[POS_AA_MAY_EXEC]) {
2792+ if (!pattern_match_invalid &&
2793+ entry->type == aa_entry_pattern &&
2794+ aamatch_match(name, entry->filename,
2795+ entry->type, entry->extradata)) {
2796+ if (match &&
2797+ AA_EXEC_UNSAFE_MASK(entry->mode) !=
2798+ AA_EXEC_UNSAFE_MASK(match->mode))
2799+ pattern_match_invalid = 1;
2800+ else
2801+ /* keep searching for an exact match */
2802+ match = entry;
2803+ } else if ((entry->type == aa_entry_literal ||
2804+ (!pattern_match_invalid &&
2805+ entry->type == aa_entry_tailglob)) &&
2806+ aamatch_match(name, entry->filename,
2807+ entry->type,
2808+ entry->extradata)) {
2809+ if (entry->type == aa_entry_literal) {
2810+ /* got an exact match -- there can be only
2811+ * one, asserted at profile load time
2812+ */
2813+ match = entry;
2814+ pattern_match_invalid = 0;
2815+ break;
2816+ } else {
2817+ if (match &&
2818+ AA_EXEC_UNSAFE_MASK(entry->mode) !=
2819+ AA_EXEC_UNSAFE_MASK(match->mode))
2820+ pattern_match_invalid = 1;
2821+ else
2822+ /* got a tailglob match, keep searching
2823+ * for an exact match
2824+ */
2825+ match = entry;
2826+ }
2827+ }
2828+
2829+ }
2830+
2831+ rc = match && !pattern_match_invalid;
2832+
2833+ if (rc) {
2834+ int mode = AA_EXEC_MASK(match->mode);
2835+
2836+ /* check for qualifiers, if present
2837+ * we just return the qualifier
2838+ */
2839+ if (mode & ~AA_MAY_EXEC)
2840+ mode = mode & ~AA_MAY_EXEC;
2841+
2842+ *xmod = mode;
2843+ *unsafe = (match->mode & AA_EXEC_UNSAFE);
2844+ } else if (!match) {
2845+ AA_DEBUG("%s: Unable to find execute entry in profile "
2846+ "for image '%s'\n",
2847+ __FUNCTION__,
2848+ name);
2849+ } else if (pattern_match_invalid) {
2850+ AA_WARN("%s: Inconsistency in profile %s. "
2851+ "Two (or more) patterns specify conflicting exec "
2852+ "qualifiers ('u', 'i' or 'p') for image %s\n",
2853+ __FUNCTION__,
2854+ active->name,
2855+ name);
2856+ }
2857+
2858+ return rc;
2859+}
2860+
2861+/**
2862+ * aa_filter_mask
2863+ * @mask: requested mask
2864+ * @inode: potential directory inode
2865+ *
2866+ * This fn performs pre-verification of the requested mask
2867+ * We ignore append. Previously we required 'w' on a dir to add a file.
2868+ * No longer. Now we require 'w' on just the file itself. Traversal 'x' is
2869+ * also ignored for directories.
2870+ *
2871+ * Returned value of %0 indicates no need to perform a perm check.
2872+ */
2873+static inline int aa_filter_mask(int mask, struct inode *inode)
2874+{
2875+ if (mask) {
2876+ int elim = MAY_APPEND;
2877+
2878+ if (inode && S_ISDIR(inode->i_mode))
2879+ elim |= (MAY_EXEC | MAY_WRITE);
2880+
2881+ mask &= ~elim;
2882+ }
2883+
2884+ return mask;
2885+}
2886+
2887+static inline void aa_permerror2result(int perm_result, struct aa_audit *sa)
2888+{
2889+ if (perm_result == 0) { /* success */
2890+ sa->result = 1;
2891+ sa->error_code = 0;
2892+ } else { /* -ve internal error code or +ve mask of denied perms */
2893+ sa->result = 0;
2894+ sa->error_code = perm_result;
2895+ }
2896+}
2897+
2898+/*************************
2899+ * Main internal functions
2900+ ************************/
2901+
2902+/**
2903+ * aa_file_perm - calculate access mode for file
2904+ * @active: profile to check against
2905+ * @name: name of file to calculate mode for
2906+ * @mask: permission mask requested for file
2907+ *
2908+ * Search the aa_entry list in @active.
2909+ * Search looking to verify all permissions passed in mask.
2910+ * Perform the search by looking at the partitioned list of entries, one
2911+ * partition per permission bit.
2912+ *
2913+ * Return %0 on success, else mask of non-allowed permissions
2914+ */
2915+static unsigned int aa_file_perm(struct aaprofile *active, const char *name,
2916+ int mask)
2917+{
2918+ int i, error = 0, mode;
2919+
2920+#define PROCPFX "/proc/"
2921+#define PROCLEN sizeof(PROCPFX) - 1
2922+
2923+ AA_DEBUG("%s: %s 0x%x\n", __FUNCTION__, name, mask);
2924+
2925+ /* should not enter with other than R/W/M/X/L */
2926+ WARN_ON(mask &
2927+ ~(AA_MAY_READ | AA_MAY_WRITE | AA_MAY_EXEC | AA_EXEC_MMAP |
2928+ AA_MAY_LINK));
2929+
2930+ /* Special case access to /proc/self/attr/current
2931+ * Currently we only allow access if opened O_WRONLY
2932+ */
2933+ if (mask == MAY_WRITE && strncmp(PROCPFX, name, PROCLEN) == 0 &&
2934+ aa_taskattr_access(name + PROCLEN))
2935+ goto done;
2936+
2937+ mode = 0;
2938+
2939+ /* iterate over partition, one permission bit at a time */
2940+ for (i = 0; i <= POS_AA_FILE_MAX; i++) {
2941+ struct aa_entry *entry;
2942+
2943+ /* do we have to accumulate this bit?
2944+ * or have we already accumulated it (shortcut below)? */
2945+ if (!(mask & (1 << i)) || mode & (1 << i))
2946+ continue;
2947+
2948+ list_for_each_entry(entry, &active->file_entryp[i],
2949+ listp[i]) {
2950+ if (aamatch_match(name, entry->filename,
2951+ entry->type, entry->extradata)) {
2952+ /* Shortcut, accumulate all bits present */
2953+ mode |= entry->mode;
2954+
2955+ /* Mask bits are overloaded
2956+ * MAY_{EXEC,WRITE,READ,APPEND} are used by
2957+ * kernel, other values are used locally only.
2958+ */
2959+ if ((mode & mask) == mask) {
2960+ AA_DEBUG("MATCH! %s=0x%x [total mode=0x%x]\n",
2961+ name, mask, mode);
2962+
2963+ goto done;
2964+ }
2965+ }
2966+ }
2967+ }
2968+
2969+ /* return permissions not satisfied */
2970+ error = mask & ~mode;
2971+
2972+done:
2973+ return error;
2974+}
2975+
2976+/**
2977+ * aa_link_perm - test permission to link to a file
2978+ * @active: profile to check against
2979+ * @link: name of link being created
2980+ * @target: name of target to be linked to
2981+ *
2982+ * Look up permission mode on both @link and @target. @link must have same
2983+ * permission mode as @target. At least @link must have the link bit enabled.
2984+ * Return %0 on success, error otherwise.
2985+ */
2986+static int aa_link_perm(struct aaprofile *active,
2987+ const char *link, const char *target)
2988+{
2989+ int l_mode, t_mode, ret;
2990+
2991+ l_mode = aa_file_mode(active, link);
2992+ if (l_mode & AA_MAY_LINK) {
2993+ /* mask off link bit */
2994+ l_mode &= ~AA_MAY_LINK;
2995+
2996+ t_mode = aa_file_mode(active, target);
2997+ t_mode &= ~AA_MAY_LINK;
2998+
2999+ ret = (l_mode == t_mode);
3000+ } else {
3001+ ret = 0;
3002+ }
3003+
3004+ return ret;
3005+}
3006+
3007+/**
3008+ * _aa_perm_dentry
3009+ * @active: profile to check against
3010+ * @dentry: requested dentry
3011+ * @mask: mask of requested operations
3012+ * @pname: pointer to hold matched pathname (if any)
3013+ *
3014+ * Helper function. Obtain pathname for specified dentry. Verify if profile
3015+ * authorizes mask operations on pathname (due to lack of vfsmnt it is sadly
3016+ * necessary to search mountpoints in namespace -- when nameidata is passed
3017+ * more fully, this code can go away). If more than one mountpoint matches
3018+ * but none satisfy the profile, only the first pathname (mountpoint) is
3019+ * returned for subsequent logging.
3020+ *
3021+ * Return %0 (success), +ve (mask of permissions not satisfied) or -ve (system
3022+ * error, most likely -%ENOMEM).
3023+ */
3024+static int _aa_perm_dentry(struct aaprofile *active, struct dentry *dentry,
3025+ int mask, const char **pname)
3026+{
3027+ char *name = NULL, *failed_name = NULL;
3028+ struct aa_path_data data;
3029+ int error = 0, failed_error = 0, path_error,
3030+ complain = PROFILE_COMPLAIN(active);
3031+
3032+ /* search all paths to dentry */
3033+
3034+ aa_path_begin(dentry, &data);
3035+ do {
3036+ name = aa_path_getname(&data);
3037+ if (name) {
3038+ /* error here is 0 (success) or +ve (mask of perms) */
3039+ error = aa_file_perm(active, name, mask);
3040+
3041+ /* access via any path is enough */
3042+ if (complain || error == 0)
3043+ break; /* Caller must free name */
3044+
3045+ /* Already have an path that failed? */
3046+ if (failed_name) {
3047+ aa_put_name(name);
3048+ } else {
3049+ failed_name = name;
3050+ failed_error = error;
3051+ }
3052+ }
3053+ } while (name);
3054+
3055+ if ((path_error = aa_path_end(&data)) != 0) {
3056+ dentry_xlate_error(dentry, path_error, "dentry");
3057+ WARN_ON(name); /* name should not be set if error */
3058+ error = path_error;
3059+ name = NULL;
3060+ } else if (name) {
3061+ if (failed_name)
3062+ aa_put_name(failed_name);
3063+ } else {
3064+ name = failed_name;
3065+ error = failed_error;
3066+ }
3067+
3068+ *pname = name;
3069+
3070+ return error;
3071+}
3072+
3073+/**************************
3074+ * Global utility functions
3075+ *************************/
3076+
3077+/**
3078+ * attach_nullprofile - allocate and attach a null_profile hat to profile
3079+ * @profile: profile to attach a null_profile hat to.
3080+ *
3081+ * Return %0 (success) or error (-%ENOMEM)
3082+ */
3083+int attach_nullprofile(struct aaprofile *profile)
3084+{
3085+ struct aaprofile *hat = NULL;
3086+ char *hatname = NULL;
3087+
3088+ hat = alloc_aaprofile();
3089+ if (!hat)
3090+ goto fail;
3091+ if (profile->flags.complain)
3092+ hatname = kstrdup("null-complain-profile", GFP_KERNEL);
3093+ else
3094+ hatname = kstrdup("null-profile", GFP_KERNEL);
3095+ if (!hatname)
3096+ goto fail;
3097+
3098+ hat->flags.complain = profile->flags.complain;
3099+ hat->name = hatname;
3100+ hat->parent = profile;
3101+
3102+ profile->null_profile = hat;
3103+
3104+ return 0;
3105+
3106+fail:
3107+ kfree(hatname);
3108+ free_aaprofile(hat);
3109+
3110+ return -ENOMEM;
3111+}
3112+
3113+
3114+/**
3115+ * alloc_null_complain_profile - Allocate the global null_complain_profile.
3116+ *
3117+ * Return %0 (success) or error (-%ENOMEM)
3118+ */
3119+int alloc_null_complain_profile(void)
3120+{
3121+ null_complain_profile = alloc_aaprofile();
3122+ if (!null_complain_profile)
3123+ goto fail;
3124+
3125+ null_complain_profile->name =
3126+ kstrdup("null-complain-profile", GFP_KERNEL);
3127+
3128+ if (!null_complain_profile->name)
3129+ goto fail;
3130+
3131+ null_complain_profile->flags.complain = 1;
3132+ if (attach_nullprofile(null_complain_profile))
3133+ goto fail;
3134+
3135+ return 0;
3136+
3137+fail:
3138+ /* free_aaprofile is safe for freeing partially constructed objects */
3139+ free_aaprofile(null_complain_profile);
3140+ null_complain_profile = NULL;
3141+
3142+ return -ENOMEM;
3143+}
3144+
3145+/**
3146+ * free_null_complain_profile - Free null profiles
3147+ */
3148+void free_null_complain_profile(void)
3149+{
3150+ put_aaprofile(null_complain_profile);
3151+ null_complain_profile = NULL;
3152+}
3153+
3154+/**
3155+ * aa_audit_message - Log a message to the audit subsystem
3156+ * @active: profile to check against
3157+ * @gfp: allocation flags
3158+ * @flags: audit flags
3159+ * @fmt: varargs fmt
3160+ */
3161+int aa_audit_message(struct aaprofile *active, gfp_t gfp, int flags,
3162+ const char *fmt, ...)
3163+{
3164+ int ret;
3165+ struct aa_audit sa;
3166+
3167+ sa.type = AA_AUDITTYPE_MSG;
3168+ sa.name = fmt;
3169+ va_start(sa.vaval, fmt);
3170+ sa.flags = flags;
3171+ sa.gfp_mask = gfp;
3172+ sa.error_code = 0;
3173+ sa.result = 0; /* fake failure: force message to be logged */
3174+
3175+ ret = aa_audit(active, &sa);
3176+
3177+ va_end(sa.vaval);
3178+
3179+ return ret;
3180+}
3181+
3182+/**
3183+ * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem
3184+ * @active: profile to check against
3185+ * @gfp: memory allocation flags
3186+ * @call: aa syscall cache bit number
3187+ */
3188+int aa_audit_syscallreject(struct aaprofile *active, gfp_t gfp,
3189+ enum aasyscall call)
3190+{
3191+ struct aa_audit sa;
3192+ int error = -EPERM;
3193+
3194+ if (!syscall_is_cached(call)) {
3195+ sa.type = AA_AUDITTYPE_SYSCALL;
3196+ sa.name = syscall_to_name(call);
3197+ sa.flags = 0;
3198+ sa.gfp_mask = gfp;
3199+ sa.error_code = 0;
3200+ sa.result = 0; /* failure */
3201+
3202+ error = aa_audit(active, &sa);
3203+ if (error == -EPERM)
3204+ add_to_cached_syscalls(call);
3205+ }
3206+ return error;
3207+}
3208+
3209+/**
3210+ * aa_audit - Log an audit event to the audit subsystem
3211+ * @active: profile to check against
3212+ * @sa: audit event
3213+ */
3214+int aa_audit(struct aaprofile *active, const struct aa_audit *sa)
3215+{
3216+ struct audit_buffer *ab = NULL;
3217+ struct audit_context *ctx;
3218+
3219+ const char *logcls;
3220+ unsigned int flags;
3221+ int audit = 0,
3222+ complain = 0,
3223+ error = -EINVAL,
3224+ opspec_error = -EACCES;
3225+
3226+ const gfp_t gfp_mask = sa->gfp_mask;
3227+
3228+ WARN_ON(sa->type >= AA_AUDITTYPE__END);
3229+
3230+ /*
3231+ * sa->result: 1 success, 0 failure
3232+ * sa->error_code: success: 0
3233+ * failure: +ve mask of failed permissions or -ve
3234+ * system error
3235+ */
3236+
3237+ if (likely(sa->result)) {
3238+ if (likely(!PROFILE_AUDIT(active))) {
3239+ /* nothing to log */
3240+ error = 0;
3241+ goto out;
3242+ } else {
3243+ audit = 1;
3244+ logcls = "AUDITING";
3245+ }
3246+ } else if (sa->error_code < 0) {
3247+ audit_log(current->audit_context, gfp_mask, AUDIT_SD,
3248+ "Internal error auditing event type %d (error %d)",
3249+ sa->type, sa->error_code);
3250+ AA_ERROR("Internal error auditing event type %d (error %d)\n",
3251+ sa->type, sa->error_code);
3252+ error = sa->error_code;
3253+ goto out;
3254+ } else if (sa->type == AA_AUDITTYPE_SYSCALL) {
3255+ /* Currently AA_AUDITTYPE_SYSCALL is for rejects only.
3256+ * Values set by aa_audit_syscallreject will get us here.
3257+ */
3258+ logcls = "REJECTING";
3259+ } else {
3260+ complain = PROFILE_COMPLAIN(active);
3261+ logcls = complain ? "PERMITTING" : "REJECTING";
3262+ }
3263+
3264+ /* test if event has already been logged and cached used to log
3265+ * only first time event occurs.
3266+ */
3267+ if (sa->type == AA_AUDITTYPE_CAP) {
3268+ if (cap_is_cached(sa->ival)) {
3269+ opspec_error = -EPERM;
3270+ goto skip_logging;
3271+ }
3272+ }
3273+
3274+ /* In future extend w/ per-profile flags
3275+ * (flags |= sa->active->flags)
3276+ */
3277+ flags = sa->flags;
3278+ if (apparmor_logsyscall)
3279+ flags |= AA_AUDITFLAG_AUDITSS_SYSCALL;
3280+
3281+
3282+ /* Force full audit syscall logging regardless of global setting if
3283+ * we are rejecting a syscall
3284+ */
3285+ if (sa->type == AA_AUDITTYPE_SYSCALL) {
3286+ ctx = current->audit_context;
3287+ } else {
3288+ ctx = (flags & AA_AUDITFLAG_AUDITSS_SYSCALL) ?
3289+ current->audit_context : NULL;
3290+ }
3291+
3292+ ab = audit_log_start(ctx, gfp_mask, AUDIT_SD);
3293+
3294+ if (!ab) {
3295+ AA_ERROR("Unable to log event (%d) to audit subsys\n",
3296+ sa->type);
3297+ if (complain)
3298+ error = 0;
3299+ goto out;
3300+ }
3301+
3302+ /* messages get special handling */
3303+ if (sa->type == AA_AUDITTYPE_MSG) {
3304+ audit_log_vformat(ab, sa->name, sa->vaval);
3305+ audit_log_end(ab);
3306+ error = 0;
3307+ goto out;
3308+ }
3309+
3310+ /* log operation */
3311+
3312+ audit_log_format(ab, "%s ", logcls); /* REJECTING/ALLOWING/etc */
3313+
3314+ if (sa->type == AA_AUDITTYPE_FILE) {
3315+ int perm = audit ? sa->ival : sa->error_code;
3316+
3317+ audit_log_format(ab, "%s%s%s%s%s access to %s ",
3318+ perm & AA_EXEC_MMAP ? "m" : "",
3319+ perm & AA_MAY_READ ? "r" : "",
3320+ perm & AA_MAY_WRITE ? "w" : "",
3321+ perm & AA_MAY_EXEC ? "x" : "",
3322+ perm & AA_MAY_LINK ? "l" : "",
3323+ sa->name);
3324+
3325+ opspec_error = -EPERM;
3326+
3327+ } else if (sa->type == AA_AUDITTYPE_DIR) {
3328+ audit_log_format(ab, "%s on %s ",
3329+ sa->ival == aa_dir_mkdir ? "mkdir" : "rmdir",
3330+ sa->name);
3331+
3332+ } else if (sa->type == AA_AUDITTYPE_ATTR) {
3333+ struct iattr *iattr = (struct iattr*)sa->pval;
3334+
3335+ audit_log_format(ab,
3336+ "attribute (%s%s%s%s%s%s%s) change to %s ",
3337+ iattr->ia_valid & ATTR_MODE ? "mode," : "",
3338+ iattr->ia_valid & ATTR_UID ? "uid," : "",
3339+ iattr->ia_valid & ATTR_GID ? "gid," : "",
3340+ iattr->ia_valid & ATTR_SIZE ? "size," : "",
3341+ ((iattr->ia_valid & ATTR_ATIME_SET) ||
3342+ (iattr->ia_valid & ATTR_ATIME)) ? "atime," : "",
3343+ ((iattr->ia_valid & ATTR_MTIME_SET) ||
3344+ (iattr->ia_valid & ATTR_MTIME)) ? "mtime," : "",
3345+ iattr->ia_valid & ATTR_CTIME ? "ctime," : "",
3346+ sa->name);
3347+
3348+ } else if (sa->type == AA_AUDITTYPE_XATTR) {
3349+ const char *fmt;
3350+ switch (sa->ival) {
3351+ case aa_xattr_get:
3352+ fmt = "xattr get";
3353+ break;
3354+ case aa_xattr_set:
3355+ fmt = "xattr set";
3356+ break;
3357+ case aa_xattr_list:
3358+ fmt = "xattr list";
3359+ break;
3360+ case aa_xattr_remove:
3361+ fmt = "xattr remove";
3362+ break;
3363+ default:
3364+ fmt = "xattr <unknown>";
3365+ break;
3366+ }
3367+
3368+ audit_log_format(ab, "%s on %s ", fmt, sa->name);
3369+
3370+ } else if (sa->type == AA_AUDITTYPE_LINK) {
3371+ audit_log_format(ab,
3372+ "link access from %s to %s ",
3373+ sa->name,
3374+ (char*)sa->pval);
3375+
3376+ } else if (sa->type == AA_AUDITTYPE_CAP) {
3377+ audit_log_format(ab,
3378+ "access to capability '%s' ",
3379+ capability_to_name(sa->ival));
3380+ add_to_cached_caps(sa->ival);
3381+ opspec_error = -EPERM;
3382+ } else if (sa->type == AA_AUDITTYPE_SYSCALL) {
3383+ audit_log_format(ab, "access to syscall '%s' ", sa->name);
3384+
3385+ opspec_error = -EPERM;
3386+ } else {
3387+ /* -EINVAL -- will WARN_ON above */
3388+ goto out;
3389+ }
3390+
3391+ audit_log_format(ab, "(%s(%d) profile %s active %s)",
3392+ current->comm, current->pid,
3393+ BASE_PROFILE(active)->name, active->name);
3394+
3395+ audit_log_end(ab);
3396+
3397+skip_logging:
3398+ if (complain)
3399+ error = 0;
3400+ else
3401+ error = sa->result ? 0 : opspec_error;
3402+
3403+out:
3404+ return error;
3405+}
3406+
3407+/**
3408+ * aa_get_name - retrieve fully qualified path name
3409+ * @dentry: relative path element
3410+ * @mnt: where in tree
3411+ *
3412+ * Returns fully qualified path name on sucess, NULL on failure.
3413+ * aa_put_name must be used to free allocated buffer.
3414+ */
3415+char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt)
3416+{
3417+ char *page, *name;
3418+
3419+ page = (char *)__get_free_page(GFP_KERNEL);
3420+ if (!page) {
3421+ name = ERR_PTR(-ENOMEM);
3422+ goto out;
3423+ }
3424+
3425+ name = d_path(dentry, mnt, page, PAGE_SIZE);
3426+ /* check for (deleted) that d_path appends to pathnames if the dentry
3427+ * has been removed from the cache.
3428+ * The size > deleted_size and strcmp checks are redundant safe guards.
3429+ */
3430+ if (IS_ERR(name)) {
3431+ free_page((unsigned long)page);
3432+ } else {
3433+ const char deleted_str[] = " (deleted)";
3434+ const size_t deleted_size = sizeof(deleted_str) - 1;
3435+ size_t size;
3436+ size = strlen(name);
3437+ if (!IS_ROOT(dentry) && d_unhashed(dentry) &&
3438+ size > deleted_size &&
3439+ strcmp(name + size - deleted_size, deleted_str) == 0)
3440+ name[size - deleted_size] = '\0';
3441+ AA_DEBUG("%s: full_path=%s\n", __FUNCTION__, name);
3442+ }
3443+
3444+out:
3445+ return name;
3446+}
3447+
3448+/***********************************
3449+ * Global permission check functions
3450+ ***********************************/
3451+
3452+/**
3453+ * aa_attr - check whether attribute change allowed
3454+ * @active: profile to check against
3455+ * @dentry: file to check
3456+ * @iattr: attribute changes requested
3457+ */
3458+int aa_attr(struct aaprofile *active, struct dentry *dentry,
3459+ struct iattr *iattr)
3460+{
3461+ int error = 0, permerror;
3462+ struct aa_audit sa;
3463+
3464+ sa.type = AA_AUDITTYPE_ATTR;
3465+ sa.pval = iattr;
3466+ sa.flags = 0;
3467+ sa.gfp_mask = GFP_KERNEL;
3468+
3469+ permerror = _aa_perm_dentry(active, dentry, MAY_WRITE, &sa.name);
3470+ aa_permerror2result(permerror, &sa);
3471+
3472+ error = aa_audit(active, &sa);
3473+
3474+ aa_put_name(sa.name);
3475+
3476+ return error;
3477+}
3478+
3479+/**
3480+ * aa_xattr - check whether xattr attribute change allowed
3481+ * @active: profile to check against
3482+ * @dentry: file to check
3483+ * @xattr: xattr to check
3484+ * @xattroptype: type of xattr operation
3485+ */
3486+int aa_xattr(struct aaprofile *active, struct dentry *dentry,
3487+ const char *xattr, enum aa_xattroptype xattroptype)
3488+{
3489+ int error = 0, permerror, mask = 0;
3490+ struct aa_audit sa;
3491+
3492+ /* if not confined or empty mask permission granted */
3493+ if (!active)
3494+ goto out;
3495+
3496+ if (xattroptype == aa_xattr_get || xattroptype == aa_xattr_list)
3497+ mask = MAY_READ;
3498+ else if (xattroptype == aa_xattr_set || xattroptype == aa_xattr_remove)
3499+ mask = MAY_WRITE;
3500+
3501+ sa.type = AA_AUDITTYPE_XATTR;
3502+ sa.ival = xattroptype;
3503+ sa.pval = xattr;
3504+ sa.flags = 0;
3505+ sa.gfp_mask = GFP_KERNEL;
3506+
3507+ permerror = _aa_perm_dentry(active, dentry, mask, &sa.name);
3508+ aa_permerror2result(permerror, &sa);
3509+
3510+ error = aa_audit(active, &sa);
3511+
3512+ aa_put_name(sa.name);
3513+
3514+out:
3515+ return error;
3516+}
3517+
3518+/**
3519+ * aa_perm - basic apparmor permissions check
3520+ * @active: profile to check against
3521+ * @dentry: dentry
3522+ * @mnt: mountpoint
3523+ * @mask: access mode requested
3524+ *
3525+ * Determine if access (mask) for dentry is authorized by active
3526+ * profile. Result, %0 (success), -ve (error)
3527+ */
3528+int aa_perm(struct aaprofile *active, struct dentry *dentry,
3529+ struct vfsmount *mnt, int mask)
3530+{
3531+ int error = 0, permerror;
3532+ struct aa_audit sa;
3533+
3534+ if (!active)
3535+ goto out;
3536+
3537+ if ((mask = aa_filter_mask(mask, dentry->d_inode)) == 0)
3538+ goto out;
3539+
3540+ sa.type = AA_AUDITTYPE_FILE;
3541+ sa.name = aa_get_name(dentry, mnt);
3542+ sa.ival = mask;
3543+ sa.flags = 0;
3544+ sa.gfp_mask = GFP_KERNEL;
3545+
3546+ if (IS_ERR(sa.name)) {
3547+ permerror = PTR_ERR(sa.name);
3548+ sa.name = NULL;
3549+ } else {
3550+ permerror = aa_file_perm(active, sa.name, mask);
3551+ }
3552+
3553+ aa_permerror2result(permerror, &sa);
3554+
3555+ error = aa_audit(active, &sa);
3556+
3557+ aa_put_name(sa.name);
3558+
3559+out:
3560+ return error;
3561+}
3562+
3563+/**
3564+ * aa_perm_nameidata: interface to sd_perm accepting nameidata
3565+ * @active: profile to check against
3566+ * @nd: namespace data (for vfsmnt and dentry)
3567+ * @mask: access mode requested
3568+ */
3569+int aa_perm_nameidata(struct aaprofile *active, struct nameidata *nd, int mask)
3570+{
3571+ int error = 0;
3572+
3573+ if (nd)
3574+ error = aa_perm(active, nd->dentry, nd->mnt, mask);
3575+
3576+ return error;
3577+}
3578+
3579+/**
3580+ * aa_perm_dentry - file permissions interface when no vfsmnt available
3581+ * @active: profile to check against
3582+ * @dentry: requested dentry
3583+ * @mask: access mode requested
3584+ *
3585+ * Determine if access (mask) for dentry is authorized by active profile.
3586+ * Result, %0 (success), -ve (error)
3587+ */
3588+int aa_perm_dentry(struct aaprofile *active, struct dentry *dentry, int mask)
3589+{
3590+ int error = 0, permerror;
3591+ struct aa_audit sa;
3592+
3593+ if (!active)
3594+ goto out;
3595+
3596+ if ((mask = aa_filter_mask(mask, dentry->d_inode)) == 0)
3597+ goto out;
3598+
3599+ sa.type = AA_AUDITTYPE_FILE;
3600+ sa.ival = mask;
3601+ sa.flags = 0;
3602+ sa.gfp_mask = GFP_KERNEL;
3603+
3604+ permerror = _aa_perm_dentry(active, dentry, mask, &sa.name);
3605+ aa_permerror2result(permerror, &sa);
3606+
3607+ error = aa_audit(active, &sa);
3608+
3609+ aa_put_name(sa.name);
3610+
3611+out:
3612+ return error;
3613+}
3614+
3615+/**
3616+ * aa_perm_dir
3617+ * @active: profile to check against
3618+ * @dentry: requested dentry
3619+ * @diroptype: aa_dir_mkdir or aa_dir_rmdir
3620+ *
3621+ * Determine if directory operation (make/remove) for dentry is authorized
3622+ * by @active profile.
3623+ * Result, %0 (success), -ve (error)
3624+ */
3625+int aa_perm_dir(struct aaprofile *active, struct dentry *dentry,
3626+ enum aa_diroptype diroptype)
3627+{
3628+ int error = 0, permerror, mask;
3629+ struct aa_audit sa;
3630+
3631+ WARN_ON(diroptype != aa_dir_mkdir && diroptype != aa_dir_rmdir);
3632+
3633+ if (!active)
3634+ goto out;
3635+
3636+ mask = MAY_WRITE;
3637+
3638+ sa.type = AA_AUDITTYPE_DIR;
3639+ sa.ival = diroptype;
3640+ sa.flags = 0;
3641+ sa.gfp_mask = GFP_KERNEL;
3642+
3643+ permerror = _aa_perm_dentry(active, dentry, mask, &sa.name);
3644+ aa_permerror2result(permerror, &sa);
3645+
3646+ error = aa_audit(active, &sa);
3647+
3648+ aa_put_name(sa.name);
3649+
3650+out:
3651+ return error;
3652+}
3653+
3654+/**
3655+ * aa_capability - test permission to use capability
3656+ * @active: profile to check against
3657+ * @cap: capability to be tested
3658+ *
3659+ * Look up capability in active profile capability set.
3660+ * Return %0 (success), -%EPERM (error)
3661+ */
3662+int aa_capability(struct aaprofile *active, int cap)
3663+{
3664+ int error = 0;
3665+
3666+ struct aa_audit sa;
3667+
3668+ sa.type = AA_AUDITTYPE_CAP;
3669+ sa.name = NULL;
3670+ sa.ival = cap;
3671+ sa.flags = 0;
3672+ sa.error_code = 0;
3673+ sa.result = cap_raised(active->capabilities, cap);
3674+ sa.gfp_mask = GFP_ATOMIC;
3675+
3676+ error = aa_audit(active, &sa);
3677+
3678+ return error;
3679+}
3680+
3681+/**
3682+ * aa_link - hard link check
3683+ * @active: profile to check against
3684+ * @link: dentry for link being created
3685+ * @target: dentry for link target
3686+ *
3687+ * Checks link permissions for all possible name combinations. This is
3688+ * particularly ugly. Returns %0 on sucess, error otherwise.
3689+ */
3690+int aa_link(struct aaprofile *active, struct dentry *link,
3691+ struct dentry *target)
3692+{
3693+ char *iname = NULL, *oname = NULL,
3694+ *failed_iname = NULL, *failed_oname = NULL;
3695+ unsigned int result = 0;
3696+ int error, path_error, error_code = 0, match = 0,
3697+ complain = PROFILE_COMPLAIN(active);
3698+ struct aa_path_data idata, odata;
3699+ struct aa_audit sa;
3700+
3701+ if (!active)
3702+ return 0;
3703+
3704+ /* Perform nested lookup for names.
3705+ * This is necessary in the case where /dev/block is mounted
3706+ * multiple times, i.e /dev/block->/a and /dev/block->/b
3707+ * This allows us to detect links where src/dest are on different
3708+ * mounts. N.B no support yet for links across bind mounts of
3709+ * the form mount -bind /mnt/subpath /mnt2
3710+ *
3711+ * Getting direct access to vfsmounts (via nameidata) for link and
3712+ * target would allow all this uglyness to go away.
3713+ *
3714+ * If more than one mountpoint matches but none satisfy the profile,
3715+ * only the first pathname (mountpoint) is logged.
3716+ */
3717+
3718+ __aa_path_begin(target, link, &odata);
3719+ do {
3720+ oname = aa_path_getname(&odata);
3721+ if (oname) {
3722+ aa_path_begin(target, &idata);
3723+ do {
3724+ iname = aa_path_getname(&idata);
3725+ if (iname) {
3726+ result = aa_link_perm(active, oname,
3727+ iname);
3728+
3729+ /* access via any path is enough */
3730+ if (result || complain) {
3731+ match = 1;
3732+ break;
3733+ }
3734+
3735+ /* Already have an path that failed? */
3736+ if (failed_iname) {
3737+ aa_put_name(iname);
3738+ } else {
3739+ failed_iname = iname;
3740+ failed_oname = oname;
3741+ }
3742+ }
3743+ } while (iname && !match);
3744+
3745+ /* should not be possible if we matched */
3746+ if ((path_error = aa_path_end(&idata)) != 0) {
3747+ dentry_xlate_error(target, path_error,
3748+ "inner dentry [link]");
3749+
3750+ /* name should not be set if error */
3751+ WARN_ON(iname);
3752+
3753+ error_code = path_error;
3754+ }
3755+
3756+ /* don't release if we're saving it */
3757+ if (!match && failed_oname != oname)
3758+ aa_put_name(oname);
3759+ }
3760+ } while (oname && !match);
3761+
3762+ if (error_code != 0) {
3763+ /* inner error */
3764+ (void)aa_path_end(&odata);
3765+ } else if ((path_error = aa_path_end(&odata)) != 0) {
3766+ dentry_xlate_error(link, path_error, "outer dentry [link]");
3767+ error_code = path_error;
3768+ }
3769+
3770+ if (error_code != 0) {
3771+ /* inner or outer error */
3772+ result = 0;
3773+ } else if (!match) {
3774+ /* failed to match */
3775+ WARN_ON(iname);
3776+ WARN_ON(oname);
3777+
3778+ result = 0;
3779+ iname = failed_iname;
3780+ oname = failed_oname;
3781+ }
3782+
3783+ sa.type = AA_AUDITTYPE_LINK;
3784+ sa.name = oname; /* link */
3785+ sa.pval = iname; /* target */
3786+ sa.flags = 0;
3787+ sa.error_code = error_code;
3788+ sa.result = result;
3789+ sa.gfp_mask = GFP_KERNEL;
3790+
3791+ error = aa_audit(active, &sa);
3792+
3793+ if (failed_oname != oname)
3794+ aa_put_name(failed_oname);
3795+ if (failed_iname != iname)
3796+ aa_put_name(failed_iname);
3797+
3798+ aa_put_name(oname);
3799+ aa_put_name(iname);
3800+
3801+ return error;
3802+}
3803+
3804+/*******************************
3805+ * Global task related functions
3806+ *******************************/
3807+
3808+/**
3809+ * aa_fork - create a new subdomain
3810+ * @p: new process
3811+ *
3812+ * Create a new subdomain for newly created process @p if it's parent
3813+ * is already confined. Otherwise a subdomain will be lazily allocated
3814+ * will get one with NULL values. Return 0 on sucess.
3815+ * for the child if it subsequently execs (in aa_register).
3816+ * Return 0 on sucess.
3817+ *
3818+ * The sd_lock is used to maintain consistency against profile
3819+ * replacement/removal.
3820+ */
3821+
3822+int aa_fork(struct task_struct *p)
3823+{
3824+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
3825+ struct subdomain *newsd = NULL;
3826+
3827+ AA_DEBUG("%s\n", __FUNCTION__);
3828+
3829+ if (__aa_is_confined(sd)) {
3830+ unsigned long flags;
3831+
3832+ newsd = alloc_subdomain(p);
3833+
3834+ if (!newsd)
3835+ return -ENOMEM;
3836+
3837+ /* Use locking here instead of getting the reference
3838+ * because we need both the old reference and the
3839+ * new reference to be consistent.
3840+ */
3841+ spin_lock_irqsave(&sd_lock, flags);
3842+ aa_switch(newsd, sd->active);
3843+ newsd->hat_magic = sd->hat_magic;
3844+ spin_unlock_irqrestore(&sd_lock, flags);
3845+
3846+ if (SUBDOMAIN_COMPLAIN(sd) &&
3847+ sd->active == null_complain_profile)
3848+ LOG_HINT(sd->active, GFP_KERNEL, HINT_FORK,
3849+ "pid=%d child=%d\n",
3850+ current->pid, p->pid);
3851+ }
3852+ p->security = newsd;
3853+ return 0;
3854+}
3855+
3856+/**
3857+ * aa_register - register a new program
3858+ * @bprm: binprm of program being registered
3859+ *
3860+ * Try to register a new program during execve(). This should give the
3861+ * new program a valid subdomain.
3862+ */
3863+int aa_register(struct linux_binprm *bprm)
3864+{
3865+ char *filename;
3866+ struct file *filp = bprm->file;
3867+ struct aaprofile *active;
3868+ struct aaprofile *newprofile = NULL, unconstrained_flag;
3869+ int error = -ENOMEM,
3870+ exec_mode = 0,
3871+ find_profile = 0,
3872+ find_profile_mandatory = 0,
3873+ unsafe_exec = 0,
3874+ complain = 0;
3875+
3876+ AA_DEBUG("%s\n", __FUNCTION__);
3877+
3878+ filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt);
3879+ if (IS_ERR(filename)) {
3880+ AA_WARN("%s: Failed to get filename\n", __FUNCTION__);
3881+ goto out;
3882+ }
3883+
3884+ error = 0;
3885+
3886+ active = get_active_aaprofile();
3887+
3888+ if (!active) {
3889+ /* Unconfined task, load profile if it exists */
3890+ find_profile = 1;
3891+ goto find_profile;
3892+ }
3893+
3894+ complain = PROFILE_COMPLAIN(active);
3895+
3896+ /* Confined task, determine what mode inherit, unconstrained or
3897+ * mandatory to load new profile
3898+ */
3899+ if (aa_get_execmode(active, filename, &exec_mode, &unsafe_exec)) {
3900+ switch (exec_mode) {
3901+ case AA_EXEC_INHERIT:
3902+ /* do nothing - setting of profile
3903+ * already handed in aa_fork
3904+ */
3905+ AA_DEBUG("%s: INHERIT %s\n",
3906+ __FUNCTION__,
3907+ filename);
3908+ break;
3909+
3910+ case AA_EXEC_UNCONSTRAINED:
3911+ AA_DEBUG("%s: UNCONSTRAINED %s\n",
3912+ __FUNCTION__,
3913+ filename);
3914+
3915+ /* unload profile */
3916+ newprofile = &unconstrained_flag;
3917+ break;
3918+
3919+ case AA_EXEC_PROFILE:
3920+ AA_DEBUG("%s: PROFILE %s\n",
3921+ __FUNCTION__,
3922+ filename);
3923+
3924+ find_profile = 1;
3925+ find_profile_mandatory = 1;
3926+ break;
3927+
3928+ case AA_MAY_EXEC:
3929+ /* this should not happen, entries
3930+ * with just EXEC only should be
3931+ * rejected at profile load time
3932+ */
3933+ AA_ERROR("%s: Rejecting exec(2) of image '%s'. "
3934+ "AA_MAY_EXEC without exec qualifier invalid "
3935+ "(%s(%d) profile %s active %s\n",
3936+ __FUNCTION__,
3937+ filename,
3938+ current->comm, current->pid,
3939+ BASE_PROFILE(active)->name, active->name);
3940+ error = -EPERM;
3941+ break;
3942+
3943+ default:
3944+ AA_ERROR("%s: Rejecting exec(2) of image '%s'. "
3945+ "Unknown exec qualifier %x "
3946+ "(%s (pid %d) profile %s active %s)\n",
3947+ __FUNCTION__,
3948+ filename,
3949+ exec_mode,
3950+ current->comm, current->pid,
3951+ BASE_PROFILE(active)->name, active->name);
3952+ error = -EPERM;
3953+ break;
3954+ }
3955+
3956+ } else if (complain) {
3957+ /* There was no entry in calling profile
3958+ * describing mode to execute image in.
3959+ * Drop into null-profile (disabling secure exec).
3960+ */
3961+ newprofile = get_aaprofile(null_complain_profile);
3962+ unsafe_exec = 1;
3963+ } else {
3964+ AA_WARN("%s: Rejecting exec(2) of image '%s'. "
3965+ "Unable to determine exec qualifier "
3966+ "(%s (pid %d) profile %s active %s)\n",
3967+ __FUNCTION__,
3968+ filename,
3969+ current->comm, current->pid,
3970+ BASE_PROFILE(active)->name, active->name);
3971+ error = -EPERM;
3972+ }
3973+
3974+
3975+find_profile:
3976+ if (!find_profile)
3977+ goto apply_profile;
3978+
3979+ /* Locate new profile */
3980+ newprofile = aa_profilelist_find(filename);
3981+ if (newprofile) {
3982+ AA_DEBUG("%s: setting profile %s\n",
3983+ __FUNCTION__, newprofile->name);
3984+ } else if (find_profile_mandatory) {
3985+ /* Profile (mandatory) could not be found */
3986+
3987+ if (complain) {
3988+ LOG_HINT(active, GFP_KERNEL, HINT_MANDPROF,
3989+ "image=%s pid=%d profile=%s active=%s\n",
3990+ filename,
3991+ current->pid,
3992+ BASE_PROFILE(active)->name, active->name);
3993+
3994+ newprofile = get_aaprofile(null_complain_profile);
3995+ } else {
3996+ AA_WARN("REJECTING exec(2) of image '%s'. "
3997+ "Profile mandatory and not found "
3998+ "(%s(%d) profile %s active %s)\n",
3999+ filename,
4000+ current->comm, current->pid,
4001+ BASE_PROFILE(active)->name, active->name);
4002+ error = -EPERM;
4003+ }
4004+ } else {
4005+ /* Profile (non-mandatory) could not be found */
4006+
4007+ /* Only way we can get into this code is if task
4008+ * is unconstrained.
4009+ */
4010+
4011+ WARN_ON(active);
4012+
4013+ AA_DEBUG("%s: No profile found for exec image %s\n",
4014+ __FUNCTION__,
4015+ filename);
4016+ } /* newprofile */
4017+
4018+
4019+apply_profile:
4020+ /* Apply profile if necessary */
4021+ if (newprofile) {
4022+ struct subdomain *sd, *lazy_sd = NULL;
4023+ unsigned long flags;
4024+
4025+ if (newprofile == &unconstrained_flag)
4026+ newprofile = NULL;
4027+
4028+ /* grab a lock - this is to guarentee consistency against
4029+ * other writers of subdomain (replacement/removal)
4030+ *
4031+ * Several things may have changed since the code above
4032+ *
4033+ * - Task may be presently unconfined (have no sd). In which
4034+ * case we have to lazily allocate one. Note we may be raced
4035+ * to this allocation by a setprofile.
4036+ *
4037+ * - If we are a confined process, active is a refcounted copy
4038+ * of the profile that was on the subdomain at entry.
4039+ * This allows us to not have to hold a lock around
4040+ * all this code. If profile replacement has taken place
4041+ * our active may not equal sd->active any more.
4042+ * This is okay since the operation is treated as if
4043+ * the transition occured before replacement.
4044+ *
4045+ * - If newprofile points to an actual profile (result of
4046+ * aa_profilelist_find above), this profile may have been
4047+ * replaced. We need to fix it up. Doing this to avoid
4048+ * having to hold a lock around all this code.
4049+ */
4050+
4051+ if (!active && !(sd = AA_SUBDOMAIN(current->security))) {
4052+ lazy_sd = alloc_subdomain(current);
4053+ if (!lazy_sd) {
4054+ AA_ERROR("%s: Failed to allocate subdomain\n",
4055+ __FUNCTION__);
4056+ error = -ENOMEM;
4057+ goto cleanup;
4058+ }
4059+ }
4060+
4061+ spin_lock_irqsave(&sd_lock, flags);
4062+
4063+ sd = AA_SUBDOMAIN(current->security);
4064+ if (lazy_sd) {
4065+ if (sd) {
4066+ /* raced by setprofile - created sd */
4067+ free_subdomain(lazy_sd);
4068+ lazy_sd = NULL;
4069+ } else {
4070+ /* Not rcu used to get the write barrier
4071+ * correct */
4072+ rcu_assign_pointer(current->security, lazy_sd);
4073+ sd = lazy_sd;
4074+ }
4075+ }
4076+
4077+ /* Determine if profile we found earlier is stale.
4078+ * If so, reobtain it. N.B stale flag should never be
4079+ * set on null_complain profile.
4080+ */
4081+ if (newprofile && unlikely(newprofile->isstale)) {
4082+ WARN_ON(newprofile == null_complain_profile);
4083+
4084+ /* drop refcnt obtained from earlier get_aaprofile */
4085+ put_aaprofile(newprofile);
4086+
4087+ newprofile = aa_profilelist_find(filename);
4088+
4089+ if (!newprofile) {
4090+ /* Race, profile was removed, not replaced.
4091+ * Redo with error checking
4092+ */
4093+ spin_unlock_irqrestore(&sd_lock, flags);
4094+ goto find_profile;
4095+ }
4096+ }
4097+
4098+ /* Handle confined exec.
4099+ * Can be at this point for the following reasons:
4100+ * 1. unconfined switching to confined
4101+ * 2. confined switching to different confinement
4102+ * 3. confined switching to unconfined
4103+ *
4104+ * Cases 2 and 3 are marked as requiring secure exec
4105+ * (unless policy specified "unsafe exec")
4106+ */
4107+ if (__aa_is_confined(sd) && !unsafe_exec) {
4108+ unsigned long bprm_flags;
4109+
4110+ bprm_flags = AA_SECURE_EXEC_NEEDED;
4111+ bprm->security = (void*)
4112+ ((unsigned long)bprm->security | bprm_flags);
4113+ }
4114+
4115+ aa_switch(sd, newprofile);
4116+ put_aaprofile(newprofile);
4117+
4118+ if (complain && newprofile == null_complain_profile)
4119+ LOG_HINT(newprofile, GFP_ATOMIC, HINT_CHGPROF,
4120+ "pid=%d\n",
4121+ current->pid);
4122+
4123+ spin_unlock_irqrestore(&sd_lock, flags);
4124+ }
4125+
4126+cleanup:
4127+ aa_put_name(filename);
4128+
4129+ put_aaprofile(active);
4130+
4131+out:
4132+ return error;
4133+}
4134+
4135+/**
4136+ * aa_release - release the task's subdomain
4137+ * @p: task being released
4138+ *
4139+ * This is called after a task has exited and the parent has reaped it.
4140+ * @p->security blob is freed.
4141+ *
4142+ * This is the one case where we don't need to hold the sd_lock before
4143+ * removing a profile from a subdomain. Once the subdomain has been
4144+ * removed from the subdomain_list, we are no longer racing other writers.
4145+ * There may still be other readers so we must still use aa_switch
4146+ * to put the subdomain's reference safely.
4147+ */
4148+void aa_release(struct task_struct *p)
4149+{
4150+ struct subdomain *sd = AA_SUBDOMAIN(p->security);
4151+ if (sd) {
4152+ p->security = NULL;
4153+
4154+ aa_subdomainlist_remove(sd);
4155+ aa_switch_unconfined(sd);
4156+
4157+ kfree(sd);
4158+ }
4159+}
4160+
4161+/*****************************
4162+ * global subprofile functions
4163+ ****************************/
4164+
4165+/**
4166+ * do_change_hat - actually switch hats
4167+ * @hat_name: name of hat to swtich to
4168+ * @sd: current subdomain
4169+ *
4170+ * Switch to a new hat. Return %0 on success, error otherwise.
4171+ */
4172+static inline int do_change_hat(const char *hat_name, struct subdomain *sd)
4173+{
4174+ struct aaprofile *sub;
4175+ int error = 0;
4176+
4177+ sub = __aa_find_profile(hat_name, &BASE_PROFILE(sd->active)->sub);
4178+
4179+ if (sub) {
4180+ /* change hat */
4181+ aa_switch(sd, sub);
4182+ put_aaprofile(sub);
4183+ } else {
4184+ /* There is no such subprofile change to a NULL profile.
4185+ * The NULL profile grants no file access.
4186+ *
4187+ * This feature is used by changehat_apache.
4188+ *
4189+ * N.B from the null-profile the task can still changehat back
4190+ * out to the parent profile (assuming magic != NULL)
4191+ */
4192+ if (SUBDOMAIN_COMPLAIN(sd)) {
4193+ LOG_HINT(sd->active, GFP_ATOMIC, HINT_UNKNOWN_HAT,
4194+ "%s pid=%d "
4195+ "profile=%s active=%s\n",
4196+ hat_name,
4197+ current->pid,
4198+ BASE_PROFILE(sd->active)->name,
4199+ sd->active->name);
4200+ } else {
4201+ AA_DEBUG("%s: Unknown hatname '%s'. "
4202+ "Changing to NULL profile "
4203+ "(%s(%d) profile %s active %s)\n",
4204+ __FUNCTION__,
4205+ hat_name,
4206+ current->comm, current->pid,
4207+ BASE_PROFILE(sd->active)->name,
4208+ sd->active->name);
4209+ error = -EACCES;
4210+ }
4211+ aa_switch(sd, sd->active->null_profile);
4212+ }
4213+
4214+ return error;
4215+}
4216+
4217+/**
4218+ * aa_change_hat - change hat to/from subprofile
4219+ * @hat_name: specifies hat to change to
4220+ * @hat_magic: token to validate hat change
4221+ *
4222+ * Change to new @hat_name when current hat is top level profile, and store
4223+ * the @hat_magic in the current subdomain. If the new @hat_name is
4224+ * %NULL, and the @hat_magic matches that stored in the current subdomain
4225+ * return to original top level profile. Returns %0 on success, error
4226+ * otherwise.
4227+ */
4228+int aa_change_hat(const char *hat_name, u32 hat_magic)
4229+{
4230+ struct subdomain *sd = AA_SUBDOMAIN(current->security);
4231+ int error = 0;
4232+
4233+ AA_DEBUG("%s: %p, 0x%x (pid %d)\n",
4234+ __FUNCTION__,
4235+ hat_name, hat_magic,
4236+ current->pid);
4237+
4238+ /* Dump out above debugging in WARN mode if we are in AUDIT mode */
4239+ if (SUBDOMAIN_AUDIT(sd)) {
4240+ AA_WARN("%s: %s, 0x%x (pid %d)\n",
4241+ __FUNCTION__, hat_name ? hat_name : "NULL",
4242+ hat_magic, current->pid);
4243+ }
4244+
4245+ /* check to see if an unconfined process is doing a changehat. */
4246+ if (!__aa_is_confined(sd)) {
4247+ error = -EPERM;
4248+ goto out;
4249+ }
4250+
4251+ /* check to see if the confined process has any hats. */
4252+ if (list_empty(&BASE_PROFILE(sd->active)->sub) &&
4253+ !PROFILE_COMPLAIN(sd->active)) {
4254+ error = -ECHILD;
4255+ goto out;
4256+ }
4257+
4258+ /* Check whether current domain is parent
4259+ * or one of the sibling children
4260+ */
4261+ if (!IN_SUBPROFILE(sd->active)) {
4262+ /*
4263+ * parent
4264+ */
4265+ if (hat_name) {
4266+ AA_DEBUG("%s: switching to %s, 0x%x\n",
4267+ __FUNCTION__,
4268+ hat_name,
4269+ hat_magic);
4270+
4271+ /*
4272+ * N.B hat_magic == 0 has a special meaning
4273+ * this indicates that the task may never changehat
4274+ * back to it's parent, it will stay in this subhat
4275+ * (or null-profile, if the hat doesn't exist) until
4276+ * the task terminates
4277+ */
4278+ sd->hat_magic = hat_magic;
4279+ error = do_change_hat(hat_name, sd);
4280+ } else {
4281+ /* Got here via changehat(NULL, magic)
4282+ *
4283+ * We used to simply update the magic cookie.
4284+ * That's an odd behaviour, so just do nothing.
4285+ */
4286+ }
4287+ } else {
4288+ /*
4289+ * child -- check to make sure magic is same as what was
4290+ * passed when we switched into this profile,
4291+ * Handle special casing of NULL magic which confines task
4292+ * to subprofile and prohibits further changehats
4293+ */
4294+ if (hat_magic == sd->hat_magic && sd->hat_magic) {
4295+ if (!hat_name) {
4296+ /*
4297+ * Got here via changehat(NULL, magic)
4298+ * Return from subprofile, back to parent
4299+ */
4300+ aa_switch(sd, sd->active->parent);
4301+
4302+ /* Reset hat_magic to zero.
4303+ * New value will be passed on next changehat
4304+ */
4305+ sd->hat_magic = 0;
4306+ } else {
4307+ /* change to another (sibling) profile */
4308+ error = do_change_hat(hat_name, sd);
4309+ }
4310+ } else if (sd->hat_magic) {
4311+ AA_ERROR("KILLING process %s(%d) "
4312+ "Invalid change_hat() magic# 0x%x "
4313+ "(hatname %s profile %s active %s)\n",
4314+ current->comm, current->pid,
4315+ hat_magic,
4316+ hat_name ? hat_name : "NULL",
4317+ BASE_PROFILE(sd->active)->name,
4318+ sd->active->name);
4319+
4320+ /* terminate current process */
4321+ (void)send_sig_info(SIGKILL, NULL, current);
4322+ } else { /* sd->hat_magic == NULL */
4323+ AA_ERROR("KILLING process %s(%d) "
4324+ "Task was confined to current subprofile "
4325+ "(profile %s active %s)\n",
4326+ current->comm, current->pid,
4327+ BASE_PROFILE(sd->active)->name,
4328+ sd->active->name);
4329+
4330+ /* terminate current process */
4331+ (void)send_sig_info(SIGKILL, NULL, current);
4332+ }
4333+
4334+ }
4335+
4336+out:
4337+ return error;
4338+}
4339Index: b/security/apparmor/match/Kbuild
4340===================================================================
4341--- /dev/null
4342+++ b/security/apparmor/match/Kbuild
4343@@ -0,0 +1,6 @@
4344+# Makefile for AppArmor aamatch submodule
4345+#
4346+
4347+obj-$(CONFIG_SECURITY_APPARMOR) += aamatch_pcre.o
4348+
4349+aamatch_pcre-y := match_pcre.o pcre_exec.o
4350Index: b/security/apparmor/match/Makefile
4351===================================================================
4352--- /dev/null
4353+++ b/security/apparmor/match/Makefile
4354@@ -0,0 +1,5 @@
4355+# Makefile for AppArmor aamatch submodule
4356+#
4357+obj-$(CONFIG_SECURITY_APPARMOR) += aamatch_pcre.o
4358+
4359+aamatch_pcre-y := match_pcre.o pcre_exec.o
4360Index: b/security/apparmor/match/match.h
4361===================================================================
4362--- /dev/null
4363+++ b/security/apparmor/match/match.h
4364@@ -0,0 +1,132 @@
4365+/*
4366+ * Copyright (C) 2002-2005 Novell/SUSE
4367+ *
4368+ * This program is free software; you can redistribute it and/or
4369+ * modify it under the terms of the GNU General Public License as
4370+ * published by the Free Software Foundation, version 2 of the
4371+ * License.
4372+ *
4373+ * AppArmor submodule (match) prototypes
4374+ */
4375+
4376+#ifndef __MATCH_H
4377+#define __MATCH_H
4378+
4379+#include "../module_interface.h"
4380+#include "../apparmor.h"
4381+
4382+/* The following functions implement an interface used by the primary
4383+ * AppArmor module to perform name matching (n.b. "AppArmor" was previously
4384+ * called "SubDomain").
4385+
4386+ * aamatch_alloc
4387+ * aamatch_free
4388+ * aamatch_features
4389+ * aamatch_serialize
4390+ * aamatch_match
4391+ *
4392+ * The intent is for the primary module to export (via virtual fs entries)
4393+ * the features provided by the submodule (aamatch_features) so that the
4394+ * parser may only load policy that can be supported.
4395+ *
4396+ * The primary module will call aamatch_serialize to allow the submodule
4397+ * to consume submodule specific data from parser data stream and will call
4398+ * aamatch_match to determine if a pathname matches an aa_entry.
4399+ */
4400+
4401+typedef int (*aamatch_serializecb)
4402+ (struct aa_ext *, enum aa_code, void *, const char *);
4403+
4404+/**
4405+ * aamatch_alloc: allocate extradata (if necessary)
4406+ * @type: type of entry being allocated
4407+ * Return value: NULL indicates no data was allocated (ERR_PTR(x) on error)
4408+ */
4409+extern void* aamatch_alloc(enum entry_match_type type);
4410+
4411+/**
4412+ * aamatch_free: release data allocated by aamatch_alloc
4413+ * @entry_extradata: data previously allocated by aamatch_alloc
4414+ */
4415+extern void aamatch_free(void *entry_extradata);
4416+
4417+/**
4418+ * aamatch_features: return match types supported
4419+ * Return value: space seperated string (of types supported - use type=value
4420+ * to indicate variants of a type)
4421+ */
4422+extern const char* aamatch_features(void);
4423+
4424+/**
4425+ * aamatch_serialize: serialize extradata
4426+ * @entry_extradata: data previously allocated by aamatch_alloc
4427+ * @e: input stream
4428+ * @cb: callback fn (consume incoming data stream)
4429+ * Return value: 0 success, -ve error
4430+ */
4431+extern int aamatch_serialize(void *entry_extradata, struct aa_ext *e,
4432+ aamatch_serializecb cb);
4433+
4434+/**
4435+ * aamatch_match: determine if pathname matches entry
4436+ * @pathname: pathname to verify
4437+ * @entry_name: entry name
4438+ * @type: type of entry
4439+ * @entry_extradata: data previously allocated by aamatch_alloc
4440+ * Return value: 1 match, 0 othersise
4441+ */
4442+extern unsigned int aamatch_match(const char *pathname, const char *entry_name,
4443+ enum entry_match_type type,
4444+ void *entry_extradata);
4445+
4446+
4447+/**
4448+ * sd_getmatch_type - return string representation of entry_match_type
4449+ * @type: entry match type
4450+ */
4451+static inline const char *sd_getmatch_type(enum entry_match_type type)
4452+{
4453+ const char *names[] = {
4454+ "aa_entry_literal",
4455+ "aa_entry_tailglob",
4456+ "aa_entry_pattern",
4457+ "aa_entry_invalid"
4458+ };
4459+
4460+ if (type >= aa_entry_invalid) {
4461+ type = aa_entry_invalid;
4462+ }
4463+
4464+ return names[type];
4465+}
4466+
4467+/**
4468+ * aamatch_match_common - helper function to check if a pathname matches
4469+ * a literal/tailglob
4470+ * @path: path requested to search for
4471+ * @entry_name: name from aa_entry
4472+ * @type: type of entry
4473+ */
4474+static inline int aamatch_match_common(const char *path,
4475+ const char *entry_name,
4476+ enum entry_match_type type)
4477+{
4478+ int retval;
4479+
4480+ /* literal, no pattern matching characters */
4481+ if (type == aa_entry_literal) {
4482+ retval = (strcmp(entry_name, path) == 0);
4483+ /* trailing ** glob pattern */
4484+ } else if (type == aa_entry_tailglob) {
4485+ retval = (strncmp(entry_name, path,
4486+ strlen(entry_name) - 2) == 0);
4487+ } else {
4488+ AA_WARN("%s: Invalid entry_match_type %d\n",
4489+ __FUNCTION__, type);
4490+ retval = 0;
4491+ }
4492+
4493+ return retval;
4494+}
4495+
4496+#endif /* __MATCH_H */
4497Index: b/security/apparmor/match/match_default.c
4498===================================================================
4499--- /dev/null
4500+++ b/security/apparmor/match/match_default.c
4501@@ -0,0 +1,57 @@
4502+/*
4503+ * Copyright (C) 2002-2005 Novell/SUSE
4504+ *
4505+ * This program is free software; you can redistribute it and/or
4506+ * modify it under the terms of the GNU General Public License as
4507+ * published by the Free Software Foundation, version 2 of the
4508+ * License.
4509+ *
4510+ * http://forge.novell.com/modules/xfmod/project/?apparmor
4511+ *
4512+ * AppArmor default match submodule (literal and tailglob)
4513+ */
4514+
4515+#include <linux/module.h>
4516+#include "match.h"
4517+
4518+static const char *features="literal tailglob";
4519+
4520+void* aamatch_alloc(enum entry_match_type type)
4521+{
4522+ return NULL;
4523+}
4524+
4525+void aamatch_free(void *ptr)
4526+{
4527+}
4528+
4529+const char *aamatch_features(void)
4530+{
4531+ return features;
4532+}
4533+
4534+int aamatch_serialize(void *entry_extradata, struct aa_ext *e,
4535+ aamatch_serializecb cb)
4536+{
4537+ return 0;
4538+}
4539+
4540+unsigned int aamatch_match(const char *pathname, const char *entry_name,
4541+ enum entry_match_type type, void *entry_extradata)
4542+{
4543+ int ret;
4544+
4545+ ret = aamatch_match_common(pathname, entry_name, type);
4546+
4547+ return ret;
4548+}
4549+
4550+EXPORT_SYMBOL_GPL(aamatch_alloc);
4551+EXPORT_SYMBOL_GPL(aamatch_free);
4552+EXPORT_SYMBOL_GPL(aamatch_features);
4553+EXPORT_SYMBOL_GPL(aamatch_serialize);
4554+EXPORT_SYMBOL_GPL(aamatch_match);
4555+
4556+MODULE_DESCRIPTION("AppArmor match module (aamatch) [default]");
4557+MODULE_AUTHOR("Tony Jones <tonyj@suse.de>");
4558+MODULE_LICENSE("GPL");
4559Index: b/security/apparmor/match/match_pcre.c
4560===================================================================
4561--- /dev/null
4562+++ b/security/apparmor/match/match_pcre.c
4563@@ -0,0 +1,169 @@
4564+/*
4565+ * Copyright (C) 2002-2005 Novell/SUSE
4566+ *
4567+ * This program is free software; you can redistribute it and/or
4568+ * modify it under the terms of the GNU General Public License as
4569+ * published by the Free Software Foundation, version 2 of the
4570+ * License.
4571+ *
4572+ * http://forge.novell.com/modules/xfmod/project/?apparmor
4573+ *
4574+ * AppArmor aamatch submodule (w/ pattern expansion).
4575+ *
4576+ * This module makes use of a slightly modified version of the PCRE
4577+ * library developed by Philip Hazel <ph10@cam.ac.uk>. See the files
4578+ * pcre_* in this directory.
4579+ */
4580+
4581+#include <linux/module.h>
4582+#include "match.h"
4583+#include "pcre_exec.h"
4584+#include "pcre_tables.h"
4585+
4586+static const char *features="literal tailglob pattern=pcre";
4587+
4588+struct aamatch_entry
4589+{
4590+ char *pattern;
4591+ pcre *compiled;
4592+};
4593+
4594+void* aamatch_alloc(enum entry_match_type entry_type)
4595+{
4596+void *ptr=NULL;
4597+
4598+ if (entry_type == aa_entry_pattern) {
4599+ ptr = kmalloc(sizeof(struct aamatch_entry), GFP_KERNEL);
4600+ if (ptr)
4601+ memset(ptr, 0, sizeof(struct aamatch_entry));
4602+ else
4603+ ptr=ERR_PTR(-ENOMEM);
4604+ } else if (entry_type != aa_entry_literal &&
4605+ entry_type != aa_entry_tailglob) {
4606+ ptr = ERR_PTR(-EINVAL);
4607+ }
4608+
4609+ return ptr;
4610+}
4611+
4612+void aamatch_free(void *ptr)
4613+{
4614+ if (ptr) {
4615+ struct aamatch_entry *ed = (struct aamatch_entry *) ptr;
4616+ kfree(ed->pattern);
4617+ kfree(ed->compiled); /* allocated by AA_READ_X */
4618+ }
4619+ kfree(ptr);
4620+}
4621+
4622+const char *aamatch_features(void)
4623+{
4624+ return features;
4625+}
4626+
4627+int aamatch_serialize(void *entry_extradata, struct aa_ext *e,
4628+ aamatch_serializecb cb)
4629+{
4630+#define AA_READ_X(E, C, D, N) \
4631+ do { \
4632+ if (!cb((E), (C), (D), (N))) { \
4633+ error = -EINVAL; \
4634+ goto done; \
4635+ }\
4636+ } while (0)
4637+
4638+ int error = 0;
4639+ u32 size, magic, opts;
4640+ u8 t_char;
4641+ struct aamatch_entry *ed = (struct aamatch_entry *) entry_extradata;
4642+
4643+ if (ed == NULL)
4644+ goto done;
4645+
4646+ AA_READ_X(e, AA_DYN_STRING, &ed->pattern, NULL);
4647+
4648+ /* size determines the real size of the pcre struct,
4649+ it is size_t - sizeof(pcre) on user side.
4650+ uschar must be the same in user and kernel space */
4651+ /* check that we are processing the correct structure */
4652+ AA_READ_X(e, AA_STRUCT, NULL, "pcre");
4653+ AA_READ_X(e, AA_U32, &size, NULL);
4654+ AA_READ_X(e, AA_U32, &magic, NULL);
4655+
4656+ /* the allocation of pcre is delayed because it depends on the size
4657+ * of the pattern */
4658+ ed->compiled = (pcre *) kmalloc(size + sizeof(pcre), GFP_KERNEL);
4659+ if (!ed->compiled) {
4660+ error = -ENOMEM;
4661+ goto done;
4662+ }
4663+
4664+ memset(ed->compiled, 0, size + sizeof(pcre));
4665+ ed->compiled->magic_number = magic;
4666+ ed->compiled->size = size + sizeof(pcre);
4667+
4668+ AA_READ_X(e, AA_U32, &opts, NULL);
4669+ ed->compiled->options = opts;
4670+ AA_READ_X(e, AA_U16, &ed->compiled->top_bracket, NULL);
4671+ AA_READ_X(e, AA_U16, &ed->compiled->top_backref, NULL);
4672+ AA_READ_X(e, AA_U8, &t_char, NULL);
4673+ ed->compiled->first_char = t_char;
4674+ AA_READ_X(e, AA_U8, &t_char, NULL);
4675+ ed->compiled->req_char = t_char;
4676+ AA_READ_X(e, AA_U8, &t_char, NULL);
4677+ ed->compiled->code[0] = t_char;
4678+
4679+ AA_READ_X(e, AA_STATIC_BLOB, &ed->compiled->code[1], NULL);
4680+
4681+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
4682+
4683+ /* stitch in pcre patterns, it was NULLed out by parser
4684+ * pcre_default_tables defined in pcre_tables.h */
4685+ ed->compiled->tables = pcre_default_tables;
4686+
4687+done:
4688+ if (error != 0 && ed) {
4689+ kfree(ed->pattern); /* allocated by AA_READ_X */
4690+ kfree(ed->compiled);
4691+ ed->pattern = NULL;
4692+ ed->compiled = NULL;
4693+ }
4694+
4695+ return error;
4696+}
4697+
4698+unsigned int aamatch_match(const char *pathname, const char *entry_name,
4699+ enum entry_match_type entry_type, void *entry_extradata)
4700+{
4701+ int ret;
4702+
4703+ if (entry_type == aa_entry_pattern) {
4704+ int pcreret;
4705+ struct aamatch_entry *ed =
4706+ (struct aamatch_entry *) entry_extradata;
4707+
4708+ pcreret = pcre_exec(ed->compiled, NULL,
4709+ pathname, strlen(pathname),
4710+ 0, 0, NULL, 0);
4711+
4712+ ret = (pcreret >= 0);
4713+
4714+ // XXX - this needs access to subdomain_debug, hmmm
4715+ //AA_DEBUG("%s(%d): %s %s %d\n", __FUNCTION__,
4716+ // ret, pathname, ed->pattern, pcreret);
4717+ } else {
4718+ ret = aamatch_match_common(pathname, entry_name, entry_type);
4719+ }
4720+
4721+ return ret;
4722+}
4723+
4724+EXPORT_SYMBOL_GPL(aamatch_alloc);
4725+EXPORT_SYMBOL_GPL(aamatch_free);
4726+EXPORT_SYMBOL_GPL(aamatch_features);
4727+EXPORT_SYMBOL_GPL(aamatch_serialize);
4728+EXPORT_SYMBOL_GPL(aamatch_match);
4729+
4730+MODULE_DESCRIPTION("AppArmor aa_match module [pcre]");
4731+MODULE_AUTHOR("Tony Jones <tonyj@suse.de>");
4732+MODULE_LICENSE("GPL");
4733Index: b/security/apparmor/match/pcre_exec.c
4734===================================================================
4735--- /dev/null
4736+++ b/security/apparmor/match/pcre_exec.c
4737@@ -0,0 +1,1945 @@
4738+/*
4739+ * This is a modified version of pcre.c containing only the code/data
4740+ * required to support pcre_exec()
4741+ */
4742+
4743+
4744+/*************************************************
4745+* Perl-Compatible Regular Expressions *
4746+*************************************************/
4747+
4748+/*
4749+This is a library of functions to support regular expressions whose syntax
4750+and semantics are as close as possible to those of the Perl 5 language. See
4751+the file Tech.Notes for some information on the internals.
4752+
4753+Written by: Philip Hazel <ph10@cam.ac.uk>
4754+
4755+ Copyright (c) 1997-2001 University of Cambridge
4756+
4757+-----------------------------------------------------------------------------
4758+Permission is granted to anyone to use this software for any purpose on any
4759+computer system, and to redistribute it freely, subject to the following
4760+restrictions:
4761+
4762+1. This software is distributed in the hope that it will be useful,
4763+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4764+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
4765+
4766+2. The origin of this software must not be misrepresented, either by
4767+ explicit claim or by omission.
4768+
4769+3. Altered versions must be plainly marked as such, and must not be
4770+ misrepresented as being the original software.
4771+
4772+4. If PCRE is embedded in any software that is released under the GNU
4773+ General Purpose Licence (GPL), then the terms of that licence shall
4774+ supersede any condition above with which it is incompatible.
4775+-----------------------------------------------------------------------------
4776+*/
4777+
4778+
4779+/* Define DEBUG to get debugging output on stdout. */
4780+
4781+/* #define DEBUG */
4782+
4783+/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
4784+inline, and there are *still* stupid compilers about that don't like indented
4785+pre-processor statements. I suppose it's only been 10 years... */
4786+
4787+#ifdef DEBUG
4788+#define DPRINTF(p) PCRE_PRINTF p
4789+#else
4790+#define DPRINTF(p) /*nothing*/
4791+#endif
4792+
4793+/* Include the internals header, which itself includes Standard C headers plus
4794+the external pcre header. */
4795+
4796+#include "pcre_exec.h"
4797+
4798+
4799+/* ---- CODE DELETED ---- */
4800+
4801+
4802+/* Min and max values for the common repeats; for the maxima, 0 => infinity */
4803+
4804+static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
4805+static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
4806+
4807+
4808+/* ---- CODE DELETED ---- */
4809+
4810+
4811+/* Structure for building a chain of data that actually lives on the
4812+ * stack, for holding the values of the subject pointer at the start of each
4813+ * subpattern, so as to detect when an empty string has been matched by a
4814+ * subpattern - to break infinite loops. */
4815+
4816+typedef struct eptrblock {
4817+ struct eptrblock *prev;
4818+ const uschar *saved_eptr;
4819+} eptrblock;
4820+
4821+/* Flag bits for the match() function */
4822+
4823+#define match_condassert 0x01 /* Called to check a condition assertion */
4824+#define match_isgroup 0x02 /* Set if start of bracketed group */
4825+
4826+
4827+/* ---- CODE DELETED ---- */
4828+
4829+
4830+/*************************************************
4831+ * * Global variables *
4832+ * *************************************************/
4833+
4834+/* PCRE is thread-clean and doesn't use any global variables in the normal
4835+ * sense. However, it calls memory allocation and free functions via the two
4836+ * indirections below, which are can be changed by the caller, but are shared
4837+ * between all threads. */
4838+
4839+#ifdef __KERNEL__
4840+static void *kern_malloc(size_t sz)
4841+{
4842+ return kmalloc(sz, GFP_KERNEL);
4843+}
4844+void *(*pcre_malloc)(size_t) = kern_malloc;
4845+void (*pcre_free)(const void *) = kfree;
4846+#else
4847+void *(*pcre_malloc)(size_t) = malloc;
4848+void (*pcre_free)(const void *) = free;
4849+#endif
4850+
4851+
4852+/*************************************************
4853+ * * Macros and tables for character handling *
4854+ * *************************************************/
4855+
4856+/* When UTF-8 encoding is being used, a character is no longer just a single
4857+ * byte. The macros for character handling generate simple sequences when used in
4858+ * byte-mode, and more complicated ones for UTF-8 characters. */
4859+
4860+#ifndef SUPPORT_UTF8
4861+#define GETCHARINC(c, eptr) c = *eptr++;
4862+#define GETCHARLEN(c, eptr, len) c = *eptr;
4863+#define BACKCHAR(eptr)
4864+#endif
4865+
4866+/* ---- CODE DELETED ---- */
4867+
4868+#ifdef DEBUG
4869+/*************************************************
4870+* Debugging function to print chars *
4871+*************************************************/
4872+
4873+/* Print a sequence of chars in printable format, stopping at the end of the
4874+subject if the requested.
4875+
4876+Arguments:
4877+ p points to characters
4878+ length number to print
4879+ is_subject TRUE if printing from within md->start_subject
4880+ md pointer to matching data block, if is_subject is TRUE
4881+
4882+Returns: nothing
4883+*/
4884+
4885+static void
4886+pchars(const uschar *p, int length, BOOL is_subject, match_data *md)
4887+{
4888+int c;
4889+if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
4890+while (length-- > 0)
4891+ if (isprint(c = *(p++))) PCRE_PRINTF("%c", c); else PCRE_PRINTF("\\x%02x", c);
4892+}
4893+#endif /* DEBUG */
4894+
4895+/* ---- CODE DELETED ---- */
4896+
4897+
4898+/*************************************************
4899+* Match a back-reference *
4900+*************************************************/
4901+
4902+/* If a back reference hasn't been set, the length that is passed is greater
4903+than the number of characters left in the string, so the match fails.
4904+
4905+Arguments:
4906+ offset index into the offset vector
4907+ eptr points into the subject
4908+ length length to be matched
4909+ md points to match data block
4910+ ims the ims flags
4911+
4912+Returns: TRUE if matched
4913+*/
4914+
4915+static BOOL
4916+match_ref(int offset, register const uschar *eptr, int length, match_data *md,
4917+ unsigned long int ims)
4918+{
4919+const uschar *p = md->start_subject + md->offset_vector[offset];
4920+
4921+#ifdef DEBUG
4922+if (eptr >= md->end_subject)
4923+ PCRE_PRINTF("matching subject <null>");
4924+else
4925+ {
4926+ PCRE_PRINTF("matching subject ");
4927+ pchars(eptr, length, TRUE, md);
4928+ }
4929+PCRE_PRINTF(" against backref ");
4930+pchars(p, length, FALSE, md);
4931+PCRE_PRINTF("\n");
4932+#endif
4933+
4934+/* Always fail if not enough characters left */
4935+
4936+if (length > md->end_subject - eptr) return FALSE;
4937+
4938+/* Separate the caselesss case for speed */
4939+
4940+if ((ims & PCRE_CASELESS) != 0)
4941+ {
4942+ while (length-- > 0)
4943+ if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE;
4944+ }
4945+else
4946+ { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
4947+
4948+return TRUE;
4949+}
4950+
4951+
4952+/*************************************************
4953+* Match from current position *
4954+*************************************************/
4955+
4956+/* On entry ecode points to the first opcode, and eptr to the first character
4957+in the subject string, while eptrb holds the value of eptr at the start of the
4958+last bracketed group - used for breaking infinite loops matching zero-length
4959+strings.
4960+
4961+Arguments:
4962+ eptr pointer in subject
4963+ ecode position in code
4964+ offset_top current top pointer
4965+ md pointer to "static" info for the match
4966+ ims current /i, /m, and /s options
4967+ eptrb pointer to chain of blocks containing eptr at start of
4968+ brackets - for testing for empty matches
4969+ flags can contain
4970+ match_condassert - this is an assertion condition
4971+ match_isgroup - this is the start of a bracketed group
4972+
4973+Returns: TRUE if matched
4974+*/
4975+
4976+static BOOL
4977+match(register const uschar *eptr, register const uschar *ecode,
4978+ int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,
4979+ int flags)
4980+{
4981+unsigned long int original_ims = ims; /* Save for resetting on ')' */
4982+eptrblock newptrb;
4983+
4984+/* At the start of a bracketed group, add the current subject pointer to the
4985+stack of such pointers, to be re-instated at the end of the group when we hit
4986+the closing ket. When match() is called in other circumstances, we don't add to
4987+the stack. */
4988+
4989+if ((flags & match_isgroup) != 0)
4990+ {
4991+ newptrb.prev = eptrb;
4992+ newptrb.saved_eptr = eptr;
4993+ eptrb = &newptrb;
4994+ }
4995+
4996+/* Now start processing the operations. */
4997+
4998+for (;;)
4999+ {
5000+ int op = (int)*ecode;
5001+ int min, max, ctype;
5002+ register int i;
5003+ register int c;
5004+ BOOL minimize = FALSE;
5005+
5006+ /* Opening capturing bracket. If there is space in the offset vector, save
5007+ the current subject position in the working slot at the top of the vector. We
5008+ mustn't change the current values of the data slot, because they may be set
5009+ from a previous iteration of this group, and be referred to by a reference
5010+ inside the group.
5011+
5012+ If the bracket fails to match, we need to restore this value and also the
5013+ values of the final offsets, in case they were set by a previous iteration of
5014+ the same bracket.
5015+
5016+ If there isn't enough space in the offset vector, treat this as if it were a
5017+ non-capturing bracket. Don't worry about setting the flag for the error case
5018+ here; that is handled in the code for KET. */
5019+
5020+ if (op > OP_BRA)
5021+ {
5022+ int offset;
5023+ int number = op - OP_BRA;
5024+
5025+ /* For extended extraction brackets (large number), we have to fish out the
5026+ number from a dummy opcode at the start. */
5027+
5028+ if (number > EXTRACT_BASIC_MAX) number = (ecode[4] << 8) | ecode[5];
5029+ offset = number << 1;
5030+
5031+#ifdef DEBUG
5032+ PCRE_PRINTF("start bracket %d subject=", number);
5033+ pchars(eptr, 16, TRUE, md);
5034+ PCRE_PRINTF("\n");
5035+#endif
5036+
5037+ if (offset < md->offset_max)
5038+ {
5039+ int save_offset1 = md->offset_vector[offset];
5040+ int save_offset2 = md->offset_vector[offset+1];
5041+ int save_offset3 = md->offset_vector[md->offset_end - number];
5042+
5043+ DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
5044+ md->offset_vector[md->offset_end - number] = eptr - md->start_subject;
5045+
5046+ do
5047+ {
5048+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup))
5049+ return TRUE;
5050+ ecode += (ecode[1] << 8) + ecode[2];
5051+ }
5052+ while (*ecode == OP_ALT);
5053+
5054+ DPRINTF(("bracket %d failed\n", number));
5055+
5056+ md->offset_vector[offset] = save_offset1;
5057+ md->offset_vector[offset+1] = save_offset2;
5058+ md->offset_vector[md->offset_end - number] = save_offset3;
5059+
5060+ return FALSE;
5061+ }
5062+
5063+ /* Insufficient room for saving captured contents */
5064+
5065+ else op = OP_BRA;
5066+ }
5067+
5068+ /* Other types of node can be handled by a switch */
5069+
5070+ switch(op)
5071+ {
5072+ case OP_BRA: /* Non-capturing bracket: optimized */
5073+ DPRINTF(("start bracket 0\n"));
5074+ do
5075+ {
5076+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup))
5077+ return TRUE;
5078+ ecode += (ecode[1] << 8) + ecode[2];
5079+ }
5080+ while (*ecode == OP_ALT);
5081+ DPRINTF(("bracket 0 failed\n"));
5082+ return FALSE;
5083+
5084+ /* Conditional group: compilation checked that there are no more than
5085+ two branches. If the condition is false, skipping the first branch takes us
5086+ past the end if there is only one branch, but that's OK because that is
5087+ exactly what going to the ket would do. */
5088+
5089+ case OP_COND:
5090+ if (ecode[3] == OP_CREF) /* Condition is extraction test */
5091+ {
5092+ int offset = (ecode[4] << 9) | (ecode[5] << 1); /* Doubled ref number */
5093+ return match(eptr,
5094+ ecode + ((offset < offset_top && md->offset_vector[offset] >= 0)?
5095+ 6 : 3 + (ecode[1] << 8) + ecode[2]),
5096+ offset_top, md, ims, eptrb, match_isgroup);
5097+ }
5098+
5099+ /* The condition is an assertion. Call match() to evaluate it - setting
5100+ the final argument TRUE causes it to stop at the end of an assertion. */
5101+
5102+ else
5103+ {
5104+ if (match(eptr, ecode+3, offset_top, md, ims, NULL,
5105+ match_condassert | match_isgroup))
5106+ {
5107+ ecode += 3 + (ecode[4] << 8) + ecode[5];
5108+ while (*ecode == OP_ALT) ecode += (ecode[1] << 8) + ecode[2];
5109+ }
5110+ else ecode += (ecode[1] << 8) + ecode[2];
5111+ return match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup);
5112+ }
5113+ /* Control never reaches here */
5114+
5115+ /* Skip over conditional reference or large extraction number data if
5116+ encountered. */
5117+
5118+ case OP_CREF:
5119+ case OP_BRANUMBER:
5120+ ecode += 3;
5121+ break;
5122+
5123+ /* End of the pattern. If PCRE_NOTEMPTY is set, fail if we have matched
5124+ an empty string - recursion will then try other alternatives, if any. */
5125+
5126+ case OP_END:
5127+ if (md->notempty && eptr == md->start_match) return FALSE;
5128+ md->end_match_ptr = eptr; /* Record where we ended */
5129+ md->end_offset_top = offset_top; /* and how many extracts were taken */
5130+ return TRUE;
5131+
5132+ /* Change option settings */
5133+
5134+ case OP_OPT:
5135+ ims = ecode[1];
5136+ ecode += 2;
5137+ DPRINTF(("ims set to %02lx\n", ims));
5138+ break;
5139+
5140+ /* Assertion brackets. Check the alternative branches in turn - the
5141+ matching won't pass the KET for an assertion. If any one branch matches,
5142+ the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
5143+ start of each branch to move the current point backwards, so the code at
5144+ this level is identical to the lookahead case. */
5145+
5146+ case OP_ASSERT:
5147+ case OP_ASSERTBACK:
5148+ do
5149+ {
5150+ if (match(eptr, ecode+3, offset_top, md, ims, NULL, match_isgroup)) break;
5151+ ecode += (ecode[1] << 8) + ecode[2];
5152+ }
5153+ while (*ecode == OP_ALT);
5154+ if (*ecode == OP_KET) return FALSE;
5155+
5156+ /* If checking an assertion for a condition, return TRUE. */
5157+
5158+ if ((flags & match_condassert) != 0) return TRUE;
5159+
5160+ /* Continue from after the assertion, updating the offsets high water
5161+ mark, since extracts may have been taken during the assertion. */
5162+
5163+ do ecode += (ecode[1] << 8) + ecode[2]; while (*ecode == OP_ALT);
5164+ ecode += 3;
5165+ offset_top = md->end_offset_top;
5166+ continue;
5167+
5168+ /* Negative assertion: all branches must fail to match */
5169+
5170+ case OP_ASSERT_NOT:
5171+ case OP_ASSERTBACK_NOT:
5172+ do
5173+ {
5174+ if (match(eptr, ecode+3, offset_top, md, ims, NULL, match_isgroup))
5175+ return FALSE;
5176+ ecode += (ecode[1] << 8) + ecode[2];
5177+ }
5178+ while (*ecode == OP_ALT);
5179+
5180+ if ((flags & match_condassert) != 0) return TRUE;
5181+
5182+ ecode += 3;
5183+ continue;
5184+
5185+ /* Move the subject pointer back. This occurs only at the start of
5186+ each branch of a lookbehind assertion. If we are too close to the start to
5187+ move back, this match function fails. When working with UTF-8 we move
5188+ back a number of characters, not bytes. */
5189+
5190+ case OP_REVERSE:
5191+#ifdef SUPPORT_UTF8
5192+ c = (ecode[1] << 8) + ecode[2];
5193+ for (i = 0; i < c; i++)
5194+ {
5195+ eptr--;
5196+ BACKCHAR(eptr)
5197+ }
5198+#else
5199+ eptr -= (ecode[1] << 8) + ecode[2];
5200+#endif
5201+
5202+ if (eptr < md->start_subject) return FALSE;
5203+ ecode += 3;
5204+ break;
5205+
5206+ /* Recursion matches the current regex, nested. If there are any capturing
5207+ brackets started but not finished, we have to save their starting points
5208+ and reinstate them after the recursion. However, we don't know how many
5209+ such there are (offset_top records the completed total) so we just have
5210+ to save all the potential data. There may be up to 99 such values, which
5211+ is a bit large to put on the stack, but using malloc for small numbers
5212+ seems expensive. As a compromise, the stack is used when there are fewer
5213+ than 16 values to store; otherwise malloc is used. A problem is what to do
5214+ if the malloc fails ... there is no way of returning to the top level with
5215+ an error. Save the top 15 values on the stack, and accept that the rest
5216+ may be wrong. */
5217+
5218+ case OP_RECURSE:
5219+ {
5220+ BOOL rc;
5221+ int *save;
5222+ int stacksave[15];
5223+
5224+ c = md->offset_max;
5225+
5226+ if (c < 16) save = stacksave; else
5227+ {
5228+ save = (int *)(pcre_malloc)((c+1) * sizeof(int));
5229+ if (save == NULL)
5230+ {
5231+ save = stacksave;
5232+ c = 15;
5233+ }
5234+ }
5235+
5236+ for (i = 1; i <= c; i++)
5237+ save[i] = md->offset_vector[md->offset_end - i];
5238+ rc = match(eptr, md->start_pattern, offset_top, md, ims, eptrb,
5239+ match_isgroup);
5240+ for (i = 1; i <= c; i++)
5241+ md->offset_vector[md->offset_end - i] = save[i];
5242+ if (save != stacksave) (pcre_free)(save);
5243+ if (!rc) return FALSE;
5244+
5245+ /* In case the recursion has set more capturing values, save the final
5246+ number, then move along the subject till after the recursive match,
5247+ and advance one byte in the pattern code. */
5248+
5249+ offset_top = md->end_offset_top;
5250+ eptr = md->end_match_ptr;
5251+ ecode++;
5252+ }
5253+ break;
5254+
5255+ /* "Once" brackets are like assertion brackets except that after a match,
5256+ the point in the subject string is not moved back. Thus there can never be
5257+ a move back into the brackets. Check the alternative branches in turn - the
5258+ matching won't pass the KET for this kind of subpattern. If any one branch
5259+ matches, we carry on as at the end of a normal bracket, leaving the subject
5260+ pointer. */
5261+
5262+ case OP_ONCE:
5263+ {
5264+ const uschar *prev = ecode;
5265+ const uschar *saved_eptr = eptr;
5266+
5267+ do
5268+ {
5269+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, match_isgroup))
5270+ break;
5271+ ecode += (ecode[1] << 8) + ecode[2];
5272+ }
5273+ while (*ecode == OP_ALT);
5274+
5275+ /* If hit the end of the group (which could be repeated), fail */
5276+
5277+ if (*ecode != OP_ONCE && *ecode != OP_ALT) return FALSE;
5278+
5279+ /* Continue as from after the assertion, updating the offsets high water
5280+ mark, since extracts may have been taken. */
5281+
5282+ do ecode += (ecode[1] << 8) + ecode[2]; while (*ecode == OP_ALT);
5283+
5284+ offset_top = md->end_offset_top;
5285+ eptr = md->end_match_ptr;
5286+
5287+ /* For a non-repeating ket, just continue at this level. This also
5288+ happens for a repeating ket if no characters were matched in the group.
5289+ This is the forcible breaking of infinite loops as implemented in Perl
5290+ 5.005. If there is an options reset, it will get obeyed in the normal
5291+ course of events. */
5292+
5293+ if (*ecode == OP_KET || eptr == saved_eptr)
5294+ {
5295+ ecode += 3;
5296+ break;
5297+ }
5298+
5299+ /* The repeating kets try the rest of the pattern or restart from the
5300+ preceding bracket, in the appropriate order. We need to reset any options
5301+ that changed within the bracket before re-running it, so check the next
5302+ opcode. */
5303+
5304+ if (ecode[3] == OP_OPT)
5305+ {
5306+ ims = (ims & ~PCRE_IMS) | ecode[4];
5307+ DPRINTF(("ims set to %02lx at group repeat\n", ims));
5308+ }
5309+
5310+ if (*ecode == OP_KETRMIN)
5311+ {
5312+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, 0) ||
5313+ match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup))
5314+ return TRUE;
5315+ }
5316+ else /* OP_KETRMAX */
5317+ {
5318+ if (match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup) ||
5319+ match(eptr, ecode+3, offset_top, md, ims, eptrb, 0)) return TRUE;
5320+ }
5321+ }
5322+ return FALSE;
5323+
5324+ /* An alternation is the end of a branch; scan along to find the end of the
5325+ bracketed group and go to there. */
5326+
5327+ case OP_ALT:
5328+ do ecode += (ecode[1] << 8) + ecode[2]; while (*ecode == OP_ALT);
5329+ break;
5330+
5331+ /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating
5332+ that it may occur zero times. It may repeat infinitely, or not at all -
5333+ i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper
5334+ repeat limits are compiled as a number of copies, with the optional ones
5335+ preceded by BRAZERO or BRAMINZERO. */
5336+
5337+ case OP_BRAZERO:
5338+ {
5339+ const uschar *next = ecode+1;
5340+ if (match(eptr, next, offset_top, md, ims, eptrb, match_isgroup))
5341+ return TRUE;
5342+ do next += (next[1] << 8) + next[2]; while (*next == OP_ALT);
5343+ ecode = next + 3;
5344+ }
5345+ break;
5346+
5347+ case OP_BRAMINZERO:
5348+ {
5349+ const uschar *next = ecode+1;
5350+ do next += (next[1] << 8) + next[2]; while (*next == OP_ALT);
5351+ if (match(eptr, next+3, offset_top, md, ims, eptrb, match_isgroup))
5352+ return TRUE;
5353+ ecode++;
5354+ }
5355+ break;
5356+
5357+ /* End of a group, repeated or non-repeating. If we are at the end of
5358+ an assertion "group", stop matching and return TRUE, but record the
5359+ current high water mark for use by positive assertions. Do this also
5360+ for the "once" (not-backup up) groups. */
5361+
5362+ case OP_KET:
5363+ case OP_KETRMIN:
5364+ case OP_KETRMAX:
5365+ {
5366+ const uschar *prev = ecode - (ecode[1] << 8) - ecode[2];
5367+ const uschar *saved_eptr = eptrb->saved_eptr;
5368+
5369+ eptrb = eptrb->prev; /* Back up the stack of bracket start pointers */
5370+
5371+ if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
5372+ *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
5373+ *prev == OP_ONCE)
5374+ {
5375+ md->end_match_ptr = eptr; /* For ONCE */
5376+ md->end_offset_top = offset_top;
5377+ return TRUE;
5378+ }
5379+
5380+ /* In all other cases except a conditional group we have to check the
5381+ group number back at the start and if necessary complete handling an
5382+ extraction by setting the offsets and bumping the high water mark. */
5383+
5384+ if (*prev != OP_COND)
5385+ {
5386+ int offset;
5387+ int number = *prev - OP_BRA;
5388+
5389+ /* For extended extraction brackets (large number), we have to fish out
5390+ the number from a dummy opcode at the start. */
5391+
5392+ if (number > EXTRACT_BASIC_MAX) number = (prev[4] << 8) | prev[5];
5393+ offset = number << 1;
5394+
5395+#ifdef DEBUG
5396+ PCRE_PRINTF("end bracket %d", number);
5397+ PCRE_PRINTF("\n");
5398+#endif
5399+
5400+ if (number > 0)
5401+ {
5402+ if (offset >= md->offset_max) md->offset_overflow = TRUE; else
5403+ {
5404+ md->offset_vector[offset] =
5405+ md->offset_vector[md->offset_end - number];
5406+ md->offset_vector[offset+1] = eptr - md->start_subject;
5407+ if (offset_top <= offset) offset_top = offset + 2;
5408+ }
5409+ }
5410+ }
5411+
5412+ /* Reset the value of the ims flags, in case they got changed during
5413+ the group. */
5414+
5415+ ims = original_ims;
5416+ DPRINTF(("ims reset to %02lx\n", ims));
5417+
5418+ /* For a non-repeating ket, just continue at this level. This also
5419+ happens for a repeating ket if no characters were matched in the group.
5420+ This is the forcible breaking of infinite loops as implemented in Perl
5421+ 5.005. If there is an options reset, it will get obeyed in the normal
5422+ course of events. */
5423+
5424+ if (*ecode == OP_KET || eptr == saved_eptr)
5425+ {
5426+ ecode += 3;
5427+ break;
5428+ }
5429+
5430+ /* The repeating kets try the rest of the pattern or restart from the
5431+ preceding bracket, in the appropriate order. */
5432+
5433+ if (*ecode == OP_KETRMIN)
5434+ {
5435+ if (match(eptr, ecode+3, offset_top, md, ims, eptrb, 0) ||
5436+ match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup))
5437+ return TRUE;
5438+ }
5439+ else /* OP_KETRMAX */
5440+ {
5441+ if (match(eptr, prev, offset_top, md, ims, eptrb, match_isgroup) ||
5442+ match(eptr, ecode+3, offset_top, md, ims, eptrb, 0)) return TRUE;
5443+ }
5444+ }
5445+ return FALSE;
5446+
5447+ /* Start of subject unless notbol, or after internal newline if multiline */
5448+
5449+ case OP_CIRC:
5450+ if (md->notbol && eptr == md->start_subject) return FALSE;
5451+ if ((ims & PCRE_MULTILINE) != 0)
5452+ {
5453+ if (eptr != md->start_subject && eptr[-1] != NEWLINE) return FALSE;
5454+ ecode++;
5455+ break;
5456+ }
5457+ /* ... else fall through */
5458+
5459+ /* Start of subject assertion */
5460+
5461+ case OP_SOD:
5462+ if (eptr != md->start_subject) return FALSE;
5463+ ecode++;
5464+ break;
5465+
5466+ /* Assert before internal newline if multiline, or before a terminating
5467+ newline unless endonly is set, else end of subject unless noteol is set. */
5468+
5469+ case OP_DOLL:
5470+ if ((ims & PCRE_MULTILINE) != 0)
5471+ {
5472+ if (eptr < md->end_subject) { if (*eptr != NEWLINE) return FALSE; }
5473+ else { if (md->noteol) return FALSE; }
5474+ ecode++;
5475+ break;
5476+ }
5477+ else
5478+ {
5479+ if (md->noteol) return FALSE;
5480+ if (!md->endonly)
5481+ {
5482+ if (eptr < md->end_subject - 1 ||
5483+ (eptr == md->end_subject - 1 && *eptr != NEWLINE)) return FALSE;
5484+
5485+ ecode++;
5486+ break;
5487+ }
5488+ }
5489+ /* ... else fall through */
5490+
5491+ /* End of subject assertion (\z) */
5492+
5493+ case OP_EOD:
5494+ if (eptr < md->end_subject) return FALSE;
5495+ ecode++;
5496+ break;
5497+
5498+ /* End of subject or ending \n assertion (\Z) */
5499+
5500+ case OP_EODN:
5501+ if (eptr < md->end_subject - 1 ||
5502+ (eptr == md->end_subject - 1 && *eptr != NEWLINE)) return FALSE;
5503+ ecode++;
5504+ break;
5505+
5506+ /* Word boundary assertions */
5507+
5508+ case OP_NOT_WORD_BOUNDARY:
5509+ case OP_WORD_BOUNDARY:
5510+ {
5511+ BOOL prev_is_word = (eptr != md->start_subject) &&
5512+ ((md->ctypes[eptr[-1]] & ctype_word) != 0);
5513+ BOOL cur_is_word = (eptr < md->end_subject) &&
5514+ ((md->ctypes[*eptr] & ctype_word) != 0);
5515+ if ((*ecode++ == OP_WORD_BOUNDARY)?
5516+ cur_is_word == prev_is_word : cur_is_word != prev_is_word)
5517+ return FALSE;
5518+ }
5519+ break;
5520+
5521+ /* Match a single character type; inline for speed */
5522+
5523+ case OP_ANY:
5524+ if ((ims & PCRE_DOTALL) == 0 && eptr < md->end_subject && *eptr == NEWLINE)
5525+ return FALSE;
5526+ if (eptr++ >= md->end_subject) return FALSE;
5527+#ifdef SUPPORT_UTF8
5528+ if (md->utf8)
5529+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
5530+#endif
5531+ ecode++;
5532+ break;
5533+
5534+ case OP_NOT_DIGIT:
5535+ if (eptr >= md->end_subject ||
5536+ (md->ctypes[*eptr++] & ctype_digit) != 0)
5537+ return FALSE;
5538+ ecode++;
5539+ break;
5540+
5541+ case OP_DIGIT:
5542+ if (eptr >= md->end_subject ||
5543+ (md->ctypes[*eptr++] & ctype_digit) == 0)
5544+ return FALSE;
5545+ ecode++;
5546+ break;
5547+
5548+ case OP_NOT_WHITESPACE:
5549+ if (eptr >= md->end_subject ||
5550+ (md->ctypes[*eptr++] & ctype_space) != 0)
5551+ return FALSE;
5552+ ecode++;
5553+ break;
5554+
5555+ case OP_WHITESPACE:
5556+ if (eptr >= md->end_subject ||
5557+ (md->ctypes[*eptr++] & ctype_space) == 0)
5558+ return FALSE;
5559+ ecode++;
5560+ break;
5561+
5562+ case OP_NOT_WORDCHAR:
5563+ if (eptr >= md->end_subject ||
5564+ (md->ctypes[*eptr++] & ctype_word) != 0)
5565+ return FALSE;
5566+ ecode++;
5567+ break;
5568+
5569+ case OP_WORDCHAR:
5570+ if (eptr >= md->end_subject ||
5571+ (md->ctypes[*eptr++] & ctype_word) == 0)
5572+ return FALSE;
5573+ ecode++;
5574+ break;
5575+
5576+ /* Match a back reference, possibly repeatedly. Look past the end of the
5577+ item to see if there is repeat information following. The code is similar
5578+ to that for character classes, but repeated for efficiency. Then obey
5579+ similar code to character type repeats - written out again for speed.
5580+ However, if the referenced string is the empty string, always treat
5581+ it as matched, any number of times (otherwise there could be infinite
5582+ loops). */
5583+
5584+ case OP_REF:
5585+ {
5586+ int length;
5587+ int offset = (ecode[1] << 9) | (ecode[2] << 1); /* Doubled ref number */
5588+ ecode += 3; /* Advance past item */
5589+
5590+ /* If the reference is unset, set the length to be longer than the amount
5591+ of subject left; this ensures that every attempt at a match fails. We
5592+ can't just fail here, because of the possibility of quantifiers with zero
5593+ minima. */
5594+
5595+ length = (offset >= offset_top || md->offset_vector[offset] < 0)?
5596+ md->end_subject - eptr + 1 :
5597+ md->offset_vector[offset+1] - md->offset_vector[offset];
5598+
5599+ /* Set up for repetition, or handle the non-repeated case */
5600+
5601+ switch (*ecode)
5602+ {
5603+ case OP_CRSTAR:
5604+ case OP_CRMINSTAR:
5605+ case OP_CRPLUS:
5606+ case OP_CRMINPLUS:
5607+ case OP_CRQUERY:
5608+ case OP_CRMINQUERY:
5609+ c = *ecode++ - OP_CRSTAR;
5610+ minimize = (c & 1) != 0;
5611+ min = rep_min[c]; /* Pick up values from tables; */
5612+ max = rep_max[c]; /* zero for max => infinity */
5613+ if (max == 0) max = INT_MAX;
5614+ break;
5615+
5616+ case OP_CRRANGE:
5617+ case OP_CRMINRANGE:
5618+ minimize = (*ecode == OP_CRMINRANGE);
5619+ min = (ecode[1] << 8) + ecode[2];
5620+ max = (ecode[3] << 8) + ecode[4];
5621+ if (max == 0) max = INT_MAX;
5622+ ecode += 5;
5623+ break;
5624+
5625+ default: /* No repeat follows */
5626+ if (!match_ref(offset, eptr, length, md, ims)) return FALSE;
5627+ eptr += length;
5628+ continue; /* With the main loop */
5629+ }
5630+
5631+ /* If the length of the reference is zero, just continue with the
5632+ main loop. */
5633+
5634+ if (length == 0) continue;
5635+
5636+ /* First, ensure the minimum number of matches are present. We get back
5637+ the length of the reference string explicitly rather than passing the
5638+ address of eptr, so that eptr can be a register variable. */
5639+
5640+ for (i = 1; i <= min; i++)
5641+ {
5642+ if (!match_ref(offset, eptr, length, md, ims)) return FALSE;
5643+ eptr += length;
5644+ }
5645+
5646+ /* If min = max, continue at the same level without recursion.
5647+ They are not both allowed to be zero. */
5648+
5649+ if (min == max) continue;
5650+
5651+ /* If minimizing, keep trying and advancing the pointer */
5652+
5653+ if (minimize)
5654+ {
5655+ for (i = min;; i++)
5656+ {
5657+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
5658+ return TRUE;
5659+ if (i >= max || !match_ref(offset, eptr, length, md, ims))
5660+ return FALSE;
5661+ eptr += length;
5662+ }
5663+ /* Control never gets here */
5664+ }
5665+
5666+ /* If maximizing, find the longest string and work backwards */
5667+
5668+ else
5669+ {
5670+ const uschar *pp = eptr;
5671+ for (i = min; i < max; i++)
5672+ {
5673+ if (!match_ref(offset, eptr, length, md, ims)) break;
5674+ eptr += length;
5675+ }
5676+ while (eptr >= pp)
5677+ {
5678+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
5679+ return TRUE;
5680+ eptr -= length;
5681+ }
5682+ return FALSE;
5683+ }
5684+ }
5685+ /* Control never gets here */
5686+
5687+
5688+
5689+ /* Match a character class, possibly repeatedly. Look past the end of the
5690+ item to see if there is repeat information following. Then obey similar
5691+ code to character type repeats - written out again for speed. */
5692+
5693+ case OP_CLASS:
5694+ {
5695+ const uschar *data = ecode + 1; /* Save for matching */
5696+ ecode += 33; /* Advance past the item */
5697+
5698+ switch (*ecode)
5699+ {
5700+ case OP_CRSTAR:
5701+ case OP_CRMINSTAR:
5702+ case OP_CRPLUS:
5703+ case OP_CRMINPLUS:
5704+ case OP_CRQUERY:
5705+ case OP_CRMINQUERY:
5706+ c = *ecode++ - OP_CRSTAR;
5707+ minimize = (c & 1) != 0;
5708+ min = rep_min[c]; /* Pick up values from tables; */
5709+ max = rep_max[c]; /* zero for max => infinity */
5710+ if (max == 0) max = INT_MAX;
5711+ break;
5712+
5713+ case OP_CRRANGE:
5714+ case OP_CRMINRANGE:
5715+ minimize = (*ecode == OP_CRMINRANGE);
5716+ min = (ecode[1] << 8) + ecode[2];
5717+ max = (ecode[3] << 8) + ecode[4];
5718+ if (max == 0) max = INT_MAX;
5719+ ecode += 5;
5720+ break;
5721+
5722+ default: /* No repeat follows */
5723+ min = max = 1;
5724+ break;
5725+ }
5726+
5727+ /* First, ensure the minimum number of matches are present. */
5728+
5729+ for (i = 1; i <= min; i++)
5730+ {
5731+ if (eptr >= md->end_subject) return FALSE;
5732+ GETCHARINC(c, eptr) /* Get character; increment eptr */
5733+
5734+#ifdef SUPPORT_UTF8
5735+ /* We do not yet support class members > 255 */
5736+ if (c > 255) return FALSE;
5737+#endif
5738+
5739+ if ((data[c/8] & (1 << (c&7))) != 0) continue;
5740+ return FALSE;
5741+ }
5742+
5743+ /* If max == min we can continue with the main loop without the
5744+ need to recurse. */
5745+
5746+ if (min == max) continue;
5747+
5748+ /* If minimizing, keep testing the rest of the expression and advancing
5749+ the pointer while it matches the class. */
5750+
5751+ if (minimize)
5752+ {
5753+ for (i = min;; i++)
5754+ {
5755+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
5756+ return TRUE;
5757+ if (i >= max || eptr >= md->end_subject) return FALSE;
5758+ GETCHARINC(c, eptr) /* Get character; increment eptr */
5759+
5760+#ifdef SUPPORT_UTF8
5761+ /* We do not yet support class members > 255 */
5762+ if (c > 255) return FALSE;
5763+#endif
5764+ if ((data[c/8] & (1 << (c&7))) != 0) continue;
5765+ return FALSE;
5766+ }
5767+ /* Control never gets here */
5768+ }
5769+
5770+ /* If maximizing, find the longest possible run, then work backwards. */
5771+
5772+ else
5773+ {
5774+ const uschar *pp = eptr;
5775+ int len = 1;
5776+ for (i = min; i < max; i++)
5777+ {
5778+ if (eptr >= md->end_subject) break;
5779+ GETCHARLEN(c, eptr, len) /* Get character, set length if UTF-8 */
5780+
5781+#ifdef SUPPORT_UTF8
5782+ /* We do not yet support class members > 255 */
5783+ if (c > 255) break;
5784+#endif
5785+ if ((data[c/8] & (1 << (c&7))) == 0) break;
5786+ eptr += len;
5787+ }
5788+
5789+ while (eptr >= pp)
5790+ {
5791+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
5792+ return TRUE;
5793+
5794+#ifdef SUPPORT_UTF8
5795+ BACKCHAR(eptr)
5796+#endif
5797+ }
5798+ return FALSE;
5799+ }
5800+ }
5801+ /* Control never gets here */
5802+
5803+ /* Match a run of characters */
5804+
5805+ case OP_CHARS:
5806+ {
5807+ register int length = ecode[1];
5808+ ecode += 2;
5809+
5810+#ifdef DEBUG /* Sigh. Some compilers never learn. */
5811+ if (eptr >= md->end_subject)
5812+ PCRE_PRINTF("matching subject <null> against pattern ");
5813+ else
5814+ {
5815+ PCRE_PRINTF("matching subject ");
5816+ pchars(eptr, length, TRUE, md);
5817+ PCRE_PRINTF(" against pattern ");
5818+ }
5819+ pchars(ecode, length, FALSE, md);
5820+ PCRE_PRINTF("\n");
5821+#endif
5822+
5823+ if (length > md->end_subject - eptr) return FALSE;
5824+ if ((ims & PCRE_CASELESS) != 0)
5825+ {
5826+ while (length-- > 0)
5827+ if (md->lcc[*ecode++] != md->lcc[*eptr++])
5828+ return FALSE;
5829+ }
5830+ else
5831+ {
5832+ while (length-- > 0) if (*ecode++ != *eptr++) return FALSE;
5833+ }
5834+ }
5835+ break;
5836+
5837+ /* Match a single character repeatedly; different opcodes share code. */
5838+
5839+ case OP_EXACT:
5840+ min = max = (ecode[1] << 8) + ecode[2];
5841+ ecode += 3;
5842+ goto REPEATCHAR;
5843+
5844+ case OP_UPTO:
5845+ case OP_MINUPTO:
5846+ min = 0;
5847+ max = (ecode[1] << 8) + ecode[2];
5848+ minimize = *ecode == OP_MINUPTO;
5849+ ecode += 3;
5850+ goto REPEATCHAR;
5851+
5852+ case OP_STAR:
5853+ case OP_MINSTAR:
5854+ case OP_PLUS:
5855+ case OP_MINPLUS:
5856+ case OP_QUERY:
5857+ case OP_MINQUERY:
5858+ c = *ecode++ - OP_STAR;
5859+ minimize = (c & 1) != 0;
5860+ min = rep_min[c]; /* Pick up values from tables; */
5861+ max = rep_max[c]; /* zero for max => infinity */
5862+ if (max == 0) max = INT_MAX;
5863+
5864+ /* Common code for all repeated single-character matches. We can give
5865+ up quickly if there are fewer than the minimum number of characters left in
5866+ the subject. */
5867+
5868+ REPEATCHAR:
5869+ if (min > md->end_subject - eptr) return FALSE;
5870+ c = *ecode++;
5871+
5872+ /* The code is duplicated for the caseless and caseful cases, for speed,
5873+ since matching characters is likely to be quite common. First, ensure the
5874+ minimum number of matches are present. If min = max, continue at the same
5875+ level without recursing. Otherwise, if minimizing, keep trying the rest of
5876+ the expression and advancing one matching character if failing, up to the
5877+ maximum. Alternatively, if maximizing, find the maximum number of
5878+ characters and work backwards. */
5879+
5880+ DPRINTF(("matching %c{%d,%d} against subject %.*s\n", c, min, max,
5881+ max, eptr));
5882+
5883+ if ((ims & PCRE_CASELESS) != 0)
5884+ {
5885+ c = md->lcc[c];
5886+ for (i = 1; i <= min; i++)
5887+ if (c != md->lcc[*eptr++]) return FALSE;
5888+ if (min == max) continue;
5889+ if (minimize)
5890+ {
5891+ for (i = min;; i++)
5892+ {
5893+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
5894+ return TRUE;
5895+ if (i >= max || eptr >= md->end_subject ||
5896+ c != md->lcc[*eptr++])
5897+ return FALSE;
5898+ }
5899+ /* Control never gets here */
5900+ }
5901+ else
5902+ {
5903+ const uschar *pp = eptr;
5904+ for (i = min; i < max; i++)
5905+ {
5906+ if (eptr >= md->end_subject || c != md->lcc[*eptr]) break;
5907+ eptr++;
5908+ }
5909+ while (eptr >= pp)
5910+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
5911+ return TRUE;
5912+ return FALSE;
5913+ }
5914+ /* Control never gets here */
5915+ }
5916+
5917+ /* Caseful comparisons */
5918+
5919+ else
5920+ {
5921+ for (i = 1; i <= min; i++) if (c != *eptr++) return FALSE;
5922+ if (min == max) continue;
5923+ if (minimize)
5924+ {
5925+ for (i = min;; i++)
5926+ {
5927+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
5928+ return TRUE;
5929+ if (i >= max || eptr >= md->end_subject || c != *eptr++) return FALSE;
5930+ }
5931+ /* Control never gets here */
5932+ }
5933+ else
5934+ {
5935+ const uschar *pp = eptr;
5936+ for (i = min; i < max; i++)
5937+ {
5938+ if (eptr >= md->end_subject || c != *eptr) break;
5939+ eptr++;
5940+ }
5941+ while (eptr >= pp)
5942+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
5943+ return TRUE;
5944+ return FALSE;
5945+ }
5946+ }
5947+ /* Control never gets here */
5948+
5949+ /* Match a negated single character */
5950+
5951+ case OP_NOT:
5952+ if (eptr >= md->end_subject) return FALSE;
5953+ ecode++;
5954+ if ((ims & PCRE_CASELESS) != 0)
5955+ {
5956+ if (md->lcc[*ecode++] == md->lcc[*eptr++]) return FALSE;
5957+ }
5958+ else
5959+ {
5960+ if (*ecode++ == *eptr++) return FALSE;
5961+ }
5962+ break;
5963+
5964+ /* Match a negated single character repeatedly. This is almost a repeat of
5965+ the code for a repeated single character, but I haven't found a nice way of
5966+ commoning these up that doesn't require a test of the positive/negative
5967+ option for each character match. Maybe that wouldn't add very much to the
5968+ time taken, but character matching *is* what this is all about... */
5969+
5970+ case OP_NOTEXACT:
5971+ min = max = (ecode[1] << 8) + ecode[2];
5972+ ecode += 3;
5973+ goto REPEATNOTCHAR;
5974+
5975+ case OP_NOTUPTO:
5976+ case OP_NOTMINUPTO:
5977+ min = 0;
5978+ max = (ecode[1] << 8) + ecode[2];
5979+ minimize = *ecode == OP_NOTMINUPTO;
5980+ ecode += 3;
5981+ goto REPEATNOTCHAR;
5982+
5983+ case OP_NOTSTAR:
5984+ case OP_NOTMINSTAR:
5985+ case OP_NOTPLUS:
5986+ case OP_NOTMINPLUS:
5987+ case OP_NOTQUERY:
5988+ case OP_NOTMINQUERY:
5989+ c = *ecode++ - OP_NOTSTAR;
5990+ minimize = (c & 1) != 0;
5991+ min = rep_min[c]; /* Pick up values from tables; */
5992+ max = rep_max[c]; /* zero for max => infinity */
5993+ if (max == 0) max = INT_MAX;
5994+
5995+ /* Common code for all repeated single-character matches. We can give
5996+ up quickly if there are fewer than the minimum number of characters left in
5997+ the subject. */
5998+
5999+ REPEATNOTCHAR:
6000+ if (min > md->end_subject - eptr) return FALSE;
6001+ c = *ecode++;
6002+
6003+ /* The code is duplicated for the caseless and caseful cases, for speed,
6004+ since matching characters is likely to be quite common. First, ensure the
6005+ minimum number of matches are present. If min = max, continue at the same
6006+ level without recursing. Otherwise, if minimizing, keep trying the rest of
6007+ the expression and advancing one matching character if failing, up to the
6008+ maximum. Alternatively, if maximizing, find the maximum number of
6009+ characters and work backwards. */
6010+
6011+ DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", c, min, max,
6012+ max, eptr));
6013+
6014+ if ((ims & PCRE_CASELESS) != 0)
6015+ {
6016+ c = md->lcc[c];
6017+ for (i = 1; i <= min; i++)
6018+ if (c == md->lcc[*eptr++]) return FALSE;
6019+ if (min == max) continue;
6020+ if (minimize)
6021+ {
6022+ for (i = min;; i++)
6023+ {
6024+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
6025+ return TRUE;
6026+ if (i >= max || eptr >= md->end_subject ||
6027+ c == md->lcc[*eptr++])
6028+ return FALSE;
6029+ }
6030+ /* Control never gets here */
6031+ }
6032+ else
6033+ {
6034+ const uschar *pp = eptr;
6035+ for (i = min; i < max; i++)
6036+ {
6037+ if (eptr >= md->end_subject || c == md->lcc[*eptr]) break;
6038+ eptr++;
6039+ }
6040+ while (eptr >= pp)
6041+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
6042+ return TRUE;
6043+ return FALSE;
6044+ }
6045+ /* Control never gets here */
6046+ }
6047+
6048+ /* Caseful comparisons */
6049+
6050+ else
6051+ {
6052+ for (i = 1; i <= min; i++) if (c == *eptr++) return FALSE;
6053+ if (min == max) continue;
6054+ if (minimize)
6055+ {
6056+ for (i = min;; i++)
6057+ {
6058+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0))
6059+ return TRUE;
6060+ if (i >= max || eptr >= md->end_subject || c == *eptr++) return FALSE;
6061+ }
6062+ /* Control never gets here */
6063+ }
6064+ else
6065+ {
6066+ const uschar *pp = eptr;
6067+ for (i = min; i < max; i++)
6068+ {
6069+ if (eptr >= md->end_subject || c == *eptr) break;
6070+ eptr++;
6071+ }
6072+ while (eptr >= pp)
6073+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
6074+ return TRUE;
6075+ return FALSE;
6076+ }
6077+ }
6078+ /* Control never gets here */
6079+
6080+ /* Match a single character type repeatedly; several different opcodes
6081+ share code. This is very similar to the code for single characters, but we
6082+ repeat it in the interests of efficiency. */
6083+
6084+ case OP_TYPEEXACT:
6085+ min = max = (ecode[1] << 8) + ecode[2];
6086+ minimize = TRUE;
6087+ ecode += 3;
6088+ goto REPEATTYPE;
6089+
6090+ case OP_TYPEUPTO:
6091+ case OP_TYPEMINUPTO:
6092+ min = 0;
6093+ max = (ecode[1] << 8) + ecode[2];
6094+ minimize = *ecode == OP_TYPEMINUPTO;
6095+ ecode += 3;
6096+ goto REPEATTYPE;
6097+
6098+ case OP_TYPESTAR:
6099+ case OP_TYPEMINSTAR:
6100+ case OP_TYPEPLUS:
6101+ case OP_TYPEMINPLUS:
6102+ case OP_TYPEQUERY:
6103+ case OP_TYPEMINQUERY:
6104+ c = *ecode++ - OP_TYPESTAR;
6105+ minimize = (c & 1) != 0;
6106+ min = rep_min[c]; /* Pick up values from tables; */
6107+ max = rep_max[c]; /* zero for max => infinity */
6108+ if (max == 0) max = INT_MAX;
6109+
6110+ /* Common code for all repeated single character type matches */
6111+
6112+ REPEATTYPE:
6113+ ctype = *ecode++; /* Code for the character type */
6114+
6115+ /* First, ensure the minimum number of matches are present. Use inline
6116+ code for maximizing the speed, and do the type test once at the start
6117+ (i.e. keep it out of the loop). Also we can test that there are at least
6118+ the minimum number of bytes before we start, except when doing '.' in
6119+ UTF8 mode. Leave the test in in all cases; in the special case we have
6120+ to test after each character. */
6121+
6122+ if (min > md->end_subject - eptr) return FALSE;
6123+ if (min > 0) switch(ctype)
6124+ {
6125+ case OP_ANY:
6126+#ifdef SUPPORT_UTF8
6127+ if (md->utf8)
6128+ {
6129+ for (i = 1; i <= min; i++)
6130+ {
6131+ if (eptr >= md->end_subject ||
6132+ (*eptr++ == NEWLINE && (ims & PCRE_DOTALL) == 0))
6133+ return FALSE;
6134+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
6135+ }
6136+ break;
6137+ }
6138+#endif
6139+ /* Non-UTF8 can be faster */
6140+ if ((ims & PCRE_DOTALL) == 0)
6141+ { for (i = 1; i <= min; i++) if (*eptr++ == NEWLINE) return FALSE; }
6142+ else eptr += min;
6143+ break;
6144+
6145+ case OP_NOT_DIGIT:
6146+ for (i = 1; i <= min; i++)
6147+ if ((md->ctypes[*eptr++] & ctype_digit) != 0) return FALSE;
6148+ break;
6149+
6150+ case OP_DIGIT:
6151+ for (i = 1; i <= min; i++)
6152+ if ((md->ctypes[*eptr++] & ctype_digit) == 0) return FALSE;
6153+ break;
6154+
6155+ case OP_NOT_WHITESPACE:
6156+ for (i = 1; i <= min; i++)
6157+ if ((md->ctypes[*eptr++] & ctype_space) != 0) return FALSE;
6158+ break;
6159+
6160+ case OP_WHITESPACE:
6161+ for (i = 1; i <= min; i++)
6162+ if ((md->ctypes[*eptr++] & ctype_space) == 0) return FALSE;
6163+ break;
6164+
6165+ case OP_NOT_WORDCHAR:
6166+ for (i = 1; i <= min; i++)
6167+ if ((md->ctypes[*eptr++] & ctype_word) != 0)
6168+ return FALSE;
6169+ break;
6170+
6171+ case OP_WORDCHAR:
6172+ for (i = 1; i <= min; i++)
6173+ if ((md->ctypes[*eptr++] & ctype_word) == 0)
6174+ return FALSE;
6175+ break;
6176+ }
6177+
6178+ /* If min = max, continue at the same level without recursing */
6179+
6180+ if (min == max) continue;
6181+
6182+ /* If minimizing, we have to test the rest of the pattern before each
6183+ subsequent match. */
6184+
6185+ if (minimize)
6186+ {
6187+ for (i = min;; i++)
6188+ {
6189+ if (match(eptr, ecode, offset_top, md, ims, eptrb, 0)) return TRUE;
6190+ if (i >= max || eptr >= md->end_subject) return FALSE;
6191+
6192+ c = *eptr++;
6193+ switch(ctype)
6194+ {
6195+ case OP_ANY:
6196+ if ((ims & PCRE_DOTALL) == 0 && c == NEWLINE) return FALSE;
6197+#ifdef SUPPORT_UTF8
6198+ if (md->utf8)
6199+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
6200+#endif
6201+ break;
6202+
6203+ case OP_NOT_DIGIT:
6204+ if ((md->ctypes[c] & ctype_digit) != 0) return FALSE;
6205+ break;
6206+
6207+ case OP_DIGIT:
6208+ if ((md->ctypes[c] & ctype_digit) == 0) return FALSE;
6209+ break;
6210+
6211+ case OP_NOT_WHITESPACE:
6212+ if ((md->ctypes[c] & ctype_space) != 0) return FALSE;
6213+ break;
6214+
6215+ case OP_WHITESPACE:
6216+ if ((md->ctypes[c] & ctype_space) == 0) return FALSE;
6217+ break;
6218+
6219+ case OP_NOT_WORDCHAR:
6220+ if ((md->ctypes[c] & ctype_word) != 0) return FALSE;
6221+ break;
6222+
6223+ case OP_WORDCHAR:
6224+ if ((md->ctypes[c] & ctype_word) == 0) return FALSE;
6225+ break;
6226+ }
6227+ }
6228+ /* Control never gets here */
6229+ }
6230+
6231+ /* If maximizing it is worth using inline code for speed, doing the type
6232+ test once at the start (i.e. keep it out of the loop). */
6233+
6234+ else
6235+ {
6236+ const uschar *pp = eptr;
6237+ switch(ctype)
6238+ {
6239+ case OP_ANY:
6240+
6241+ /* Special code is required for UTF8, but when the maximum is unlimited
6242+ we don't need it. */
6243+
6244+#ifdef SUPPORT_UTF8
6245+ if (md->utf8 && max < INT_MAX)
6246+ {
6247+ if ((ims & PCRE_DOTALL) == 0)
6248+ {
6249+ for (i = min; i < max; i++)
6250+ {
6251+ if (eptr >= md->end_subject || *eptr++ == NEWLINE) break;
6252+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
6253+ }
6254+ }
6255+ else
6256+ {
6257+ for (i = min; i < max; i++)
6258+ {
6259+ eptr++;
6260+ while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
6261+ }
6262+ }
6263+ break;
6264+ }
6265+#endif
6266+ /* Non-UTF8 can be faster */
6267+ if ((ims & PCRE_DOTALL) == 0)
6268+ {
6269+ for (i = min; i < max; i++)
6270+ {
6271+ if (eptr >= md->end_subject || *eptr == NEWLINE) break;
6272+ eptr++;
6273+ }
6274+ }
6275+ else
6276+ {
6277+ c = max - min;
6278+ if (c > md->end_subject - eptr) c = md->end_subject - eptr;
6279+ eptr += c;
6280+ }
6281+ break;
6282+
6283+ case OP_NOT_DIGIT:
6284+ for (i = min; i < max; i++)
6285+ {
6286+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0)
6287+ break;
6288+ eptr++;
6289+ }
6290+ break;
6291+
6292+ case OP_DIGIT:
6293+ for (i = min; i < max; i++)
6294+ {
6295+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0)
6296+ break;
6297+ eptr++;
6298+ }
6299+ break;
6300+
6301+ case OP_NOT_WHITESPACE:
6302+ for (i = min; i < max; i++)
6303+ {
6304+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0)
6305+ break;
6306+ eptr++;
6307+ }
6308+ break;
6309+
6310+ case OP_WHITESPACE:
6311+ for (i = min; i < max; i++)
6312+ {
6313+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0)
6314+ break;
6315+ eptr++;
6316+ }
6317+ break;
6318+
6319+ case OP_NOT_WORDCHAR:
6320+ for (i = min; i < max; i++)
6321+ {
6322+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0)
6323+ break;
6324+ eptr++;
6325+ }
6326+ break;
6327+
6328+ case OP_WORDCHAR:
6329+ for (i = min; i < max; i++)
6330+ {
6331+ if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0)
6332+ break;
6333+ eptr++;
6334+ }
6335+ break;
6336+ }
6337+
6338+ while (eptr >= pp)
6339+ {
6340+ if (match(eptr--, ecode, offset_top, md, ims, eptrb, 0))
6341+ return TRUE;
6342+#ifdef SUPPORT_UTF8
6343+ if (md->utf8)
6344+ while (eptr > pp && (*eptr & 0xc0) == 0x80) eptr--;
6345+#endif
6346+ }
6347+ return FALSE;
6348+ }
6349+ /* Control never gets here */
6350+
6351+ /* There's been some horrible disaster. */
6352+
6353+ default:
6354+ DPRINTF(("Unknown opcode %d\n", *ecode));
6355+ md->errorcode = PCRE_ERROR_UNKNOWN_NODE;
6356+ return FALSE;
6357+ }
6358+
6359+ /* Do not stick any code in here without much thought; it is assumed
6360+ that "continue" in the code above comes out to here to repeat the main
6361+ loop. */
6362+
6363+ } /* End of main loop */
6364+/* Control never reaches here */
6365+}
6366+
6367+
6368+/*************************************************
6369+* Execute a Regular Expression *
6370+*************************************************/
6371+
6372+/* This function applies a compiled re to a subject string and picks out
6373+portions of the string if it matches. Two elements in the vector are set for
6374+each substring: the offsets to the start and end of the substring.
6375+
6376+Arguments:
6377+ external_re points to the compiled expression
6378+ external_extra points to "hints" from pcre_study() or is NULL
6379+ subject points to the subject string
6380+ length length of subject string (may contain binary zeros)
6381+ start_offset where to start in the subject string
6382+ options option bits
6383+ offsets points to a vector of ints to be filled in with offsets
6384+ offsetcount the number of elements in the vector
6385+
6386+Returns: > 0 => success; value is the number of elements filled in
6387+ = 0 => success, but offsets is not big enough
6388+ -1 => failed to match
6389+ < -1 => some kind of unexpected problem
6390+*/
6391+
6392+int
6393+pcre_exec(const pcre *external_re, const pcre_extra *external_extra,
6394+ const char *subject, int length, int start_offset, int options, int *offsets,
6395+ int offsetcount)
6396+{
6397+int resetcount, ocount;
6398+int first_char = -1;
6399+int req_char = -1;
6400+int req_char2 = -1;
6401+unsigned long int ims = 0;
6402+match_data match_block;
6403+const uschar *start_bits = NULL;
6404+const uschar *start_match = (const uschar *)subject + start_offset;
6405+const uschar *end_subject;
6406+const uschar *req_char_ptr = start_match - 1;
6407+const real_pcre *re = (const real_pcre *)external_re;
6408+const real_pcre_extra *extra = (const real_pcre_extra *)external_extra;
6409+BOOL using_temporary_offsets = FALSE;
6410+BOOL anchored;
6411+BOOL startline;
6412+
6413+if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
6414+
6415+if (re == NULL || subject == NULL ||
6416+ (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
6417+if (re->magic_number != MAGIC_NUMBER) return PCRE_ERROR_BADMAGIC;
6418+
6419+anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
6420+startline = (re->options & PCRE_STARTLINE) != 0;
6421+
6422+match_block.start_pattern = re->code;
6423+match_block.start_subject = (const uschar *)subject;
6424+match_block.end_subject = match_block.start_subject + length;
6425+end_subject = match_block.end_subject;
6426+
6427+match_block.endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6428+match_block.utf8 = (re->options & PCRE_UTF8) != 0;
6429+
6430+match_block.notbol = (options & PCRE_NOTBOL) != 0;
6431+match_block.noteol = (options & PCRE_NOTEOL) != 0;
6432+match_block.notempty = (options & PCRE_NOTEMPTY) != 0;
6433+
6434+match_block.errorcode = PCRE_ERROR_NOMATCH; /* Default error */
6435+
6436+match_block.lcc = re->tables + lcc_offset;
6437+match_block.ctypes = re->tables + ctypes_offset;
6438+
6439+/* The ims options can vary during the matching as a result of the presence
6440+of (?ims) items in the pattern. They are kept in a local variable so that
6441+restoring at the exit of a group is easy. */
6442+
6443+ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL);
6444+
6445+/* If the expression has got more back references than the offsets supplied can
6446+hold, we get a temporary bit of working store to use during the matching.
6447+Otherwise, we can use the vector supplied, rounding down its size to a multiple
6448+of 3. */
6449+
6450+ocount = offsetcount - (offsetcount % 3);
6451+
6452+if (re->top_backref > 0 && re->top_backref >= ocount/3)
6453+ {
6454+ ocount = re->top_backref * 3 + 3;
6455+ match_block.offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
6456+ if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
6457+ using_temporary_offsets = TRUE;
6458+ DPRINTF(("Got memory to hold back references\n"));
6459+ }
6460+else match_block.offset_vector = offsets;
6461+
6462+match_block.offset_end = ocount;
6463+match_block.offset_max = (2*ocount)/3;
6464+match_block.offset_overflow = FALSE;
6465+
6466+/* Compute the minimum number of offsets that we need to reset each time. Doing
6467+this makes a huge difference to execution time when there aren't many brackets
6468+in the pattern. */
6469+
6470+resetcount = 2 + re->top_bracket * 2;
6471+if (resetcount > offsetcount) resetcount = ocount;
6472+
6473+/* Reset the working variable associated with each extraction. These should
6474+never be used unless previously set, but they get saved and restored, and so we
6475+initialize them to avoid reading uninitialized locations. */
6476+
6477+if (match_block.offset_vector != NULL)
6478+ {
6479+ register int *iptr = match_block.offset_vector + ocount;
6480+ register int *iend = iptr - resetcount/2 + 1;
6481+ while (--iptr >= iend) *iptr = -1;
6482+ }
6483+
6484+/* Set up the first character to match, if available. The first_char value is
6485+never set for an anchored regular expression, but the anchoring may be forced
6486+at run time, so we have to test for anchoring. The first char may be unset for
6487+an unanchored pattern, of course. If there's no first char and the pattern was
6488+studied, there may be a bitmap of possible first characters. */
6489+
6490+if (!anchored)
6491+ {
6492+ if ((re->options & PCRE_FIRSTSET) != 0)
6493+ {
6494+ first_char = re->first_char;
6495+ if ((ims & PCRE_CASELESS) != 0) first_char = match_block.lcc[first_char];
6496+ }
6497+ else
6498+ if (!startline && extra != NULL &&
6499+ (extra->options & PCRE_STUDY_MAPPED) != 0)
6500+ start_bits = extra->start_bits;
6501+ }
6502+
6503+/* For anchored or unanchored matches, there may be a "last known required
6504+character" set. If the PCRE_CASELESS is set, implying that the match starts
6505+caselessly, or if there are any changes of this flag within the regex, set up
6506+both cases of the character. Otherwise set the two values the same, which will
6507+avoid duplicate testing (which takes significant time). This covers the vast
6508+majority of cases. It will be suboptimal when the case flag changes in a regex
6509+and the required character in fact is caseful. */
6510+
6511+if ((re->options & PCRE_REQCHSET) != 0)
6512+ {
6513+ req_char = re->req_char;
6514+ req_char2 = ((re->options & (PCRE_CASELESS | PCRE_ICHANGED)) != 0)?
6515+ (re->tables + fcc_offset)[req_char] : req_char;
6516+ }
6517+
6518+/* Loop for handling unanchored repeated matching attempts; for anchored regexs
6519+the loop runs just once. */
6520+
6521+do
6522+ {
6523+ int rc;
6524+ register int *iptr = match_block.offset_vector;
6525+ register int *iend = iptr + resetcount;
6526+
6527+ /* Reset the maximum number of extractions we might see. */
6528+
6529+ while (iptr < iend) *iptr++ = -1;
6530+
6531+ /* Advance to a unique first char if possible */
6532+
6533+ if (first_char >= 0)
6534+ {
6535+ if ((ims & PCRE_CASELESS) != 0)
6536+ while (start_match < end_subject &&
6537+ match_block.lcc[*start_match] != first_char)
6538+ start_match++;
6539+ else
6540+ while (start_match < end_subject && *start_match != first_char)
6541+ start_match++;
6542+ }
6543+
6544+ /* Or to just after \n for a multiline match if possible */
6545+
6546+ else if (startline)
6547+ {
6548+ if (start_match > match_block.start_subject + start_offset)
6549+ {
6550+ while (start_match < end_subject && start_match[-1] != NEWLINE)
6551+ start_match++;
6552+ }
6553+ }
6554+
6555+ /* Or to a non-unique first char after study */
6556+
6557+ else if (start_bits != NULL)
6558+ {
6559+ while (start_match < end_subject)
6560+ {
6561+ register int c = *start_match;
6562+ if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++; else break;
6563+ }
6564+ }
6565+
6566+#ifdef DEBUG /* Sigh. Some compilers never learn. */
6567+ PCRE_PRINTF(">>>> Match against: ");
6568+ pchars(start_match, end_subject - start_match, TRUE, &match_block);
6569+ PCRE_PRINTF("\n");
6570+#endif
6571+
6572+ /* If req_char is set, we know that that character must appear in the subject
6573+ for the match to succeed. If the first character is set, req_char must be
6574+ later in the subject; otherwise the test starts at the match point. This
6575+ optimization can save a huge amount of backtracking in patterns with nested
6576+ unlimited repeats that aren't going to match. We don't know what the state of
6577+ case matching may be when this character is hit, so test for it in both its
6578+ cases if necessary. However, the different cased versions will not be set up
6579+ unless PCRE_CASELESS was given or the casing state changes within the regex.
6580+ Writing separate code makes it go faster, as does using an autoincrement and
6581+ backing off on a match. */
6582+
6583+ if (req_char >= 0)
6584+ {
6585+ register const uschar *p = start_match + ((first_char >= 0)? 1 : 0);
6586+
6587+ /* We don't need to repeat the search if we haven't yet reached the
6588+ place we found it at last time. */
6589+
6590+ if (p > req_char_ptr)
6591+ {
6592+ /* Do a single test if no case difference is set up */
6593+
6594+ if (req_char == req_char2)
6595+ {
6596+ while (p < end_subject)
6597+ {
6598+ if (*p++ == req_char) { p--; break; }
6599+ }
6600+ }
6601+
6602+ /* Otherwise test for either case */
6603+
6604+ else
6605+ {
6606+ while (p < end_subject)
6607+ {
6608+ register int pp = *p++;
6609+ if (pp == req_char || pp == req_char2) { p--; break; }
6610+ }
6611+ }
6612+
6613+ /* If we can't find the required character, break the matching loop */
6614+
6615+ if (p >= end_subject) break;
6616+
6617+ /* If we have found the required character, save the point where we
6618+ found it, so that we don't search again next time round the loop if
6619+ the start hasn't passed this character yet. */
6620+
6621+ req_char_ptr = p;
6622+ }
6623+ }
6624+
6625+ /* When a match occurs, substrings will be set for all internal extractions;
6626+ we just need to set up the whole thing as substring 0 before returning. If
6627+ there were too many extractions, set the return code to zero. In the case
6628+ where we had to get some local store to hold offsets for backreferences, copy
6629+ those back references that we can. In this case there need not be overflow
6630+ if certain parts of the pattern were not used. */
6631+
6632+ match_block.start_match = start_match;
6633+ if (!match(start_match, re->code, 2, &match_block, ims, NULL, match_isgroup))
6634+ continue;
6635+
6636+ /* Copy the offset information from temporary store if necessary */
6637+
6638+ if (using_temporary_offsets)
6639+ {
6640+ if (offsetcount >= 4)
6641+ {
6642+ memcpy(offsets + 2, match_block.offset_vector + 2,
6643+ (offsetcount - 2) * sizeof(int));
6644+ DPRINTF(("Copied offsets from temporary memory\n"));
6645+ }
6646+ if (match_block.end_offset_top > offsetcount)
6647+ match_block.offset_overflow = TRUE;
6648+
6649+ DPRINTF(("Freeing temporary memory\n"));
6650+ (pcre_free)(match_block.offset_vector);
6651+ }
6652+
6653+ rc = match_block.offset_overflow? 0 : match_block.end_offset_top/2;
6654+
6655+ if (offsetcount < 2) rc = 0; else
6656+ {
6657+ offsets[0] = start_match - match_block.start_subject;
6658+ offsets[1] = match_block.end_match_ptr - match_block.start_subject;
6659+ }
6660+
6661+ DPRINTF((">>>> returning %d\n", rc));
6662+ return rc;
6663+ }
6664+
6665+/* This "while" is the end of the "do" above */
6666+
6667+while (!anchored &&
6668+ match_block.errorcode == PCRE_ERROR_NOMATCH &&
6669+ start_match++ < end_subject);
6670+
6671+if (using_temporary_offsets)
6672+ {
6673+ DPRINTF(("Freeing temporary memory\n"));
6674+ (pcre_free)(match_block.offset_vector);
6675+ }
6676+
6677+DPRINTF((">>>> returning %d\n", match_block.errorcode));
6678+
6679+return match_block.errorcode;
6680+}
6681+
6682+/* End of pcre.c */
6683Index: b/security/apparmor/match/pcre_exec.h
6684===================================================================
6685--- /dev/null
6686+++ b/security/apparmor/match/pcre_exec.h
6687@@ -0,0 +1,308 @@
6688+/*
6689+ * This is a modified header file containing the definitions from
6690+ * pcre.h and internal.h required to support pcre_exec()
6691+ */
6692+
6693+
6694+/*************************************************
6695+* Perl-Compatible Regular Expressions *
6696+*************************************************/
6697+
6698+/* Copyright (c) 1997-2001 University of Cambridge */
6699+
6700+#ifndef _PCRE_H
6701+#define _PCRE_H
6702+
6703+/* ----- CODE ADDED ---- */
6704+
6705+#ifdef __KERNEL__
6706+#include <linux/slab.h> // for kmalloc/kfree
6707+#endif
6708+
6709+#ifdef __KERNEL__
6710+#define PCRE_PRINTF printk
6711+#define isprint(x) ((unsigned char)(x) >= 128 && (unsigned char)(x) <= 255)
6712+#else
6713+#define PCRE_PRINTF printf
6714+#endif
6715+
6716+/* The value of NEWLINE determines the newline character. The default is to
6717+ * leave it up to the compiler, but some sites want to force a particular value.
6718+ * On Unix systems, "configure" can be used to override this default. */
6719+
6720+#ifndef NEWLINE
6721+#define NEWLINE '\n'
6722+#endif
6723+
6724+/* ---- CODE DELETED ---- */
6725+
6726+/* Options */
6727+
6728+#define PCRE_CASELESS 0x0001
6729+#define PCRE_MULTILINE 0x0002
6730+#define PCRE_DOTALL 0x0004
6731+#define PCRE_EXTENDED 0x0008
6732+#define PCRE_ANCHORED 0x0010
6733+#define PCRE_DOLLAR_ENDONLY 0x0020
6734+#define PCRE_EXTRA 0x0040
6735+#define PCRE_NOTBOL 0x0080
6736+#define PCRE_NOTEOL 0x0100
6737+#define PCRE_UNGREEDY 0x0200
6738+#define PCRE_NOTEMPTY 0x0400
6739+#define PCRE_UTF8 0x0800
6740+
6741+/* Exec-time and get-time error codes */
6742+
6743+#define PCRE_ERROR_NOMATCH (-1)
6744+#define PCRE_ERROR_NULL (-2)
6745+#define PCRE_ERROR_BADOPTION (-3)
6746+#define PCRE_ERROR_BADMAGIC (-4)
6747+#define PCRE_ERROR_UNKNOWN_NODE (-5)
6748+#define PCRE_ERROR_NOMEMORY (-6)
6749+#define PCRE_ERROR_NOSUBSTRING (-7)
6750+
6751+/* ---- CODE DELETED ---- */
6752+
6753+/* Types */
6754+
6755+struct real_pcre; /* declaration; the definition is private */
6756+struct real_pcre_extra; /* declaration; the definition is private */
6757+
6758+typedef struct real_pcre pcre;
6759+typedef struct real_pcre_extra pcre_extra;
6760+
6761+/* ---- CODE DELETED ---- */
6762+
6763+extern int pcre_exec(const pcre *, const pcre_extra *,
6764+ const char *, int, int, int, int *,
6765+ int);
6766+
6767+/* ---- CODE ADDED (from internal.h) ---- */
6768+
6769+/* These are the public options that can change during matching. */
6770+
6771+#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
6772+
6773+/* Private options flags start at the most significant end of the four bytes,
6774+but skip the top bit so we can use ints for convenience without getting tangled
6775+with negative values. The public options defined in pcre.h start at the least
6776+significant end. Make sure they don't overlap, though now that we have expanded
6777+to four bytes there is plenty of space. */
6778+
6779+#define PCRE_FIRSTSET 0x40000000 /* first_char is set */
6780+#define PCRE_REQCHSET 0x20000000 /* req_char is set */
6781+#define PCRE_STARTLINE 0x10000000 /* start after \n for multiline */
6782+#define PCRE_ICHANGED 0x04000000 /* i option changes within regex */
6783+
6784+/* Options for the "extra" block produced by pcre_study(). */
6785+
6786+#define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */
6787+
6788+/* Masks for identifying the public options which are permitted at compile
6789+time, run time or study time, respectively. */
6790+
6791+#define PUBLIC_EXEC_OPTIONS \
6792+ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY)
6793+
6794+/* Magic number to provide a small check against being handed junk. */
6795+
6796+#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
6797+
6798+typedef int BOOL;
6799+
6800+#define FALSE 0
6801+#define TRUE 1
6802+
6803+/* Opcode table: OP_BRA must be last, as all values >= it are used for brackets
6804+that extract substrings. Starting from 1 (i.e. after OP_END), the values up to
6805+OP_EOD must correspond in order to the list of escapes immediately above. */
6806+
6807+enum {
6808+ OP_END, /* End of pattern */
6809+
6810+ /* Values corresponding to backslashed metacharacters */
6811+
6812+ OP_SOD, /* Start of data: \A */
6813+ OP_NOT_WORD_BOUNDARY, /* \B */
6814+ OP_WORD_BOUNDARY, /* \b */
6815+ OP_NOT_DIGIT, /* \D */
6816+ OP_DIGIT, /* \d */
6817+ OP_NOT_WHITESPACE, /* \S */
6818+ OP_WHITESPACE, /* \s */
6819+ OP_NOT_WORDCHAR, /* \W */
6820+ OP_WORDCHAR, /* \w */
6821+ OP_EODN, /* End of data or \n at end of data: \Z. */
6822+ OP_EOD, /* End of data: \z */
6823+
6824+ OP_OPT, /* Set runtime options */
6825+ OP_CIRC, /* Start of line - varies with multiline switch */
6826+ OP_DOLL, /* End of line - varies with multiline switch */
6827+ OP_ANY, /* Match any character */
6828+ OP_CHARS, /* Match string of characters */
6829+ OP_NOT, /* Match anything but the following char */
6830+
6831+ OP_STAR, /* The maximizing and minimizing versions of */
6832+ OP_MINSTAR, /* all these opcodes must come in pairs, with */
6833+ OP_PLUS, /* the minimizing one second. */
6834+ OP_MINPLUS, /* This first set applies to single characters */
6835+ OP_QUERY,
6836+ OP_MINQUERY,
6837+ OP_UPTO, /* From 0 to n matches */
6838+ OP_MINUPTO,
6839+ OP_EXACT, /* Exactly n matches */
6840+
6841+ OP_NOTSTAR, /* The maximizing and minimizing versions of */
6842+ OP_NOTMINSTAR, /* all these opcodes must come in pairs, with */
6843+ OP_NOTPLUS, /* the minimizing one second. */
6844+ OP_NOTMINPLUS, /* This first set applies to "not" single characters */
6845+ OP_NOTQUERY,
6846+ OP_NOTMINQUERY,
6847+ OP_NOTUPTO, /* From 0 to n matches */
6848+ OP_NOTMINUPTO,
6849+ OP_NOTEXACT, /* Exactly n matches */
6850+
6851+ OP_TYPESTAR, /* The maximizing and minimizing versions of */
6852+ OP_TYPEMINSTAR, /* all these opcodes must come in pairs, with */
6853+ OP_TYPEPLUS, /* the minimizing one second. These codes must */
6854+ OP_TYPEMINPLUS, /* be in exactly the same order as those above. */
6855+ OP_TYPEQUERY, /* This set applies to character types such as \d */
6856+ OP_TYPEMINQUERY,
6857+ OP_TYPEUPTO, /* From 0 to n matches */
6858+ OP_TYPEMINUPTO,
6859+ OP_TYPEEXACT, /* Exactly n matches */
6860+
6861+ OP_CRSTAR, /* The maximizing and minimizing versions of */
6862+ OP_CRMINSTAR, /* all these opcodes must come in pairs, with */
6863+ OP_CRPLUS, /* the minimizing one second. These codes must */
6864+ OP_CRMINPLUS, /* be in exactly the same order as those above. */
6865+ OP_CRQUERY, /* These are for character classes and back refs */
6866+ OP_CRMINQUERY,
6867+ OP_CRRANGE, /* These are different to the three seta above. */
6868+ OP_CRMINRANGE,
6869+
6870+ OP_CLASS, /* Match a character class */
6871+ OP_REF, /* Match a back reference */
6872+ OP_RECURSE, /* Match this pattern recursively */
6873+
6874+ OP_ALT, /* Start of alternation */
6875+ OP_KET, /* End of group that doesn't have an unbounded repeat */
6876+ OP_KETRMAX, /* These two must remain together and in this */
6877+ OP_KETRMIN, /* order. They are for groups the repeat for ever. */
6878+
6879+ /* The assertions must come before ONCE and COND */
6880+
6881+ OP_ASSERT, /* Positive lookahead */
6882+ OP_ASSERT_NOT, /* Negative lookahead */
6883+ OP_ASSERTBACK, /* Positive lookbehind */
6884+ OP_ASSERTBACK_NOT, /* Negative lookbehind */
6885+ OP_REVERSE, /* Move pointer back - used in lookbehind assertions */
6886+
6887+ /* ONCE and COND must come after the assertions, with ONCE first, as there's
6888+ a test for >= ONCE for a subpattern that isn't an assertion. */
6889+
6890+ OP_ONCE, /* Once matched, don't back up into the subpattern */
6891+ OP_COND, /* Conditional group */
6892+ OP_CREF, /* Used to hold an extraction string number (cond ref) */
6893+
6894+ OP_BRAZERO, /* These two must remain together and in this */
6895+ OP_BRAMINZERO, /* order. */
6896+
6897+ OP_BRANUMBER, /* Used for extracting brackets whose number is greater
6898+ than can fit into an opcode. */
6899+
6900+ OP_BRA /* This and greater values are used for brackets that
6901+ extract substrings up to a basic limit. After that,
6902+ use is made of OP_BRANUMBER. */
6903+};
6904+
6905+/* The highest extraction number before we have to start using additional
6906+bytes. (Originally PCRE didn't have support for extraction counts highter than
6907+this number.) The value is limited by the number of opcodes left after OP_BRA,
6908+i.e. 255 - OP_BRA. We actually set it a bit lower to leave room for additional
6909+opcodes. */
6910+
6911+#define EXTRACT_BASIC_MAX 150
6912+
6913+/* All character handling must be done as unsigned characters. Otherwise there
6914+are problems with top-bit-set characters and functions such as isspace().
6915+However, we leave the interface to the outside world as char *, because that
6916+should make things easier for callers. We define a short type for unsigned char
6917+to save lots of typing. I tried "uchar", but it causes problems on Digital
6918+Unix, where it is defined in sys/types, so use "uschar" instead. */
6919+
6920+typedef unsigned char uschar;
6921+
6922+/* The real format of the start of the pcre block; the actual code vector
6923+runs on as long as necessary after the end. */
6924+
6925+typedef struct real_pcre {
6926+ unsigned long int magic_number;
6927+ size_t size;
6928+ const unsigned char *tables;
6929+ unsigned long int options;
6930+ unsigned short int top_bracket;
6931+ unsigned short int top_backref;
6932+ uschar first_char;
6933+ uschar req_char;
6934+ uschar code[1];
6935+} real_pcre;
6936+
6937+/* The real format of the extra block returned by pcre_study(). */
6938+
6939+typedef struct real_pcre_extra {
6940+ uschar options;
6941+ uschar start_bits[32];
6942+} real_pcre_extra;
6943+
6944+/* Structure for passing "static" information around between the functions
6945+doing the matching, so that they are thread-safe. */
6946+
6947+typedef struct match_data {
6948+ int errorcode; /* As it says */
6949+ int *offset_vector; /* Offset vector */
6950+ int offset_end; /* One past the end */
6951+ int offset_max; /* The maximum usable for return data */
6952+ const uschar *lcc; /* Points to lower casing table */
6953+ const uschar *ctypes; /* Points to table of type maps */
6954+ BOOL offset_overflow; /* Set if too many extractions */
6955+ BOOL notbol; /* NOTBOL flag */
6956+ BOOL noteol; /* NOTEOL flag */
6957+ BOOL utf8; /* UTF8 flag */
6958+ BOOL endonly; /* Dollar not before final \n */
6959+ BOOL notempty; /* Empty string match not wanted */
6960+ const uschar *start_pattern; /* For use when recursing */
6961+ const uschar *start_subject; /* Start of the subject string */
6962+ const uschar *end_subject; /* End of the subject string */
6963+ const uschar *start_match; /* Start of this match attempt */
6964+ const uschar *end_match_ptr; /* Subject position at end match */
6965+ int end_offset_top; /* Highwater mark at end of match */
6966+} match_data;
6967+
6968+/* Bit definitions for entries in the pcre_ctypes table. */
6969+
6970+#define ctype_space 0x01
6971+#define ctype_letter 0x02
6972+#define ctype_digit 0x04
6973+#define ctype_xdigit 0x08
6974+#define ctype_word 0x10 /* alphameric or '_' */
6975+#define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */
6976+
6977+/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
6978+of bits for a class map. Some classes are built by combining these tables. */
6979+
6980+#define cbit_length 320 /* Length of the cbits table */
6981+
6982+/* Offsets of the various tables from the base tables pointer, and
6983+total length. */
6984+
6985+#define lcc_offset 0
6986+#define fcc_offset 256
6987+
6988+#define fcc_offset 256
6989+#define cbits_offset 512
6990+#define ctypes_offset (cbits_offset + cbit_length)
6991+
6992+/* ----- CODE ADDED ---- */
6993+
6994+#endif // _PCRE_H
6995+ /* End of pcre.h */
6996Index: b/security/apparmor/match/pcre_tables.h
6997===================================================================
6998--- /dev/null
6999+++ b/security/apparmor/match/pcre_tables.h
7000@@ -0,0 +1,184 @@
7001+
7002+/*************************************************
7003+* Perl-Compatible Regular Expressions *
7004+*************************************************/
7005+
7006+/* This file is automatically written by the dftables auxiliary
7007+program. If you edit it by hand, you might like to edit the Makefile to
7008+prevent its ever being regenerated.
7009+
7010+This file is #included in the compilation of pcre.c to build the default
7011+character tables which are used when no tables are passed to the compile
7012+function. */
7013+
7014+static unsigned char pcre_default_tables[] = {
7015+
7016+/* This table is a lower casing table. */
7017+
7018+ 0, 1, 2, 3, 4, 5, 6, 7,
7019+ 8, 9, 10, 11, 12, 13, 14, 15,
7020+ 16, 17, 18, 19, 20, 21, 22, 23,
7021+ 24, 25, 26, 27, 28, 29, 30, 31,
7022+ 32, 33, 34, 35, 36, 37, 38, 39,
7023+ 40, 41, 42, 43, 44, 45, 46, 47,
7024+ 48, 49, 50, 51, 52, 53, 54, 55,
7025+ 56, 57, 58, 59, 60, 61, 62, 63,
7026+ 64, 97, 98, 99,100,101,102,103,
7027+ 104,105,106,107,108,109,110,111,
7028+ 112,113,114,115,116,117,118,119,
7029+ 120,121,122, 91, 92, 93, 94, 95,
7030+ 96, 97, 98, 99,100,101,102,103,
7031+ 104,105,106,107,108,109,110,111,
7032+ 112,113,114,115,116,117,118,119,
7033+ 120,121,122,123,124,125,126,127,
7034+ 128,129,130,131,132,133,134,135,
7035+ 136,137,138,139,140,141,142,143,
7036+ 144,145,146,147,148,149,150,151,
7037+ 152,153,154,155,156,157,158,159,
7038+ 160,161,162,163,164,165,166,167,
7039+ 168,169,170,171,172,173,174,175,
7040+ 176,177,178,179,180,181,182,183,
7041+ 184,185,186,187,188,189,190,191,
7042+ 192,193,194,195,196,197,198,199,
7043+ 200,201,202,203,204,205,206,207,
7044+ 208,209,210,211,212,213,214,215,
7045+ 216,217,218,219,220,221,222,223,
7046+ 224,225,226,227,228,229,230,231,
7047+ 232,233,234,235,236,237,238,239,
7048+ 240,241,242,243,244,245,246,247,
7049+ 248,249,250,251,252,253,254,255,
7050+
7051+/* This table is a case flipping table. */
7052+
7053+ 0, 1, 2, 3, 4, 5, 6, 7,
7054+ 8, 9, 10, 11, 12, 13, 14, 15,
7055+ 16, 17, 18, 19, 20, 21, 22, 23,
7056+ 24, 25, 26, 27, 28, 29, 30, 31,
7057+ 32, 33, 34, 35, 36, 37, 38, 39,
7058+ 40, 41, 42, 43, 44, 45, 46, 47,
7059+ 48, 49, 50, 51, 52, 53, 54, 55,
7060+ 56, 57, 58, 59, 60, 61, 62, 63,
7061+ 64, 97, 98, 99,100,101,102,103,
7062+ 104,105,106,107,108,109,110,111,
7063+ 112,113,114,115,116,117,118,119,
7064+ 120,121,122, 91, 92, 93, 94, 95,
7065+ 96, 65, 66, 67, 68, 69, 70, 71,
7066+ 72, 73, 74, 75, 76, 77, 78, 79,
7067+ 80, 81, 82, 83, 84, 85, 86, 87,
7068+ 88, 89, 90,123,124,125,126,127,
7069+ 128,129,130,131,132,133,134,135,
7070+ 136,137,138,139,140,141,142,143,
7071+ 144,145,146,147,148,149,150,151,
7072+ 152,153,154,155,156,157,158,159,
7073+ 160,161,162,163,164,165,166,167,
7074+ 168,169,170,171,172,173,174,175,
7075+ 176,177,178,179,180,181,182,183,
7076+ 184,185,186,187,188,189,190,191,
7077+ 192,193,194,195,196,197,198,199,
7078+ 200,201,202,203,204,205,206,207,
7079+ 208,209,210,211,212,213,214,215,
7080+ 216,217,218,219,220,221,222,223,
7081+ 224,225,226,227,228,229,230,231,
7082+ 232,233,234,235,236,237,238,239,
7083+ 240,241,242,243,244,245,246,247,
7084+ 248,249,250,251,252,253,254,255,
7085+
7086+/* This table contains bit maps for various character classes.
7087+Each map is 32 bytes long and the bits run from the least
7088+significant end of each byte. The classes that have their own
7089+maps are: space, xdigit, digit, upper, lower, word, graph
7090+print, punct, and cntrl. Other classes are built from combinations. */
7091+
7092+ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
7093+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7094+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7095+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7096+
7097+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
7098+ 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
7099+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7100+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7101+
7102+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
7103+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7104+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7105+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7106+
7107+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7108+ 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
7109+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7110+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7111+
7112+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7113+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
7114+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7115+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7116+
7117+ 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
7118+ 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
7119+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7120+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7121+
7122+ 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
7123+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
7124+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7125+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7126+
7127+ 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
7128+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
7129+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7130+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7131+
7132+ 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
7133+ 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
7134+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7135+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7136+
7137+ 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
7138+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
7139+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7140+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
7141+
7142+/* This table identifies various classes of character by individual bits:
7143+ 0x01 white space character
7144+ 0x02 letter
7145+ 0x04 decimal digit
7146+ 0x08 hexadecimal digit
7147+ 0x10 alphanumeric or '_'
7148+ 0x80 regular expression metacharacter or binary zero
7149+*/
7150+
7151+ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
7152+ 0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00, /* 8- 15 */
7153+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
7154+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
7155+ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
7156+ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
7157+ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
7158+ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
7159+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
7160+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
7161+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
7162+ 0x12,0x12,0x12,0x80,0x00,0x00,0x80,0x10, /* X - _ */
7163+ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
7164+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
7165+ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
7166+ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
7167+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
7168+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
7169+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
7170+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
7171+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
7172+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
7173+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
7174+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
7175+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
7176+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
7177+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
7178+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
7179+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
7180+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
7181+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
7182+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
7183+
7184+/* End of chartables.c */
7185Index: b/security/apparmor/module_interface.c
7186===================================================================
7187--- /dev/null
7188+++ b/security/apparmor/module_interface.c
7189@@ -0,0 +1,845 @@
7190+/*
7191+ * Copyright (C) 1998-2005 Novell/SUSE
7192+ *
7193+ * This program is free software; you can redistribute it and/or
7194+ * modify it under the terms of the GNU General Public License as
7195+ * published by the Free Software Foundation, version 2 of the
7196+ * License.
7197+ *
7198+ * AppArmor userspace policy interface
7199+ */
7200+
7201+#include <asm/unaligned.h>
7202+
7203+#include "apparmor.h"
7204+#include "inline.h"
7205+#include "module_interface.h"
7206+#include "match/match.h"
7207+
7208+/* aa_code defined in module_interface.h */
7209+
7210+const int aacode_datasize[] = { 1, 2, 4, 8, 2, 2, 4, 0, 0, 0, 0, 0, 0 };
7211+
7212+struct aa_taskreplace_data {
7213+ struct aaprofile *old_profile;
7214+ struct aaprofile *new_profile;
7215+};
7216+
7217+/* inlines must be forward of there use in newer version of gcc,
7218+ just forward declaring with a prototype won't work anymore */
7219+
7220+static inline void free_aa_entry(struct aa_entry *entry)
7221+{
7222+ if (entry) {
7223+ kfree(entry->filename);
7224+ aamatch_free(entry->extradata);
7225+ kfree(entry);
7226+ }
7227+}
7228+
7229+/**
7230+ * alloc_aa_entry - create new empty aa_entry
7231+ * This routine allocates, initializes, and returns a new aa_entry
7232+ * file entry structure. Structure is zeroed. Returns new structure on
7233+ * success, %NULL on failure.
7234+ */
7235+static inline struct aa_entry *alloc_aa_entry(void)
7236+{
7237+ struct aa_entry *entry;
7238+
7239+ AA_DEBUG("%s\n", __FUNCTION__);
7240+ entry = kzalloc(sizeof(struct aa_entry), GFP_KERNEL);
7241+ if (entry) {
7242+ int i;
7243+ INIT_LIST_HEAD(&entry->list);
7244+ for (i = 0; i <= POS_AA_FILE_MAX; i++) {
7245+ INIT_LIST_HEAD(&entry->listp[i]);
7246+ }
7247+ }
7248+ return entry;
7249+}
7250+
7251+/**
7252+ * free_aaprofile_rcu - rcu callback for free profiles
7253+ * @head: rcu_head struct of the profile whose reference is being put.
7254+ *
7255+ * the rcu callback routine, which delays the freeing of a profile when
7256+ * its last reference is put.
7257+ */
7258+static void free_aaprofile_rcu(struct rcu_head *head)
7259+{
7260+ struct aaprofile *p = container_of(head, struct aaprofile, rcu);
7261+ free_aaprofile(p);
7262+}
7263+
7264+/**
7265+ * task_remove - remove profile from a task's subdomain
7266+ * @sd: task's subdomain
7267+ *
7268+ * remove the active profile from a task's subdomain, switching the task
7269+ * to an unconfined state.
7270+ */
7271+static inline void task_remove(struct subdomain *sd)
7272+{
7273+ /* spin_lock(&sd_lock) held here */
7274+ AA_DEBUG("%s: removing profile from task %s(%d) profile %s active %s\n",
7275+ __FUNCTION__,
7276+ sd->task->comm,
7277+ sd->task->pid,
7278+ BASE_PROFILE(sd->active)->name,
7279+ sd->active->name);
7280+
7281+ aa_switch_unconfined(sd);
7282+}
7283+
7284+/** taskremove_iter - Iterator to unconfine subdomains which match cookie
7285+ * @sd: subdomain to consider for profile removal
7286+ * @cookie: pointer to the oldprofile which is being removed
7287+ *
7288+ * If the subdomain's active profile matches old_profile, then call
7289+ * task_remove() to remove the profile leaving the task (subdomain) unconfined.
7290+ */
7291+static int taskremove_iter(struct subdomain *sd, void *cookie)
7292+{
7293+ struct aaprofile *old_profile = (struct aaprofile *)cookie;
7294+ unsigned long flags;
7295+
7296+ spin_lock_irqsave(&sd_lock, flags);
7297+
7298+ if (__aa_is_confined(sd) && BASE_PROFILE(sd->active) == old_profile) {
7299+ task_remove(sd);
7300+ }
7301+
7302+ spin_unlock_irqrestore(&sd_lock, flags);
7303+
7304+ return 0;
7305+}
7306+
7307+/** task_replace - replace subdomain's current profile with a new profile
7308+ * @sd: subdomain to replace the profile on
7309+ * @new: new profile
7310+ *
7311+ * Replace a task's (subdomain's) active profile with a new profile. If
7312+ * task was in a hat then the new profile will also be in the equivalent
7313+ * hat in the new profile if it exists. If it doesn't exist the
7314+ * task will be placed in the special null_profile state.
7315+ */
7316+static inline void task_replace(struct subdomain *sd, struct aaprofile *new)
7317+{
7318+ AA_DEBUG("%s: replacing profile for task %s(%d) "
7319+ "profile=%s (%p) active=%s (%p)\n",
7320+ __FUNCTION__,
7321+ sd->task->comm, sd->task->pid,
7322+ BASE_PROFILE(sd->active)->name, BASE_PROFILE(sd->active),
7323+ sd->active->name, sd->active);
7324+
7325+ if (!sd->active)
7326+ goto out;
7327+
7328+ if (IN_SUBPROFILE(sd->active)) {
7329+ struct aaprofile *nactive;
7330+
7331+ /* The old profile was in a hat, check to see if the new
7332+ * profile has an equivalent hat */
7333+ nactive = __aa_find_profile(sd->active->name, &new->sub);
7334+
7335+ if (!nactive)
7336+ nactive = get_aaprofile(new->null_profile);
7337+
7338+ aa_switch(sd, nactive);
7339+ put_aaprofile(nactive);
7340+ } else {
7341+ aa_switch(sd, new);
7342+ }
7343+
7344+ out:
7345+ return;
7346+}
7347+
7348+/** taskreplace_iter - Iterator to replace a subdomain's profile
7349+ * @sd: subdomain to consider for profile replacement
7350+ * @cookie: pointer to the old profile which is being replaced.
7351+ *
7352+ * If the subdomain's active profile matches old_profile call
7353+ * task_replace() to replace with the subdomain's active profile with
7354+ * the new profile.
7355+ */
7356+static int taskreplace_iter(struct subdomain *sd, void *cookie)
7357+{
7358+ struct aa_taskreplace_data *data = (struct aa_taskreplace_data *)cookie;
7359+ unsigned long flags;
7360+
7361+ spin_lock_irqsave(&sd_lock, flags);
7362+
7363+ if (__aa_is_confined(sd) &&
7364+ BASE_PROFILE(sd->active) == data->old_profile)
7365+ task_replace(sd, data->new_profile);
7366+
7367+ spin_unlock_irqrestore(&sd_lock, flags);
7368+
7369+ return 0;
7370+}
7371+
7372+static inline int aa_inbounds(struct aa_ext *e, size_t size)
7373+{
7374+ return (e->pos + size <= e->end);
7375+}
7376+
7377+/**
7378+ * aaconvert - convert trailing values of serialized type codes
7379+ * @code: type code
7380+ * @dest: pointer to object to receive the converted value
7381+ * @src: pointer to value to convert
7382+ *
7383+ * for serialized type codes which have a trailing value, convert it
7384+ * and place it in @dest. If a code does not have a trailing value nop.
7385+ */
7386+static void aaconvert(enum aa_code code, void *dest, void *src)
7387+{
7388+ switch (code) {
7389+ case AA_U8:
7390+ *(u8 *)dest = *(u8 *) src;
7391+ break;
7392+ case AA_U16:
7393+ case AA_NAME:
7394+ case AA_DYN_STRING:
7395+ *(u16 *)dest = le16_to_cpu(get_unaligned((u16 *)src));
7396+ break;
7397+ case AA_U32:
7398+ case AA_STATIC_BLOB:
7399+ *(u32 *)dest = le32_to_cpu(get_unaligned((u32 *)src));
7400+ break;
7401+ case AA_U64:
7402+ *(u64 *)dest = le64_to_cpu(get_unaligned((u64 *)src));
7403+ break;
7404+ default:
7405+ /* nop - all other type codes do not have a trailing value */
7406+ ;
7407+ }
7408+}
7409+
7410+/**
7411+ * aa_is_X - check if the next element is of type X
7412+ * @e: serialized data extent information
7413+ * @code: type code
7414+ * @data: object located at @e->pos (of type @code) is written into @data
7415+ * if @data is non-null. if data is null it means skip this
7416+ * entry
7417+ * check to see if the next element in the serialized data stream is of type
7418+ * X and check that it is with in bounds, if so put the associated value in
7419+ * @data.
7420+ * return the size of bytes associated with the returned data
7421+ * for complex object like blob and string a pointer to the allocated
7422+ * data is returned in data, but the size of the blob or string is
7423+ * returned.
7424+ */
7425+static u32 aa_is_X(struct aa_ext *e, enum aa_code code, void *data)
7426+{
7427+ void *pos = e->pos;
7428+ int ret = 0;
7429+ if (!aa_inbounds(e, AA_CODE_BYTE + aacode_datasize[code]))
7430+ goto fail;
7431+ if (code != *(u8 *)e->pos)
7432+ goto out;
7433+ e->pos += AA_CODE_BYTE;
7434+ if (code == AA_NAME) {
7435+ u16 size;
7436+ /* name codes are followed by X bytes */
7437+ size = le16_to_cpu(get_unaligned((u16 *)e->pos));
7438+ if (!aa_inbounds(e, (size_t) size))
7439+ goto fail;
7440+ if (data)
7441+ *(u16 *)data = size;
7442+ e->pos += aacode_datasize[code];
7443+ ret = 1 + aacode_datasize[code];
7444+ } else if (code == AA_DYN_STRING) {
7445+ u16 size;
7446+ char *str;
7447+ /* strings codes are followed by X bytes */
7448+ size = le16_to_cpu(get_unaligned((u16 *)e->pos));
7449+ e->pos += aacode_datasize[code];
7450+ if (!aa_inbounds(e, (size_t) size))
7451+ goto fail;
7452+ if (data) {
7453+ * (char **)data = NULL;
7454+ str = kmalloc(size, GFP_KERNEL);
7455+ if (!str)
7456+ goto fail;
7457+ memcpy(str, e->pos, (size_t) size);
7458+ str[size-1] = '\0';
7459+ * (char **)data = str;
7460+ }
7461+ e->pos += size;
7462+ ret = size;
7463+ } else if (code == AA_STATIC_BLOB) {
7464+ u32 size;
7465+ /* blobs are followed by X bytes, that can be 2^32 */
7466+ size = le32_to_cpu(get_unaligned((u32 *)e->pos));
7467+ e->pos += aacode_datasize[code];
7468+ if (!aa_inbounds(e, (size_t) size))
7469+ goto fail;
7470+ if (data)
7471+ memcpy(data, e->pos, (size_t) size);
7472+ e->pos += size;
7473+ ret = size;
7474+ } else {
7475+ if (data)
7476+ aaconvert(code, data, e->pos);
7477+ e->pos += aacode_datasize[code];
7478+ ret = 1 + aacode_datasize[code];
7479+ }
7480+out:
7481+ return ret;
7482+fail:
7483+ e->pos = pos;
7484+ return 0;
7485+}
7486+
7487+/**
7488+ * aa_is_nameX - check is the next element is of type X with a name of @name
7489+ * @e: serialized data extent information
7490+ * @code: type code
7491+ * @data: location to store deserialized data if match isX criteria
7492+ * @name: name to match to the serialized element.
7493+ *
7494+ * check that the next serialized data element is of type X and has a tag
7495+ * name @name. If the code matches and name (if specified) matches then
7496+ * the packed data is unpacked into *data. (Note for strings this is the
7497+ * size, and the next data in the stream is the string data)
7498+ * returns %0 if either match failes
7499+ */
7500+static int aa_is_nameX(struct aa_ext *e, enum aa_code code, void *data,
7501+ const char *name)
7502+{
7503+ void *pos = e->pos;
7504+ u16 size;
7505+ u32 ret;
7506+ /* check for presence of a tagname, and if present name size
7507+ * AA_NAME tag value is a u16 */
7508+ if (aa_is_X(e, AA_NAME, &size)) {
7509+ /* if a name is specified it must match. otherwise skip tag */
7510+ if (name && ((strlen(name) != size-1) ||
7511+ strncmp(name, (char *)e->pos, (size_t)size-1)))
7512+ goto fail;
7513+ e->pos += size;
7514+ } else if (name) {
7515+ goto fail;
7516+ }
7517+
7518+ /* now check if data actually matches */
7519+ ret = aa_is_X(e, code, data);
7520+ if (!ret)
7521+ goto fail;
7522+ return ret;
7523+
7524+fail:
7525+ e->pos = pos;
7526+ return 0;
7527+}
7528+
7529+/* macro to wrap error case to make a block of reads look nicer */
7530+#define AA_READ_X(E, C, D, N) \
7531+ do { \
7532+ u32 __ret; \
7533+ __ret = aa_is_nameX((E), (C), (D), (N)); \
7534+ if (!__ret) \
7535+ goto fail; \
7536+ } while (0)
7537+
7538+/**
7539+ * aa_activate_net_entry - unpacked serialized net entries
7540+ * @e: serialized data extent information
7541+ *
7542+ * Ignore/skips net entries if they are present in the serialized data
7543+ * stream. Network confinement rules are currently unsupported but some
7544+ * user side tools can generate them so they are currently ignored.
7545+ */
7546+static inline int aa_activate_net_entry(struct aa_ext *e)
7547+{
7548+ AA_READ_X(e, AA_STRUCT, NULL, "ne");
7549+ AA_READ_X(e, AA_U32, NULL, NULL);
7550+ AA_READ_X(e, AA_U32, NULL, NULL);
7551+ AA_READ_X(e, AA_U32, NULL, NULL);
7552+ AA_READ_X(e, AA_U16, NULL, NULL);
7553+ AA_READ_X(e, AA_U16, NULL, NULL);
7554+ AA_READ_X(e, AA_U32, NULL, NULL);
7555+ AA_READ_X(e, AA_U32, NULL, NULL);
7556+ AA_READ_X(e, AA_U16, NULL, NULL);
7557+ AA_READ_X(e, AA_U16, NULL, NULL);
7558+ /* interface name is optional so just ignore return code */
7559+ aa_is_nameX(e, AA_DYN_STRING, NULL, NULL);
7560+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
7561+
7562+ return 1;
7563+fail:
7564+ return 0;
7565+}
7566+
7567+/**
7568+ * aa_activate_file_entry - unpack serialized file entry
7569+ * @e: serialized data extent information
7570+ *
7571+ * unpack the information used for a file ACL entry.
7572+ */
7573+static inline struct aa_entry *aa_activate_file_entry(struct aa_ext *e)
7574+{
7575+ struct aa_entry *entry = NULL;
7576+
7577+ if (!(entry = alloc_aa_entry()))
7578+ goto fail;
7579+
7580+ AA_READ_X(e, AA_STRUCT, NULL, "fe");
7581+ AA_READ_X(e, AA_DYN_STRING, &entry->filename, NULL);
7582+ AA_READ_X(e, AA_U32, &entry->mode, NULL);
7583+ AA_READ_X(e, AA_U32, &entry->type, NULL);
7584+
7585+ entry->extradata = aamatch_alloc(entry->type);
7586+ if (IS_ERR(entry->extradata)) {
7587+ entry->extradata = NULL;
7588+ goto fail;
7589+ }
7590+
7591+ if (entry->extradata &&
7592+ aamatch_serialize(entry->extradata, e, aa_is_nameX) != 0) {
7593+ goto fail;
7594+ }
7595+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
7596+
7597+ switch (entry->type) {
7598+ case aa_entry_literal:
7599+ AA_DEBUG("%s: %s [no pattern] mode=0x%x\n",
7600+ __FUNCTION__,
7601+ entry->filename,
7602+ entry->mode);
7603+ break;
7604+ case aa_entry_tailglob:
7605+ AA_DEBUG("%s: %s [tailglob] mode=0x%x\n",
7606+ __FUNCTION__,
7607+ entry->filename,
7608+ entry->mode);
7609+ break;
7610+ case aa_entry_pattern:
7611+ AA_DEBUG("%s: %s mode=0x%x\n",
7612+ __FUNCTION__,
7613+ entry->filename,
7614+ entry->mode);
7615+ break;
7616+ default:
7617+ AA_WARN("%s: INVALID entry_match_type %d\n",
7618+ __FUNCTION__,
7619+ (int)entry->type);
7620+ goto fail;
7621+ }
7622+
7623+ return entry;
7624+
7625+fail:
7626+ free_aa_entry(entry);
7627+ return NULL;
7628+}
7629+
7630+/**
7631+ * check_rule_and_add - check a file rule is valid and add to a profile
7632+ * @file_entry: file rule to add
7633+ * @profile: profile to add the rule to
7634+ * @message: error message returned if the addition failes.
7635+ *
7636+ * perform consistency check to ensure that a file rule entry is valid.
7637+ * If the rule is valid it is added to the profile.
7638+ */
7639+static inline int check_rule_and_add(struct aa_entry *file_entry,
7640+ struct aaprofile *profile,
7641+ const char **message)
7642+{
7643+ /* verify consistency of x, px, ix, ux for entry against
7644+ possible duplicates for this entry */
7645+ int mode = AA_EXEC_MODIFIER_MASK(file_entry->mode);
7646+ int i;
7647+
7648+ if (mode && !(AA_MAY_EXEC & file_entry->mode)) {
7649+ *message = "inconsistent rule, x modifiers without x";
7650+ goto out;
7651+ }
7652+
7653+ /* check that only 1 of the modifiers is set */
7654+ if (mode && (mode & (mode - 1))) {
7655+ *message = "inconsistent rule, multiple x modifiers";
7656+ goto out;
7657+ }
7658+
7659+ /* ix -> m (required so that target exec binary may map itself) */
7660+ if (mode & AA_EXEC_INHERIT)
7661+ file_entry->mode |= AA_EXEC_MMAP;
7662+
7663+ list_add(&file_entry->list, &profile->file_entry);
7664+ profile->num_file_entries++;
7665+
7666+ mode = file_entry->mode;
7667+
7668+ /* Handle partitioned lists
7669+ * Chain entries onto sublists based on individual
7670+ * permission bits. This allows more rapid searching.
7671+ */
7672+ for (i = 0; i <= POS_AA_FILE_MAX; i++) {
7673+ if (mode & (1 << i))
7674+ /* profile->file_entryp[i] initially set to
7675+ * NULL in alloc_aaprofile() */
7676+ list_add(&file_entry->listp[i],
7677+ &profile->file_entryp[i]);
7678+ }
7679+
7680+ return 1;
7681+
7682+out:
7683+ free_aa_entry(file_entry);
7684+ return 0;
7685+}
7686+
7687+#define AA_ENTRY_LIST(NAME) \
7688+ do { \
7689+ if (aa_is_nameX(e, AA_LIST, NULL, (NAME))) { \
7690+ rulename = ""; \
7691+ error_string = "Invalid file entry"; \
7692+ while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) { \
7693+ struct aa_entry *file_entry; \
7694+ file_entry = aa_activate_file_entry(e); \
7695+ if (!file_entry) \
7696+ goto fail; \
7697+ if (!check_rule_and_add(file_entry, profile, \
7698+ &error_string)) { \
7699+ rulename = file_entry->filename; \
7700+ goto fail; \
7701+ } \
7702+ } \
7703+ } \
7704+ } while (0)
7705+
7706+/**
7707+ * aa_activate_profile - unpack a serialized profile
7708+ * @e: serialized data extent information
7709+ * @error: error code returned if unpacking fails
7710+ */
7711+static struct aaprofile *aa_activate_profile(struct aa_ext *e, ssize_t *error)
7712+{
7713+ struct aaprofile *profile = NULL;
7714+ const char *rulename = "";
7715+ const char *error_string = "Invalid Profile";
7716+
7717+ *error = -EPROTO;
7718+
7719+ profile = alloc_aaprofile();
7720+ if (!profile) {
7721+ error_string = "Could not allocate profile";
7722+ *error = -ENOMEM;
7723+ goto fail;
7724+ }
7725+
7726+ /* check that we have the right struct being passed */
7727+ AA_READ_X(e, AA_STRUCT, NULL, "profile");
7728+ AA_READ_X(e, AA_DYN_STRING, &profile->name, NULL);
7729+
7730+ error_string = "Invalid flags";
7731+ /* per profile debug flags (debug, complain, audit) */
7732+ AA_READ_X(e, AA_STRUCT, NULL, "flags");
7733+ AA_READ_X(e, AA_U32, &(profile->flags.debug), NULL);
7734+ AA_READ_X(e, AA_U32, &(profile->flags.complain), NULL);
7735+ AA_READ_X(e, AA_U32, &(profile->flags.audit), NULL);
7736+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
7737+
7738+ error_string = "Invalid capabilities";
7739+ AA_READ_X(e, AA_U32, &(profile->capabilities), NULL);
7740+
7741+ /* get the file entries. */
7742+ AA_ENTRY_LIST("pgent"); /* pcre rules */
7743+ AA_ENTRY_LIST("sgent"); /* simple globs */
7744+ AA_ENTRY_LIST("fent"); /* regular file entries */
7745+
7746+ /* get the net entries */
7747+ if (aa_is_nameX(e, AA_LIST, NULL, "net")) {
7748+ error_string = "Invalid net entry";
7749+ while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
7750+ if (!aa_activate_net_entry(e))
7751+ goto fail;
7752+ }
7753+ }
7754+ rulename = "";
7755+
7756+ /* get subprofiles */
7757+ if (aa_is_nameX(e, AA_LIST, NULL, "hats")) {
7758+ error_string = "Invalid profile hat";
7759+ while (!aa_is_nameX(e, AA_LISTEND, NULL, NULL)) {
7760+ struct aaprofile *subprofile;
7761+ subprofile = aa_activate_profile(e, error);
7762+ if (!subprofile)
7763+ goto fail;
7764+ subprofile->parent = profile;
7765+ list_add(&subprofile->list, &profile->sub);
7766+ }
7767+ }
7768+
7769+ error_string = "Invalid end of profile";
7770+ AA_READ_X(e, AA_STRUCTEND, NULL, NULL);
7771+
7772+ return profile;
7773+
7774+fail:
7775+ AA_WARN("%s: %s %s in profile %s\n", INTERFACE_ID, rulename,
7776+ error_string, profile && profile->name ? profile->name
7777+ : "unknown");
7778+
7779+ if (profile) {
7780+ free_aaprofile(profile);
7781+ profile = NULL;
7782+ }
7783+
7784+ return NULL;
7785+}
7786+
7787+/**
7788+ * aa_activate_top_profile - unpack a serialized base profile
7789+ * @e: serialized data extent information
7790+ * @error: error code returned if unpacking fails
7791+ *
7792+ * check interface version unpack a profile and all its hats and patch
7793+ * in any extra information that the profile needs.
7794+ */
7795+static void *aa_activate_top_profile(struct aa_ext *e, ssize_t *error)
7796+{
7797+ struct aaprofile *profile = NULL;
7798+
7799+ /* get the interface version */
7800+ if (!aa_is_nameX(e, AA_U32, &e->version, "version")) {
7801+ AA_WARN("%s: version missing\n", INTERFACE_ID);
7802+ *error = -EPROTONOSUPPORT;
7803+ goto fail;
7804+ }
7805+
7806+ /* check that the interface version is currently supported */
7807+ if (e->version != 2) {
7808+ AA_WARN("%s: unsupported interface version (%d)\n",
7809+ INTERFACE_ID, e->version);
7810+ *error = -EPROTONOSUPPORT;
7811+ goto fail;
7812+ }
7813+
7814+ profile = aa_activate_profile(e, error);
7815+ if (!profile)
7816+ goto fail;
7817+
7818+ if (!list_empty(&profile->sub) || profile->flags.complain) {
7819+ if (attach_nullprofile(profile))
7820+ goto fail;
7821+ }
7822+ return profile;
7823+
7824+fail:
7825+ free_aaprofile(profile);
7826+ return NULL;
7827+}
7828+
7829+/**
7830+ * aa_file_prof_add - add a new profile to the profile list
7831+ * @data: serialized data stream
7832+ * @size: size of the serialized data stream
7833+ *
7834+ * unpack and add a profile to the profile list. Return %0 or error
7835+ */
7836+ssize_t aa_file_prof_add(void *data, size_t size)
7837+{
7838+ struct aaprofile *profile = NULL;
7839+
7840+ struct aa_ext e = {
7841+ .start = data,
7842+ .end = data + size,
7843+ .pos = data
7844+ };
7845+ ssize_t error;
7846+
7847+ profile = aa_activate_top_profile(&e, &error);
7848+ if (!profile) {
7849+ AA_DEBUG("couldn't activate profile\n");
7850+ goto out;
7851+ }
7852+
7853+ /* aa_activate_top_profile allocates profile with initial 1 count
7854+ * aa_profilelist_add transfers that ref to profile list without
7855+ * further incrementing
7856+ */
7857+ if (aa_profilelist_add(profile)) {
7858+ error = size;
7859+ } else {
7860+ AA_WARN("trying to add profile (%s) that already exists.\n",
7861+ profile->name);
7862+ put_aaprofile(profile);
7863+ error = -EEXIST;
7864+ }
7865+
7866+out:
7867+ return error;
7868+}
7869+
7870+/**
7871+ * aa_file_prof_repl - replace a profile on the profile list
7872+ * @udata: serialized data stream
7873+ * @size: size of the serialized data stream
7874+ *
7875+ * unpack and replace a profile on the profile list and uses of that profile
7876+ * by any subdomain. If the profile does not exist on the profile list
7877+ * it is added. Return %0 or error.
7878+ */
7879+ssize_t aa_file_prof_repl(void *udata, size_t size)
7880+{
7881+ struct aa_taskreplace_data data;
7882+ struct aa_ext e = {
7883+ .start = udata,
7884+ .end = udata + size,
7885+ .pos = udata
7886+ };
7887+
7888+ ssize_t error;
7889+
7890+ data.new_profile = aa_activate_top_profile(&e, &error);
7891+ if (!data.new_profile) {
7892+ AA_DEBUG("couldn't activate profile\n");
7893+ goto out;
7894+ }
7895+
7896+ /* Refcount on data.new_profile is 1 (aa_activate_top_profile).
7897+ *
7898+ * This reference will be inherited by aa_profilelist_replace for it's
7899+ * profile list reference but this isn't sufficient.
7900+ *
7901+ * Another replace (*for-same-profile*) may race us here.
7902+ * Task A calls aa_profilelist_replace(new_profile) and is interrupted.
7903+ * Task B old_profile = aa_profilelist_replace() will return task A's
7904+ * new_profile with the count of 1. If task B proceeeds to put this
7905+ * profile it will dissapear from under task A.
7906+ *
7907+ * Grab extra reference on new_profile to prevent this
7908+ */
7909+
7910+ get_aaprofile(data.new_profile);
7911+
7912+ data.old_profile = aa_profilelist_replace(data.new_profile);
7913+
7914+ /* If there was an old profile, find all currently executing tasks
7915+ * using this profile and replace the old profile with the new.
7916+ */
7917+ if (data.old_profile) {
7918+ AA_DEBUG("%s: try to replace profile (%p)%s\n",
7919+ __FUNCTION__,
7920+ data.old_profile,
7921+ data.old_profile->name);
7922+
7923+ aa_subdomainlist_iterate(taskreplace_iter, (void *)&data);
7924+
7925+ /* it's off global list, and we are done replacing */
7926+ put_aaprofile(data.old_profile);
7927+ }
7928+
7929+ /* release extra reference obtained above (race) */
7930+ put_aaprofile(data.new_profile);
7931+
7932+ error = size;
7933+
7934+out:
7935+ return error;
7936+}
7937+
7938+/**
7939+ * aa_file_prof_remove - remove a profile from the system
7940+ * @name: name of the profile to remove
7941+ * @size: size of the name
7942+ *
7943+ * remove a profile from the profile list and all subdomain references
7944+ * to said profile. Return %0 on success, else error.
7945+ */
7946+ssize_t aa_file_prof_remove(const char *name, size_t size)
7947+{
7948+ struct aaprofile *old_profile;
7949+
7950+ /* if the old profile exists it will be removed from the list and
7951+ * a reference is returned.
7952+ */
7953+ old_profile = aa_profilelist_remove(name);
7954+
7955+ if (old_profile) {
7956+ /* remove profile from any tasks using it */
7957+ aa_subdomainlist_iterate(taskremove_iter, (void *)old_profile);
7958+
7959+ /* drop reference obtained by aa_profilelist_remove */
7960+ put_aaprofile(old_profile);
7961+ } else {
7962+ AA_WARN("%s: trying to remove profile (%s) that "
7963+ "doesn't exist - skipping.\n", __FUNCTION__, name);
7964+ return -ENOENT;
7965+ }
7966+
7967+ return size;
7968+}
7969+
7970+/**
7971+ * free_aaprofile_kref - free aaprofile by kref (called by put_aaprofile)
7972+ * @kr: kref callback for freeing of a profile
7973+ */
7974+void free_aaprofile_kref(struct kref *kr)
7975+{
7976+ struct aaprofile *p=container_of(kr, struct aaprofile, count);
7977+
7978+ call_rcu(&p->rcu, free_aaprofile_rcu);
7979+}
7980+
7981+/**
7982+ * free_aaprofile - free aaprofile structure
7983+ * @profile: the profile to free
7984+ *
7985+ * free a profile, its file entries hats and null_profile. All references
7986+ * to the profile, its hats and null_profile must have been put.
7987+ * If the profile was referenced by a subdomain free_aaprofile should be
7988+ * called from an rcu callback routine.
7989+ */
7990+void free_aaprofile(struct aaprofile *profile)
7991+{
7992+ struct aa_entry *ent, *tmp;
7993+ struct aaprofile *p, *ptmp;
7994+
7995+ AA_DEBUG("%s(%p)\n", __FUNCTION__, profile);
7996+
7997+ if (!profile)
7998+ return;
7999+
8000+ /* profile is still on global profile list -- invalid */
8001+ if (!list_empty(&profile->list)) {
8002+ AA_ERROR("%s: internal error, "
8003+ "profile '%s' still on global list\n",
8004+ __FUNCTION__,
8005+ profile->name);
8006+ BUG();
8007+ }
8008+
8009+ list_for_each_entry_safe(ent, tmp, &profile->file_entry, list) {
8010+ if (ent->filename)
8011+ AA_DEBUG("freeing aa_entry: %p %s\n",
8012+ ent->filename, ent->filename);
8013+ list_del_init(&ent->list);
8014+ free_aa_entry(ent);
8015+ }
8016+
8017+ /* use free_aaprofile instead of put_aaprofile to destroy the
8018+ * null_profile, because the null_profile use the same reference
8019+ * counting as hats, ie. the count goes to the base profile.
8020+ */
8021+ free_aaprofile(profile->null_profile);
8022+ list_for_each_entry_safe(p, ptmp, &profile->sub, list) {
8023+ list_del_init(&p->list);
8024+ p->parent = NULL;
8025+ put_aaprofile(p);
8026+ }
8027+
8028+ if (profile->name) {
8029+ AA_DEBUG("%s: %s\n", __FUNCTION__, profile->name);
8030+ kfree(profile->name);
8031+ }
8032+
8033+ kfree(profile);
8034+}
8035Index: b/security/apparmor/module_interface.h
8036===================================================================
8037--- /dev/null
8038+++ b/security/apparmor/module_interface.h
8039@@ -0,0 +1,37 @@
8040+#ifndef __MODULEINTERFACE_H
8041+#define __MODULEINTERFACE_H
8042+
8043+/* Codes of the types of basic structures that are understood */
8044+#define AA_CODE_BYTE (sizeof(u8))
8045+#define INTERFACE_ID "INTERFACE"
8046+
8047+#define APPARMOR_INTERFACE_VERSION 2
8048+
8049+enum aa_code {
8050+ AA_U8,
8051+ AA_U16,
8052+ AA_U32,
8053+ AA_U64,
8054+ AA_NAME, /* same as string except it is items name */
8055+ AA_DYN_STRING,
8056+ AA_STATIC_BLOB,
8057+ AA_STRUCT,
8058+ AA_STRUCTEND,
8059+ AA_LIST,
8060+ AA_LISTEND,
8061+ AA_OFFSET,
8062+ AA_BAD
8063+};
8064+
8065+/* aa_ext tracks the kernel buffer and read position in it. The interface
8066+ * data is copied into a kernel buffer in apparmorfs and then handed off to
8067+ * the activate routines.
8068+ */
8069+struct aa_ext {
8070+ void *start;
8071+ void *end;
8072+ void *pos; /* pointer to current position in the buffer */
8073+ u32 version;
8074+};
8075+
8076+#endif /* __MODULEINTERFACE_H */
8077Index: b/security/apparmor/procattr.c
8078===================================================================
8079--- /dev/null
8080+++ b/security/apparmor/procattr.c
8081@@ -0,0 +1,332 @@
8082+/*
8083+ * Copyright (C) 2005 Novell/SUSE
8084+ *
8085+ * This program is free software; you can redistribute it and/or
8086+ * modify it under the terms of the GNU General Public License as
8087+ * published by the Free Software Foundation, version 2 of the
8088+ * License.
8089+ *
8090+ * AppArmor /proc/pid/attr handling
8091+ */
8092+
8093+/* for isspace */
8094+#include <linux/ctype.h>
8095+
8096+#include "apparmor.h"
8097+#include "inline.h"
8098+
8099+size_t aa_getprocattr(struct aaprofile *active, char *str, size_t size)
8100+{
8101+ int error = -EACCES; /* default to a perm denied */
8102+ size_t len;
8103+
8104+ if (active) {
8105+ size_t lena, lenm, lenp = 0;
8106+ const char *enforce_str = " (enforce)";
8107+ const char *complain_str = " (complain)";
8108+ const char *mode_str =
8109+ PROFILE_COMPLAIN(active) ? complain_str : enforce_str;
8110+
8111+ lenm = strlen(mode_str);
8112+
8113+ lena = strlen(active->name);
8114+
8115+ len = lena;
8116+ if (IN_SUBPROFILE(active)) {
8117+ lenp = strlen(BASE_PROFILE(active)->name);
8118+ len += (lenp + 1); /* +1 for ^ */
8119+ }
8120+ /* DONT null terminate strings we output via proc */
8121+ len += (lenm + 1); /* for \n */
8122+
8123+ if (len <= size) {
8124+ if (lenp) {
8125+ memcpy(str, BASE_PROFILE(active)->name,
8126+ lenp);
8127+ str += lenp;
8128+ *str++ = '^';
8129+ }
8130+
8131+ memcpy(str, active->name, lena);
8132+ str += lena;
8133+ memcpy(str, mode_str, lenm);
8134+ str += lenm;
8135+ *str++ = '\n';
8136+ error = len;
8137+ } else if (size == 0) {
8138+ error = len;
8139+ } else {
8140+ error = -ERANGE;
8141+ }
8142+ } else {
8143+ const char *unconstrained_str = "unconstrained\n";
8144+ len = strlen(unconstrained_str);
8145+
8146+ /* DONT null terminate strings we output via proc */
8147+ if (len <= size) {
8148+ memcpy(str, unconstrained_str, len);
8149+ error = len;
8150+ } else if (size == 0) {
8151+ error = len;
8152+ } else {
8153+ error = -ERANGE;
8154+ }
8155+ }
8156+
8157+ return error;
8158+
8159+}
8160+
8161+int aa_setprocattr_changehat(char *hatinfo, size_t infosize)
8162+{
8163+ int error = -EINVAL;
8164+ char *token = NULL, *hat, *smagic, *tmp;
8165+ u32 magic;
8166+ int rc, len, consumed;
8167+ unsigned long flags;
8168+
8169+ AA_DEBUG("%s: %p %zd\n", __FUNCTION__, hatinfo, infosize);
8170+
8171+ /* strip leading white space */
8172+ while (infosize && isspace(*hatinfo)) {
8173+ hatinfo++;
8174+ infosize--;
8175+ }
8176+
8177+ if (infosize == 0)
8178+ goto out;
8179+
8180+ /*
8181+ * Copy string to a new buffer so we can play with it
8182+ * It may be zero terminated but we add a trailing 0
8183+ * for 100% safety
8184+ */
8185+ token = kmalloc(infosize + 1, GFP_KERNEL);
8186+
8187+ if (!token) {
8188+ error = -ENOMEM;
8189+ goto out;
8190+ }
8191+
8192+ memcpy(token, hatinfo, infosize);
8193+ token[infosize] = 0;
8194+
8195+ /* error is INVAL until we have at least parsed something */
8196+ error = -EINVAL;
8197+
8198+ tmp = token;
8199+ while (*tmp && *tmp != '^') {
8200+ tmp++;
8201+ }
8202+
8203+ if (!*tmp || tmp == token) {
8204+ AA_WARN("%s: Invalid input '%s'\n", __FUNCTION__, token);
8205+ goto out;
8206+ }
8207+
8208+ /* split magic and hat into two strings */
8209+ *tmp = 0;
8210+ smagic = token;
8211+
8212+ /*
8213+ * Initially set consumed=strlen(magic), as if sscanf
8214+ * consumes all input via the %x it will not process the %n
8215+ * directive. Otherwise, if sscanf does not consume all the
8216+ * input it will process the %n and update consumed.
8217+ */
8218+ consumed = len = strlen(smagic);
8219+
8220+ rc = sscanf(smagic, "%x%n", &magic, &consumed);
8221+
8222+ if (rc != 1 || consumed != len) {
8223+ AA_WARN("%s: Invalid hex magic %s\n",
8224+ __FUNCTION__,
8225+ smagic);
8226+ goto out;
8227+ }
8228+
8229+ hat = tmp + 1;
8230+
8231+ if (!*hat)
8232+ hat = NULL;
8233+
8234+ if (!hat && !magic) {
8235+ AA_WARN("%s: Invalid input, NULL hat and NULL magic\n",
8236+ __FUNCTION__);
8237+ goto out;
8238+ }
8239+
8240+ AA_DEBUG("%s: Magic 0x%x Hat '%s'\n",
8241+ __FUNCTION__, magic, hat ? hat : NULL);
8242+
8243+ spin_lock_irqsave(&sd_lock, flags);
8244+ error = aa_change_hat(hat, magic);
8245+ spin_unlock_irqrestore(&sd_lock, flags);
8246+
8247+out:
8248+ if (token) {
8249+ memset(token, 0, infosize);
8250+ kfree(token);
8251+ }
8252+
8253+ return error;
8254+}
8255+
8256+int aa_setprocattr_setprofile(struct task_struct *p, char *profilename,
8257+ size_t profilesize)
8258+{
8259+ int error = -EINVAL;
8260+ struct aaprofile *profile = NULL;
8261+ struct subdomain *sd;
8262+ char *name = NULL;
8263+ unsigned long flags;
8264+
8265+ AA_DEBUG("%s: current %s(%d)\n",
8266+ __FUNCTION__, current->comm, current->pid);
8267+
8268+ /* strip leading white space */
8269+ while (profilesize && isspace(*profilename)) {
8270+ profilename++;
8271+ profilesize--;
8272+ }
8273+
8274+ if (profilesize == 0)
8275+ goto out;
8276+
8277+ /*
8278+ * Copy string to a new buffer so we guarantee it is zero
8279+ * terminated
8280+ */
8281+ name = kmalloc(profilesize + 1, GFP_KERNEL);
8282+
8283+ if (!name) {
8284+ error = -ENOMEM;
8285+ goto out;
8286+ }
8287+
8288+ strncpy(name, profilename, profilesize);
8289+ name[profilesize] = 0;
8290+
8291+ repeat:
8292+ if (strcmp(name, "unconstrained") != 0) {
8293+ profile = aa_profilelist_find(name);
8294+ if (!profile) {
8295+ AA_WARN("%s: Unable to switch task %s(%d) to profile"
8296+ "'%s'. No such profile.\n",
8297+ __FUNCTION__,
8298+ p->comm, p->pid,
8299+ name);
8300+
8301+ error = -EINVAL;
8302+ goto out;
8303+ }
8304+ }
8305+
8306+ spin_lock_irqsave(&sd_lock, flags);
8307+
8308+ sd = AA_SUBDOMAIN(p->security);
8309+
8310+ /* switch to unconstrained */
8311+ if (!profile) {
8312+ if (__aa_is_confined(sd)) {
8313+ AA_WARN("%s: Unconstraining task %s(%d) "
8314+ "profile %s active %s\n",
8315+ __FUNCTION__,
8316+ p->comm, p->pid,
8317+ BASE_PROFILE(sd->active)->name,
8318+ sd->active->name);
8319+
8320+ aa_switch_unconfined(sd);
8321+ } else {
8322+ AA_WARN("%s: task %s(%d) "
8323+ "is already unconstrained\n",
8324+ __FUNCTION__, p->comm, p->pid);
8325+ }
8326+ } else {
8327+ if (!sd) {
8328+ /* this task was created before module was
8329+ * loaded, allocate a subdomain
8330+ */
8331+ AA_WARN("%s: task %s(%d) has no subdomain\n",
8332+ __FUNCTION__, p->comm, p->pid);
8333+
8334+ /* unlock so we can safely GFP_KERNEL */
8335+ spin_unlock_irqrestore(&sd_lock, flags);
8336+
8337+ sd = alloc_subdomain(p);
8338+ if (!sd) {
8339+ AA_WARN("%s: Unable to allocate subdomain for "
8340+ "task %s(%d). Cannot confine task to "
8341+ "profile %s\n",
8342+ __FUNCTION__,
8343+ p->comm, p->pid,
8344+ name);
8345+
8346+ error = -ENOMEM;
8347+ put_aaprofile(profile);
8348+
8349+ goto out;
8350+ }
8351+
8352+ spin_lock_irqsave(&sd_lock, flags);
8353+ if (!AA_SUBDOMAIN(p->security)) {
8354+ p->security = sd;
8355+ } else { /* race */
8356+ free_subdomain(sd);
8357+ sd = AA_SUBDOMAIN(p->security);
8358+ }
8359+ }
8360+
8361+ /* ensure the profile hasn't been replaced */
8362+
8363+ if (unlikely(profile->isstale)) {
8364+ WARN_ON(profile == null_complain_profile);
8365+
8366+ /* drop refcnt obtained from earlier get_aaprofile */
8367+ put_aaprofile(profile);
8368+ profile = aa_profilelist_find(name);
8369+
8370+ if (!profile) {
8371+ /* Race, profile was removed. */
8372+ spin_unlock_irqrestore(&sd_lock, flags);
8373+ goto repeat;
8374+ }
8375+ }
8376+
8377+ /* we do not do a normal task replace since we are not
8378+ * replacing with the same profile.
8379+ * If existing process is in a hat, it will be moved
8380+ * into the new parent profile, even if this new
8381+ * profile has a identical named hat.
8382+ */
8383+
8384+ AA_WARN("%s: Switching task %s(%d) "
8385+ "profile %s active %s to new profile %s\n",
8386+ __FUNCTION__,
8387+ p->comm, p->pid,
8388+ sd->active ? BASE_PROFILE(sd->active)->name :
8389+ "unconstrained",
8390+ sd->active ? sd->active->name : "unconstrained",
8391+ name);
8392+
8393+ aa_switch(sd, profile);
8394+
8395+ put_aaprofile(profile); /* drop ref we obtained above
8396+ * from aa_profilelist_find
8397+ */
8398+
8399+ /* Reset magic in case we were in a subhat before
8400+ * This is the only case where we zero the magic after
8401+ * calling aa_switch
8402+ */
8403+ sd->hat_magic = 0;
8404+ }
8405+
8406+ spin_unlock_irqrestore(&sd_lock, flags);
8407+
8408+ error = 0;
8409+out:
8410+ kfree(name);
8411+
8412+ return error;
8413+}
8414Index: b/security/apparmor/shared.h
8415===================================================================
8416--- /dev/null
8417+++ b/security/apparmor/shared.h
8418@@ -0,0 +1,46 @@
8419+/*
8420+ * Copyright (C) 2000, 2001, 2004, 2005 Novell/SUSE
8421+ *
8422+ * Immunix AppArmor LSM
8423+ *
8424+ * This program is free software; you can redistribute it and/or
8425+ * modify it under the terms of the GNU General Public License as
8426+ * published by the Free Software Foundation, version 2 of the
8427+ * License.
8428+ */
8429+
8430+#ifndef _SHARED_H
8431+#define _SHARED_H
8432+
8433+/* start of system offsets */
8434+#define POS_AA_FILE_MIN 0
8435+#define POS_AA_MAY_EXEC POS_AA_FILE_MIN
8436+#define POS_AA_MAY_WRITE (POS_AA_MAY_EXEC + 1)
8437+#define POS_AA_MAY_READ (POS_AA_MAY_WRITE + 1)
8438+#define POS_AA_MAY_APPEND (POS_AA_MAY_READ + 1)
8439+/* end of system offsets */
8440+
8441+#define POS_AA_MAY_LINK (POS_AA_MAY_APPEND + 1)
8442+#define POS_AA_EXEC_INHERIT (POS_AA_MAY_LINK + 1)
8443+#define POS_AA_EXEC_UNCONSTRAINED (POS_AA_EXEC_INHERIT + 1)
8444+#define POS_AA_EXEC_PROFILE (POS_AA_EXEC_UNCONSTRAINED + 1)
8445+#define POS_AA_EXEC_MMAP (POS_AA_EXEC_PROFILE + 1)
8446+#define POS_AA_EXEC_UNSAFE (POS_AA_EXEC_MMAP + 1)
8447+#define POS_AA_FILE_MAX POS_AA_EXEC_UNSAFE
8448+
8449+/* Modeled after MAY_READ, MAY_WRITE, MAY_EXEC def'ns */
8450+#define AA_MAY_EXEC (0x01 << POS_AA_MAY_EXEC)
8451+#define AA_MAY_WRITE (0x01 << POS_AA_MAY_WRITE)
8452+#define AA_MAY_READ (0x01 << POS_AA_MAY_READ)
8453+#define AA_MAY_LINK (0x01 << POS_AA_MAY_LINK)
8454+#define AA_EXEC_INHERIT (0x01 << POS_AA_EXEC_INHERIT)
8455+#define AA_EXEC_UNCONSTRAINED (0x01 << POS_AA_EXEC_UNCONSTRAINED)
8456+#define AA_EXEC_PROFILE (0x01 << POS_AA_EXEC_PROFILE)
8457+#define AA_EXEC_MMAP (0x01 << POS_AA_EXEC_MMAP)
8458+#define AA_EXEC_UNSAFE (0x01 << POS_AA_EXEC_UNSAFE)
8459+
8460+#define AA_EXEC_MODIFIERS (AA_EXEC_INHERIT | \
8461+ AA_EXEC_UNCONSTRAINED | \
8462+ AA_EXEC_PROFILE)
8463+
8464+#endif /* _SHARED_H */
This page took 0.977279 seconds and 4 git commands to generate.