xref: /linux/security/apparmor/apparmorfs.c (revision 29b3822f1e132aa0f115f69730d6e4182df153d4)
1 /*
2  * AppArmor security module
3  *
4  * This file contains AppArmor /sys/kernel/security/apparmor interface functions
5  *
6  * Copyright (C) 1998-2008 Novell/SUSE
7  * Copyright 2009-2010 Canonical Ltd.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation, version 2 of the
12  * License.
13  */
14 
15 #include <linux/ctype.h>
16 #include <linux/security.h>
17 #include <linux/vmalloc.h>
18 #include <linux/module.h>
19 #include <linux/seq_file.h>
20 #include <linux/uaccess.h>
21 #include <linux/namei.h>
22 #include <linux/capability.h>
23 #include <linux/rcupdate.h>
24 
25 #include "include/apparmor.h"
26 #include "include/apparmorfs.h"
27 #include "include/audit.h"
28 #include "include/context.h"
29 #include "include/policy.h"
30 #include "include/resource.h"
31 
32 /**
33  * aa_mangle_name - mangle a profile name to std profile layout form
34  * @name: profile name to mangle  (NOT NULL)
35  * @target: buffer to store mangled name, same length as @name (MAYBE NULL)
36  *
37  * Returns: length of mangled name
38  */
39 static int mangle_name(char *name, char *target)
40 {
41 	char *t = target;
42 
43 	while (*name == '/' || *name == '.')
44 		name++;
45 
46 	if (target) {
47 		for (; *name; name++) {
48 			if (*name == '/')
49 				*(t)++ = '.';
50 			else if (isspace(*name))
51 				*(t)++ = '_';
52 			else if (isalnum(*name) || strchr("._-", *name))
53 				*(t)++ = *name;
54 		}
55 
56 		*t = 0;
57 	} else {
58 		int len = 0;
59 		for (; *name; name++) {
60 			if (isalnum(*name) || isspace(*name) ||
61 			    strchr("/._-", *name))
62 				len++;
63 		}
64 
65 		return len;
66 	}
67 
68 	return t - target;
69 }
70 
71 /**
72  * aa_simple_write_to_buffer - common routine for getting policy from user
73  * @op: operation doing the user buffer copy
74  * @userbuf: user buffer to copy data from  (NOT NULL)
75  * @alloc_size: size of user buffer (REQUIRES: @alloc_size >= @copy_size)
76  * @copy_size: size of data to copy from user buffer
77  * @pos: position write is at in the file (NOT NULL)
78  *
79  * Returns: kernel buffer containing copy of user buffer data or an
80  *          ERR_PTR on failure.
81  */
82 static char *aa_simple_write_to_buffer(int op, const char __user *userbuf,
83 				       size_t alloc_size, size_t copy_size,
84 				       loff_t *pos)
85 {
86 	char *data;
87 
88 	BUG_ON(copy_size > alloc_size);
89 
90 	if (*pos != 0)
91 		/* only writes from pos 0, that is complete writes */
92 		return ERR_PTR(-ESPIPE);
93 
94 	/*
95 	 * Don't allow profile load/replace/remove from profiles that don't
96 	 * have CAP_MAC_ADMIN
97 	 */
98 	if (!aa_may_manage_policy(op))
99 		return ERR_PTR(-EACCES);
100 
101 	/* freed by caller to simple_write_to_buffer */
102 	data = kvmalloc(alloc_size);
103 	if (data == NULL)
104 		return ERR_PTR(-ENOMEM);
105 
106 	if (copy_from_user(data, userbuf, copy_size)) {
107 		kvfree(data);
108 		return ERR_PTR(-EFAULT);
109 	}
110 
111 	return data;
112 }
113 
114 
115 /* .load file hook fn to load policy */
116 static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
117 			    loff_t *pos)
118 {
119 	char *data;
120 	ssize_t error;
121 
122 	data = aa_simple_write_to_buffer(OP_PROF_LOAD, buf, size, size, pos);
123 
124 	error = PTR_ERR(data);
125 	if (!IS_ERR(data)) {
126 		error = aa_replace_profiles(data, size, PROF_ADD);
127 		kvfree(data);
128 	}
129 
130 	return error;
131 }
132 
133 static const struct file_operations aa_fs_profile_load = {
134 	.write = profile_load,
135 	.llseek = default_llseek,
136 };
137 
138 /* .replace file hook fn to load and/or replace policy */
139 static ssize_t profile_replace(struct file *f, const char __user *buf,
140 			       size_t size, loff_t *pos)
141 {
142 	char *data;
143 	ssize_t error;
144 
145 	data = aa_simple_write_to_buffer(OP_PROF_REPL, buf, size, size, pos);
146 	error = PTR_ERR(data);
147 	if (!IS_ERR(data)) {
148 		error = aa_replace_profiles(data, size, PROF_REPLACE);
149 		kvfree(data);
150 	}
151 
152 	return error;
153 }
154 
155 static const struct file_operations aa_fs_profile_replace = {
156 	.write = profile_replace,
157 	.llseek = default_llseek,
158 };
159 
160 /* .remove file hook fn to remove loaded policy */
161 static ssize_t profile_remove(struct file *f, const char __user *buf,
162 			      size_t size, loff_t *pos)
163 {
164 	char *data;
165 	ssize_t error;
166 
167 	/*
168 	 * aa_remove_profile needs a null terminated string so 1 extra
169 	 * byte is allocated and the copied data is null terminated.
170 	 */
171 	data = aa_simple_write_to_buffer(OP_PROF_RM, buf, size + 1, size, pos);
172 
173 	error = PTR_ERR(data);
174 	if (!IS_ERR(data)) {
175 		data[size] = 0;
176 		error = aa_remove_profiles(data, size);
177 		kvfree(data);
178 	}
179 
180 	return error;
181 }
182 
183 static const struct file_operations aa_fs_profile_remove = {
184 	.write = profile_remove,
185 	.llseek = default_llseek,
186 };
187 
188 static int aa_fs_seq_show(struct seq_file *seq, void *v)
189 {
190 	struct aa_fs_entry *fs_file = seq->private;
191 
192 	if (!fs_file)
193 		return 0;
194 
195 	switch (fs_file->v_type) {
196 	case AA_FS_TYPE_BOOLEAN:
197 		seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
198 		break;
199 	case AA_FS_TYPE_STRING:
200 		seq_printf(seq, "%s\n", fs_file->v.string);
201 		break;
202 	case AA_FS_TYPE_U64:
203 		seq_printf(seq, "%#08lx\n", fs_file->v.u64);
204 		break;
205 	default:
206 		/* Ignore unpritable entry types. */
207 		break;
208 	}
209 
210 	return 0;
211 }
212 
213 static int aa_fs_seq_open(struct inode *inode, struct file *file)
214 {
215 	return single_open(file, aa_fs_seq_show, inode->i_private);
216 }
217 
218 const struct file_operations aa_fs_seq_file_ops = {
219 	.owner		= THIS_MODULE,
220 	.open		= aa_fs_seq_open,
221 	.read		= seq_read,
222 	.llseek		= seq_lseek,
223 	.release	= single_release,
224 };
225 
226 static int aa_fs_seq_profile_open(struct inode *inode, struct file *file,
227 				  int (*show)(struct seq_file *, void *))
228 {
229 	struct aa_replacedby *r = aa_get_replacedby(inode->i_private);
230 	int error = single_open(file, show, r);
231 
232 	if (error) {
233 		file->private_data = NULL;
234 		aa_put_replacedby(r);
235 	}
236 
237 	return error;
238 }
239 
240 static int aa_fs_seq_profile_release(struct inode *inode, struct file *file)
241 {
242 	struct seq_file *seq = (struct seq_file *) file->private_data;
243 	if (seq)
244 		aa_put_replacedby(seq->private);
245 	return single_release(inode, file);
246 }
247 
248 static int aa_fs_seq_profname_show(struct seq_file *seq, void *v)
249 {
250 	struct aa_replacedby *r = seq->private;
251 	struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
252 	seq_printf(seq, "%s\n", profile->base.name);
253 	aa_put_profile(profile);
254 
255 	return 0;
256 }
257 
258 static int aa_fs_seq_profname_open(struct inode *inode, struct file *file)
259 {
260 	return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profname_show);
261 }
262 
263 static const struct file_operations aa_fs_profname_fops = {
264 	.owner		= THIS_MODULE,
265 	.open		= aa_fs_seq_profname_open,
266 	.read		= seq_read,
267 	.llseek		= seq_lseek,
268 	.release	= aa_fs_seq_profile_release,
269 };
270 
271 static int aa_fs_seq_profmode_show(struct seq_file *seq, void *v)
272 {
273 	struct aa_replacedby *r = seq->private;
274 	struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
275 	seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
276 	aa_put_profile(profile);
277 
278 	return 0;
279 }
280 
281 static int aa_fs_seq_profmode_open(struct inode *inode, struct file *file)
282 {
283 	return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profmode_show);
284 }
285 
286 static const struct file_operations aa_fs_profmode_fops = {
287 	.owner		= THIS_MODULE,
288 	.open		= aa_fs_seq_profmode_open,
289 	.read		= seq_read,
290 	.llseek		= seq_lseek,
291 	.release	= aa_fs_seq_profile_release,
292 };
293 
294 static int aa_fs_seq_profattach_show(struct seq_file *seq, void *v)
295 {
296 	struct aa_replacedby *r = seq->private;
297 	struct aa_profile *profile = aa_get_profile_rcu(&r->profile);
298 	if (profile->attach)
299 		seq_printf(seq, "%s\n", profile->attach);
300 	else if (profile->xmatch)
301 		seq_puts(seq, "<unknown>\n");
302 	else
303 		seq_printf(seq, "%s\n", profile->base.name);
304 	aa_put_profile(profile);
305 
306 	return 0;
307 }
308 
309 static int aa_fs_seq_profattach_open(struct inode *inode, struct file *file)
310 {
311 	return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profattach_show);
312 }
313 
314 static const struct file_operations aa_fs_profattach_fops = {
315 	.owner		= THIS_MODULE,
316 	.open		= aa_fs_seq_profattach_open,
317 	.read		= seq_read,
318 	.llseek		= seq_lseek,
319 	.release	= aa_fs_seq_profile_release,
320 };
321 
322 /** fns to setup dynamic per profile/namespace files **/
323 void __aa_fs_profile_rmdir(struct aa_profile *profile)
324 {
325 	struct aa_profile *child;
326 	int i;
327 
328 	if (!profile)
329 		return;
330 
331 	list_for_each_entry(child, &profile->base.profiles, base.list)
332 		__aa_fs_profile_rmdir(child);
333 
334 	for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) {
335 		struct aa_replacedby *r;
336 		if (!profile->dents[i])
337 			continue;
338 
339 		r = profile->dents[i]->d_inode->i_private;
340 		securityfs_remove(profile->dents[i]);
341 		aa_put_replacedby(r);
342 		profile->dents[i] = NULL;
343 	}
344 }
345 
346 void __aa_fs_profile_migrate_dents(struct aa_profile *old,
347 				   struct aa_profile *new)
348 {
349 	int i;
350 
351 	for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
352 		new->dents[i] = old->dents[i];
353 		old->dents[i] = NULL;
354 	}
355 }
356 
357 static struct dentry *create_profile_file(struct dentry *dir, const char *name,
358 					  struct aa_profile *profile,
359 					  const struct file_operations *fops)
360 {
361 	struct aa_replacedby *r = aa_get_replacedby(profile->replacedby);
362 	struct dentry *dent;
363 
364 	dent = securityfs_create_file(name, S_IFREG | 0444, dir, r, fops);
365 	if (IS_ERR(dent))
366 		aa_put_replacedby(r);
367 
368 	return dent;
369 }
370 
371 /* requires lock be held */
372 int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
373 {
374 	struct aa_profile *child;
375 	struct dentry *dent = NULL, *dir;
376 	int error;
377 
378 	if (!parent) {
379 		struct aa_profile *p;
380 		p = aa_deref_parent(profile);
381 		dent = prof_dir(p);
382 		/* adding to parent that previously didn't have children */
383 		dent = securityfs_create_dir("profiles", dent);
384 		if (IS_ERR(dent))
385 			goto fail;
386 		prof_child_dir(p) = parent = dent;
387 	}
388 
389 	if (!profile->dirname) {
390 		int len, id_len;
391 		len = mangle_name(profile->base.name, NULL);
392 		id_len = snprintf(NULL, 0, ".%ld", profile->ns->uniq_id);
393 
394 		profile->dirname = kmalloc(len + id_len + 1, GFP_KERNEL);
395 		if (!profile->dirname)
396 			goto fail;
397 
398 		mangle_name(profile->base.name, profile->dirname);
399 		sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++);
400 	}
401 
402 	dent = securityfs_create_dir(profile->dirname, parent);
403 	if (IS_ERR(dent))
404 		goto fail;
405 	prof_dir(profile) = dir = dent;
406 
407 	dent = create_profile_file(dir, "name", profile, &aa_fs_profname_fops);
408 	if (IS_ERR(dent))
409 		goto fail;
410 	profile->dents[AAFS_PROF_NAME] = dent;
411 
412 	dent = create_profile_file(dir, "mode", profile, &aa_fs_profmode_fops);
413 	if (IS_ERR(dent))
414 		goto fail;
415 	profile->dents[AAFS_PROF_MODE] = dent;
416 
417 	dent = create_profile_file(dir, "attach", profile,
418 				   &aa_fs_profattach_fops);
419 	if (IS_ERR(dent))
420 		goto fail;
421 	profile->dents[AAFS_PROF_ATTACH] = dent;
422 
423 	list_for_each_entry(child, &profile->base.profiles, base.list) {
424 		error = __aa_fs_profile_mkdir(child, prof_child_dir(profile));
425 		if (error)
426 			goto fail2;
427 	}
428 
429 	return 0;
430 
431 fail:
432 	error = PTR_ERR(dent);
433 
434 fail2:
435 	__aa_fs_profile_rmdir(profile);
436 
437 	return error;
438 }
439 
440 void __aa_fs_namespace_rmdir(struct aa_namespace *ns)
441 {
442 	struct aa_namespace *sub;
443 	struct aa_profile *child;
444 	int i;
445 
446 	if (!ns)
447 		return;
448 
449 	list_for_each_entry(child, &ns->base.profiles, base.list)
450 		__aa_fs_profile_rmdir(child);
451 
452 	list_for_each_entry(sub, &ns->sub_ns, base.list) {
453 		mutex_lock(&sub->lock);
454 		__aa_fs_namespace_rmdir(sub);
455 		mutex_unlock(&sub->lock);
456 	}
457 
458 	for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
459 		securityfs_remove(ns->dents[i]);
460 		ns->dents[i] = NULL;
461 	}
462 }
463 
464 int __aa_fs_namespace_mkdir(struct aa_namespace *ns, struct dentry *parent,
465 			    const char *name)
466 {
467 	struct aa_namespace *sub;
468 	struct aa_profile *child;
469 	struct dentry *dent, *dir;
470 	int error;
471 
472 	if (!name)
473 		name = ns->base.name;
474 
475 	dent = securityfs_create_dir(name, parent);
476 	if (IS_ERR(dent))
477 		goto fail;
478 	ns_dir(ns) = dir = dent;
479 
480 	dent = securityfs_create_dir("profiles", dir);
481 	if (IS_ERR(dent))
482 		goto fail;
483 	ns_subprofs_dir(ns) = dent;
484 
485 	dent = securityfs_create_dir("namespaces", dir);
486 	if (IS_ERR(dent))
487 		goto fail;
488 	ns_subns_dir(ns) = dent;
489 
490 	list_for_each_entry(child, &ns->base.profiles, base.list) {
491 		error = __aa_fs_profile_mkdir(child, ns_subprofs_dir(ns));
492 		if (error)
493 			goto fail2;
494 	}
495 
496 	list_for_each_entry(sub, &ns->sub_ns, base.list) {
497 		mutex_lock(&sub->lock);
498 		error = __aa_fs_namespace_mkdir(sub, ns_subns_dir(ns), NULL);
499 		mutex_unlock(&sub->lock);
500 		if (error)
501 			goto fail2;
502 	}
503 
504 	return 0;
505 
506 fail:
507 	error = PTR_ERR(dent);
508 
509 fail2:
510 	__aa_fs_namespace_rmdir(ns);
511 
512 	return error;
513 }
514 
515 
516 #define list_entry_next(pos, member) \
517 	list_entry(pos->member.next, typeof(*pos), member)
518 #define list_entry_is_head(pos, head, member) (&pos->member == (head))
519 
520 /**
521  * __next_namespace - find the next namespace to list
522  * @root: root namespace to stop search at (NOT NULL)
523  * @ns: current ns position (NOT NULL)
524  *
525  * Find the next namespace from @ns under @root and handle all locking needed
526  * while switching current namespace.
527  *
528  * Returns: next namespace or NULL if at last namespace under @root
529  * Requires: ns->parent->lock to be held
530  * NOTE: will not unlock root->lock
531  */
532 static struct aa_namespace *__next_namespace(struct aa_namespace *root,
533 					     struct aa_namespace *ns)
534 {
535 	struct aa_namespace *parent, *next;
536 
537 	/* is next namespace a child */
538 	if (!list_empty(&ns->sub_ns)) {
539 		next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
540 		mutex_lock(&next->lock);
541 		return next;
542 	}
543 
544 	/* check if the next ns is a sibling, parent, gp, .. */
545 	parent = ns->parent;
546 	while (parent) {
547 		mutex_unlock(&ns->lock);
548 		next = list_entry_next(ns, base.list);
549 		if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
550 			mutex_lock(&next->lock);
551 			return next;
552 		}
553 		if (parent == root)
554 			return NULL;
555 		ns = parent;
556 		parent = parent->parent;
557 	}
558 
559 	return NULL;
560 }
561 
562 /**
563  * __first_profile - find the first profile in a namespace
564  * @root: namespace that is root of profiles being displayed (NOT NULL)
565  * @ns: namespace to start in   (NOT NULL)
566  *
567  * Returns: unrefcounted profile or NULL if no profile
568  * Requires: profile->ns.lock to be held
569  */
570 static struct aa_profile *__first_profile(struct aa_namespace *root,
571 					  struct aa_namespace *ns)
572 {
573 	for (; ns; ns = __next_namespace(root, ns)) {
574 		if (!list_empty(&ns->base.profiles))
575 			return list_first_entry(&ns->base.profiles,
576 						struct aa_profile, base.list);
577 	}
578 	return NULL;
579 }
580 
581 /**
582  * __next_profile - step to the next profile in a profile tree
583  * @profile: current profile in tree (NOT NULL)
584  *
585  * Perform a depth first traversal on the profile tree in a namespace
586  *
587  * Returns: next profile or NULL if done
588  * Requires: profile->ns.lock to be held
589  */
590 static struct aa_profile *__next_profile(struct aa_profile *p)
591 {
592 	struct aa_profile *parent;
593 	struct aa_namespace *ns = p->ns;
594 
595 	/* is next profile a child */
596 	if (!list_empty(&p->base.profiles))
597 		return list_first_entry(&p->base.profiles, typeof(*p),
598 					base.list);
599 
600 	/* is next profile a sibling, parent sibling, gp, sibling, .. */
601 	parent = rcu_dereference_protected(p->parent,
602 					   mutex_is_locked(&p->ns->lock));
603 	while (parent) {
604 		p = list_entry_next(p, base.list);
605 		if (!list_entry_is_head(p, &parent->base.profiles, base.list))
606 			return p;
607 		p = parent;
608 		parent = rcu_dereference_protected(parent->parent,
609 					    mutex_is_locked(&parent->ns->lock));
610 	}
611 
612 	/* is next another profile in the namespace */
613 	p = list_entry_next(p, base.list);
614 	if (!list_entry_is_head(p, &ns->base.profiles, base.list))
615 		return p;
616 
617 	return NULL;
618 }
619 
620 /**
621  * next_profile - step to the next profile in where ever it may be
622  * @root: root namespace  (NOT NULL)
623  * @profile: current profile  (NOT NULL)
624  *
625  * Returns: next profile or NULL if there isn't one
626  */
627 static struct aa_profile *next_profile(struct aa_namespace *root,
628 				       struct aa_profile *profile)
629 {
630 	struct aa_profile *next = __next_profile(profile);
631 	if (next)
632 		return next;
633 
634 	/* finished all profiles in namespace move to next namespace */
635 	return __first_profile(root, __next_namespace(root, profile->ns));
636 }
637 
638 /**
639  * p_start - start a depth first traversal of profile tree
640  * @f: seq_file to fill
641  * @pos: current position
642  *
643  * Returns: first profile under current namespace or NULL if none found
644  *
645  * acquires first ns->lock
646  */
647 static void *p_start(struct seq_file *f, loff_t *pos)
648 {
649 	struct aa_profile *profile = NULL;
650 	struct aa_namespace *root = aa_current_profile()->ns;
651 	loff_t l = *pos;
652 	f->private = aa_get_namespace(root);
653 
654 
655 	/* find the first profile */
656 	mutex_lock(&root->lock);
657 	profile = __first_profile(root, root);
658 
659 	/* skip to position */
660 	for (; profile && l > 0; l--)
661 		profile = next_profile(root, profile);
662 
663 	return profile;
664 }
665 
666 /**
667  * p_next - read the next profile entry
668  * @f: seq_file to fill
669  * @p: profile previously returned
670  * @pos: current position
671  *
672  * Returns: next profile after @p or NULL if none
673  *
674  * may acquire/release locks in namespace tree as necessary
675  */
676 static void *p_next(struct seq_file *f, void *p, loff_t *pos)
677 {
678 	struct aa_profile *profile = p;
679 	struct aa_namespace *ns = f->private;
680 	(*pos)++;
681 
682 	return next_profile(ns, profile);
683 }
684 
685 /**
686  * p_stop - stop depth first traversal
687  * @f: seq_file we are filling
688  * @p: the last profile writen
689  *
690  * Release all locking done by p_start/p_next on namespace tree
691  */
692 static void p_stop(struct seq_file *f, void *p)
693 {
694 	struct aa_profile *profile = p;
695 	struct aa_namespace *root = f->private, *ns;
696 
697 	if (profile) {
698 		for (ns = profile->ns; ns && ns != root; ns = ns->parent)
699 			mutex_unlock(&ns->lock);
700 	}
701 	mutex_unlock(&root->lock);
702 	aa_put_namespace(root);
703 }
704 
705 /**
706  * seq_show_profile - show a profile entry
707  * @f: seq_file to file
708  * @p: current position (profile)    (NOT NULL)
709  *
710  * Returns: error on failure
711  */
712 static int seq_show_profile(struct seq_file *f, void *p)
713 {
714 	struct aa_profile *profile = (struct aa_profile *)p;
715 	struct aa_namespace *root = f->private;
716 
717 	if (profile->ns != root)
718 		seq_printf(f, ":%s://", aa_ns_name(root, profile->ns));
719 	seq_printf(f, "%s (%s)\n", profile->base.hname,
720 		   aa_profile_mode_names[profile->mode]);
721 
722 	return 0;
723 }
724 
725 static const struct seq_operations aa_fs_profiles_op = {
726 	.start = p_start,
727 	.next = p_next,
728 	.stop = p_stop,
729 	.show = seq_show_profile,
730 };
731 
732 static int profiles_open(struct inode *inode, struct file *file)
733 {
734 	return seq_open(file, &aa_fs_profiles_op);
735 }
736 
737 static int profiles_release(struct inode *inode, struct file *file)
738 {
739 	return seq_release(inode, file);
740 }
741 
742 static const struct file_operations aa_fs_profiles_fops = {
743 	.open = profiles_open,
744 	.read = seq_read,
745 	.llseek = seq_lseek,
746 	.release = profiles_release,
747 };
748 
749 
750 /** Base file system setup **/
751 static struct aa_fs_entry aa_fs_entry_file[] = {
752 	AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \
753 				  "link lock"),
754 	{ }
755 };
756 
757 static struct aa_fs_entry aa_fs_entry_domain[] = {
758 	AA_FS_FILE_BOOLEAN("change_hat",	1),
759 	AA_FS_FILE_BOOLEAN("change_hatv",	1),
760 	AA_FS_FILE_BOOLEAN("change_onexec",	1),
761 	AA_FS_FILE_BOOLEAN("change_profile",	1),
762 	{ }
763 };
764 
765 static struct aa_fs_entry aa_fs_entry_policy[] = {
766 	AA_FS_FILE_BOOLEAN("set_load",          1),
767 	{}
768 };
769 
770 static struct aa_fs_entry aa_fs_entry_features[] = {
771 	AA_FS_DIR("policy",			aa_fs_entry_policy),
772 	AA_FS_DIR("domain",			aa_fs_entry_domain),
773 	AA_FS_DIR("file",			aa_fs_entry_file),
774 	AA_FS_FILE_U64("capability",		VFS_CAP_FLAGS_MASK),
775 	AA_FS_DIR("rlimit",			aa_fs_entry_rlimit),
776 	{ }
777 };
778 
779 static struct aa_fs_entry aa_fs_entry_apparmor[] = {
780 	AA_FS_FILE_FOPS(".load", 0640, &aa_fs_profile_load),
781 	AA_FS_FILE_FOPS(".replace", 0640, &aa_fs_profile_replace),
782 	AA_FS_FILE_FOPS(".remove", 0640, &aa_fs_profile_remove),
783 	AA_FS_FILE_FOPS("profiles", 0640, &aa_fs_profiles_fops),
784 	AA_FS_DIR("features", aa_fs_entry_features),
785 	{ }
786 };
787 
788 static struct aa_fs_entry aa_fs_entry =
789 	AA_FS_DIR("apparmor", aa_fs_entry_apparmor);
790 
791 /**
792  * aafs_create_file - create a file entry in the apparmor securityfs
793  * @fs_file: aa_fs_entry to build an entry for (NOT NULL)
794  * @parent: the parent dentry in the securityfs
795  *
796  * Use aafs_remove_file to remove entries created with this fn.
797  */
798 static int __init aafs_create_file(struct aa_fs_entry *fs_file,
799 				   struct dentry *parent)
800 {
801 	int error = 0;
802 
803 	fs_file->dentry = securityfs_create_file(fs_file->name,
804 						 S_IFREG | fs_file->mode,
805 						 parent, fs_file,
806 						 fs_file->file_ops);
807 	if (IS_ERR(fs_file->dentry)) {
808 		error = PTR_ERR(fs_file->dentry);
809 		fs_file->dentry = NULL;
810 	}
811 	return error;
812 }
813 
814 static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir);
815 /**
816  * aafs_create_dir - recursively create a directory entry in the securityfs
817  * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL)
818  * @parent: the parent dentry in the securityfs
819  *
820  * Use aafs_remove_dir to remove entries created with this fn.
821  */
822 static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
823 				  struct dentry *parent)
824 {
825 	struct aa_fs_entry *fs_file;
826 	struct dentry *dir;
827 	int error;
828 
829 	dir = securityfs_create_dir(fs_dir->name, parent);
830 	if (IS_ERR(dir))
831 		return PTR_ERR(dir);
832 	fs_dir->dentry = dir;
833 
834 	for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
835 		if (fs_file->v_type == AA_FS_TYPE_DIR)
836 			error = aafs_create_dir(fs_file, fs_dir->dentry);
837 		else
838 			error = aafs_create_file(fs_file, fs_dir->dentry);
839 		if (error)
840 			goto failed;
841 	}
842 
843 	return 0;
844 
845 failed:
846 	aafs_remove_dir(fs_dir);
847 
848 	return error;
849 }
850 
851 /**
852  * aafs_remove_file - drop a single file entry in the apparmor securityfs
853  * @fs_file: aa_fs_entry to detach from the securityfs (NOT NULL)
854  */
855 static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
856 {
857 	if (!fs_file->dentry)
858 		return;
859 
860 	securityfs_remove(fs_file->dentry);
861 	fs_file->dentry = NULL;
862 }
863 
864 /**
865  * aafs_remove_dir - recursively drop a directory entry from the securityfs
866  * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL)
867  */
868 static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
869 {
870 	struct aa_fs_entry *fs_file;
871 
872 	for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
873 		if (fs_file->v_type == AA_FS_TYPE_DIR)
874 			aafs_remove_dir(fs_file);
875 		else
876 			aafs_remove_file(fs_file);
877 	}
878 
879 	aafs_remove_file(fs_dir);
880 }
881 
882 /**
883  * aa_destroy_aafs - cleanup and free aafs
884  *
885  * releases dentries allocated by aa_create_aafs
886  */
887 void __init aa_destroy_aafs(void)
888 {
889 	aafs_remove_dir(&aa_fs_entry);
890 }
891 
892 /**
893  * aa_create_aafs - create the apparmor security filesystem
894  *
895  * dentries created here are released by aa_destroy_aafs
896  *
897  * Returns: error on failure
898  */
899 static int __init aa_create_aafs(void)
900 {
901 	int error;
902 
903 	if (!apparmor_initialized)
904 		return 0;
905 
906 	if (aa_fs_entry.dentry) {
907 		AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
908 		return -EEXIST;
909 	}
910 
911 	/* Populate fs tree. */
912 	error = aafs_create_dir(&aa_fs_entry, NULL);
913 	if (error)
914 		goto error;
915 
916 	error = __aa_fs_namespace_mkdir(root_ns, aa_fs_entry.dentry,
917 					"policy");
918 	if (error)
919 		goto error;
920 
921 	/* TODO: add support for apparmorfs_null and apparmorfs_mnt */
922 
923 	/* Report that AppArmor fs is enabled */
924 	aa_info_message("AppArmor Filesystem Enabled");
925 	return 0;
926 
927 error:
928 	aa_destroy_aafs();
929 	AA_ERROR("Error creating AppArmor securityfs\n");
930 	return error;
931 }
932 
933 fs_initcall(aa_create_aafs);
934