]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/blame - security/apparmor/apparmorfs.c
Merge tag 'fuse-fixes-5.2-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/mszer...
[mirror_ubuntu-eoan-kernel.git] / security / apparmor / apparmorfs.c
CommitLineData
b886d83c 1// SPDX-License-Identifier: GPL-2.0-only
63e2b423
JJ
2/*
3 * AppArmor security module
4 *
5 * This file contains AppArmor /sys/kernel/security/apparmor interface functions
6 *
7 * Copyright (C) 1998-2008 Novell/SUSE
8 * Copyright 2009-2010 Canonical Ltd.
63e2b423
JJ
9 */
10
0d259f04 11#include <linux/ctype.h>
63e2b423
JJ
12#include <linux/security.h>
13#include <linux/vmalloc.h>
876979c9 14#include <linux/init.h>
63e2b423
JJ
15#include <linux/seq_file.h>
16#include <linux/uaccess.h>
a71ada30 17#include <linux/mount.h>
63e2b423 18#include <linux/namei.h>
e74abcf3 19#include <linux/capability.h>
29b3822f 20#include <linux/rcupdate.h>
a71ada30 21#include <linux/fs.h>
d9bf2c26 22#include <linux/poll.h>
a481f4d9
JJ
23#include <uapi/linux/major.h>
24#include <uapi/linux/magic.h>
63e2b423
JJ
25
26#include "include/apparmor.h"
27#include "include/apparmorfs.h"
28#include "include/audit.h"
d8889d49 29#include "include/cred.h"
f8eb8a13 30#include "include/crypto.h"
cd1dbf76 31#include "include/ipc.h"
317d9a05 32#include "include/label.h"
63e2b423 33#include "include/policy.h"
cff281f6 34#include "include/policy_ns.h"
d384b0a1 35#include "include/resource.h"
5ac8c355 36#include "include/policy_unpack.h"
63e2b423 37
c97204ba
JJ
38/*
39 * The apparmor filesystem interface used for policy load and introspection
40 * The interface is split into two main components based on their function
41 * a securityfs component:
42 * used for static files that are always available, and which allows
43 * userspace to specificy the location of the security filesystem.
44 *
45 * fns and data are prefixed with
46 * aa_sfs_
47 *
48 * an apparmorfs component:
49 * used loaded policy content and introspection. It is not part of a
50 * regular mounted filesystem and is available only through the magic
51 * policy symlink in the root of the securityfs apparmor/ directory.
52 * Tasks queries will be magically redirected to the correct portion
53 * of the policy tree based on their confinement.
54 *
55 * fns and data are prefixed with
56 * aafs_
57 *
58 * The aa_fs_ prefix is used to indicate the fn is used by both the
59 * securityfs and apparmorfs filesystems.
60 */
61
62
63/*
64 * support fns
65 */
66
0d259f04
JJ
67/**
68 * aa_mangle_name - mangle a profile name to std profile layout form
69 * @name: profile name to mangle (NOT NULL)
70 * @target: buffer to store mangled name, same length as @name (MAYBE NULL)
71 *
72 * Returns: length of mangled name
73 */
bbe4a7c8 74static int mangle_name(const char *name, char *target)
0d259f04
JJ
75{
76 char *t = target;
77
78 while (*name == '/' || *name == '.')
79 name++;
80
81 if (target) {
82 for (; *name; name++) {
83 if (*name == '/')
84 *(t)++ = '.';
85 else if (isspace(*name))
86 *(t)++ = '_';
87 else if (isalnum(*name) || strchr("._-", *name))
88 *(t)++ = *name;
89 }
90
91 *t = 0;
92 } else {
93 int len = 0;
94 for (; *name; name++) {
95 if (isalnum(*name) || isspace(*name) ||
96 strchr("/._-", *name))
97 len++;
98 }
99
100 return len;
101 }
102
103 return t - target;
104}
105
a481f4d9
JJ
106
107/*
108 * aafs - core fns and data for the policy tree
109 */
110
111#define AAFS_NAME "apparmorfs"
112static struct vfsmount *aafs_mnt;
113static int aafs_count;
114
115
116static int aafs_show_path(struct seq_file *seq, struct dentry *dentry)
117{
a0781209 118 seq_printf(seq, "%s:[%lu]", AAFS_NAME, d_inode(dentry)->i_ino);
a481f4d9
JJ
119 return 0;
120}
121
27afa27d 122static void aafs_free_inode(struct inode *inode)
a481f4d9 123{
a481f4d9
JJ
124 if (S_ISLNK(inode->i_mode))
125 kfree(inode->i_link);
f51dcd0f
AV
126 free_inode_nonrcu(inode);
127}
128
a481f4d9
JJ
129static const struct super_operations aafs_super_ops = {
130 .statfs = simple_statfs,
27afa27d 131 .free_inode = aafs_free_inode,
a481f4d9
JJ
132 .show_path = aafs_show_path,
133};
134
135static int fill_super(struct super_block *sb, void *data, int silent)
136{
137 static struct tree_descr files[] = { {""} };
138 int error;
139
140 error = simple_fill_super(sb, AAFS_MAGIC, files);
141 if (error)
142 return error;
143 sb->s_op = &aafs_super_ops;
144
145 return 0;
146}
147
148static struct dentry *aafs_mount(struct file_system_type *fs_type,
149 int flags, const char *dev_name, void *data)
150{
151 return mount_single(fs_type, flags, data, fill_super);
152}
153
154static struct file_system_type aafs_ops = {
155 .owner = THIS_MODULE,
156 .name = AAFS_NAME,
157 .mount = aafs_mount,
158 .kill_sb = kill_anon_super,
159};
160
161/**
162 * __aafs_setup_d_inode - basic inode setup for apparmorfs
163 * @dir: parent directory for the dentry
164 * @dentry: dentry we are seting the inode up for
165 * @mode: permissions the file should have
166 * @data: data to store on inode.i_private, available in open()
167 * @link: if symlink, symlink target string
168 * @fops: struct file_operations that should be used
169 * @iops: struct of inode_operations that should be used
170 */
171static int __aafs_setup_d_inode(struct inode *dir, struct dentry *dentry,
172 umode_t mode, void *data, char *link,
173 const struct file_operations *fops,
174 const struct inode_operations *iops)
175{
176 struct inode *inode = new_inode(dir->i_sb);
177
178 AA_BUG(!dir);
179 AA_BUG(!dentry);
180
181 if (!inode)
182 return -ENOMEM;
183
184 inode->i_ino = get_next_ino();
185 inode->i_mode = mode;
186 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
187 inode->i_private = data;
188 if (S_ISDIR(mode)) {
189 inode->i_op = iops ? iops : &simple_dir_inode_operations;
190 inode->i_fop = &simple_dir_operations;
191 inc_nlink(inode);
192 inc_nlink(dir);
193 } else if (S_ISLNK(mode)) {
194 inode->i_op = iops ? iops : &simple_symlink_inode_operations;
195 inode->i_link = link;
196 } else {
197 inode->i_fop = fops;
198 }
199 d_instantiate(dentry, inode);
200 dget(dentry);
201
202 return 0;
203}
204
205/**
206 * aafs_create - create a dentry in the apparmorfs filesystem
207 *
208 * @name: name of dentry to create
209 * @mode: permissions the file should have
210 * @parent: parent directory for this dentry
211 * @data: data to store on inode.i_private, available in open()
212 * @link: if symlink, symlink target string
213 * @fops: struct file_operations that should be used for
214 * @iops: struct of inode_operations that should be used
215 *
216 * This is the basic "create a xxx" function for apparmorfs.
217 *
218 * Returns a pointer to a dentry if it succeeds, that must be free with
219 * aafs_remove(). Will return ERR_PTR on failure.
220 */
221static struct dentry *aafs_create(const char *name, umode_t mode,
222 struct dentry *parent, void *data, void *link,
223 const struct file_operations *fops,
224 const struct inode_operations *iops)
225{
226 struct dentry *dentry;
227 struct inode *dir;
228 int error;
229
230 AA_BUG(!name);
231 AA_BUG(!parent);
232
233 if (!(mode & S_IFMT))
234 mode = (mode & S_IALLUGO) | S_IFREG;
235
236 error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
237 if (error)
238 return ERR_PTR(error);
239
240 dir = d_inode(parent);
241
242 inode_lock(dir);
243 dentry = lookup_one_len(name, parent, strlen(name));
5d314a81
DC
244 if (IS_ERR(dentry)) {
245 error = PTR_ERR(dentry);
a481f4d9 246 goto fail_lock;
5d314a81 247 }
a481f4d9
JJ
248
249 if (d_really_is_positive(dentry)) {
250 error = -EEXIST;
251 goto fail_dentry;
252 }
253
254 error = __aafs_setup_d_inode(dir, dentry, mode, data, link, fops, iops);
255 if (error)
256 goto fail_dentry;
257 inode_unlock(dir);
258
259 return dentry;
260
261fail_dentry:
262 dput(dentry);
263
264fail_lock:
265 inode_unlock(dir);
266 simple_release_fs(&aafs_mnt, &aafs_count);
267
268 return ERR_PTR(error);
269}
270
271/**
272 * aafs_create_file - create a file in the apparmorfs filesystem
273 *
274 * @name: name of dentry to create
275 * @mode: permissions the file should have
276 * @parent: parent directory for this dentry
277 * @data: data to store on inode.i_private, available in open()
278 * @fops: struct file_operations that should be used for
279 *
280 * see aafs_create
281 */
282static struct dentry *aafs_create_file(const char *name, umode_t mode,
283 struct dentry *parent, void *data,
284 const struct file_operations *fops)
285{
286 return aafs_create(name, mode, parent, data, NULL, fops, NULL);
287}
288
289/**
290 * aafs_create_dir - create a directory in the apparmorfs filesystem
291 *
292 * @name: name of dentry to create
293 * @parent: parent directory for this dentry
294 *
295 * see aafs_create
296 */
297static struct dentry *aafs_create_dir(const char *name, struct dentry *parent)
298{
299 return aafs_create(name, S_IFDIR | 0755, parent, NULL, NULL, NULL,
300 NULL);
301}
302
303/**
304 * aafs_create_symlink - create a symlink in the apparmorfs filesystem
305 * @name: name of dentry to create
306 * @parent: parent directory for this dentry
307 * @target: if symlink, symlink target string
1180b4c7 308 * @private: private data
a481f4d9
JJ
309 * @iops: struct of inode_operations that should be used
310 *
311 * If @target parameter is %NULL, then the @iops parameter needs to be
312 * setup to handle .readlink and .get_link inode_operations.
313 */
314static struct dentry *aafs_create_symlink(const char *name,
315 struct dentry *parent,
316 const char *target,
1180b4c7 317 void *private,
a481f4d9
JJ
318 const struct inode_operations *iops)
319{
320 struct dentry *dent;
321 char *link = NULL;
322
323 if (target) {
a481f4d9
JJ
324 if (!link)
325 return ERR_PTR(-ENOMEM);
326 }
1180b4c7 327 dent = aafs_create(name, S_IFLNK | 0444, parent, private, link, NULL,
a481f4d9
JJ
328 iops);
329 if (IS_ERR(dent))
330 kfree(link);
331
332 return dent;
333}
334
335/**
336 * aafs_remove - removes a file or directory from the apparmorfs filesystem
337 *
338 * @dentry: dentry of the file/directory/symlink to removed.
339 */
340static void aafs_remove(struct dentry *dentry)
341{
342 struct inode *dir;
343
344 if (!dentry || IS_ERR(dentry))
345 return;
346
347 dir = d_inode(dentry->d_parent);
348 inode_lock(dir);
349 if (simple_positive(dentry)) {
350 if (d_is_dir(dentry))
351 simple_rmdir(dir, dentry);
352 else
353 simple_unlink(dir, dentry);
201218e4 354 d_delete(dentry);
a481f4d9
JJ
355 dput(dentry);
356 }
357 inode_unlock(dir);
358 simple_release_fs(&aafs_mnt, &aafs_count);
359}
360
361
362/*
363 * aa_fs - policy load/replace/remove
364 */
365
63e2b423
JJ
366/**
367 * aa_simple_write_to_buffer - common routine for getting policy from user
63e2b423 368 * @userbuf: user buffer to copy data from (NOT NULL)
3ed02ada 369 * @alloc_size: size of user buffer (REQUIRES: @alloc_size >= @copy_size)
63e2b423
JJ
370 * @copy_size: size of data to copy from user buffer
371 * @pos: position write is at in the file (NOT NULL)
372 *
373 * Returns: kernel buffer containing copy of user buffer data or an
374 * ERR_PTR on failure.
375 */
5ef50d01 376static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
5ac8c355
JJ
377 size_t alloc_size,
378 size_t copy_size,
379 loff_t *pos)
63e2b423 380{
5ac8c355 381 struct aa_loaddata *data;
63e2b423 382
e6bfa25d 383 AA_BUG(copy_size > alloc_size);
3ed02ada 384
63e2b423
JJ
385 if (*pos != 0)
386 /* only writes from pos 0, that is complete writes */
387 return ERR_PTR(-ESPIPE);
388
63e2b423 389 /* freed by caller to simple_write_to_buffer */
5d5182ca
JJ
390 data = aa_loaddata_alloc(alloc_size);
391 if (IS_ERR(data))
392 return data;
63e2b423 393
5d5182ca 394 data->size = copy_size;
5ac8c355 395 if (copy_from_user(data->data, userbuf, copy_size)) {
63e2b423
JJ
396 kvfree(data);
397 return ERR_PTR(-EFAULT);
398 }
399
400 return data;
401}
402
18e99f19 403static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
b7fd2c03 404 loff_t *pos, struct aa_ns *ns)
63e2b423 405{
5ac8c355 406 struct aa_loaddata *data;
637f688d
JJ
407 struct aa_label *label;
408 ssize_t error;
cf797c0e 409
637f688d 410 label = begin_current_label_crit_section();
cf797c0e 411
5ac8c355
JJ
412 /* high level check about policy management - fine grained in
413 * below after unpack
414 */
637f688d 415 error = aa_may_manage_policy(label, ns, mask);
5ac8c355
JJ
416 if (error)
417 return error;
63e2b423 418
5ef50d01 419 data = aa_simple_write_to_buffer(buf, size, size, pos);
63e2b423
JJ
420 error = PTR_ERR(data);
421 if (!IS_ERR(data)) {
637f688d 422 error = aa_replace_profiles(ns, label, mask, data);
5ac8c355 423 aa_put_loaddata(data);
63e2b423 424 }
637f688d 425 end_current_label_crit_section(label);
63e2b423
JJ
426
427 return error;
428}
429
b7fd2c03 430/* .load file hook fn to load policy */
5ac8c355
JJ
431static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
432 loff_t *pos)
433{
b7fd2c03 434 struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
18e99f19 435 int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns);
b7fd2c03
JJ
436
437 aa_put_ns(ns);
5ac8c355
JJ
438
439 return error;
440}
441
63e2b423 442static const struct file_operations aa_fs_profile_load = {
6038f373
AB
443 .write = profile_load,
444 .llseek = default_llseek,
63e2b423
JJ
445};
446
447/* .replace file hook fn to load and/or replace policy */
448static ssize_t profile_replace(struct file *f, const char __user *buf,
449 size_t size, loff_t *pos)
450{
b7fd2c03 451 struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
18e99f19
JJ
452 int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY,
453 buf, size, pos, ns);
b7fd2c03 454 aa_put_ns(ns);
63e2b423
JJ
455
456 return error;
457}
458
459static const struct file_operations aa_fs_profile_replace = {
6038f373
AB
460 .write = profile_replace,
461 .llseek = default_llseek,
63e2b423
JJ
462};
463
b7fd2c03 464/* .remove file hook fn to remove loaded policy */
63e2b423
JJ
465static ssize_t profile_remove(struct file *f, const char __user *buf,
466 size_t size, loff_t *pos)
467{
5ac8c355 468 struct aa_loaddata *data;
637f688d 469 struct aa_label *label;
63e2b423 470 ssize_t error;
b7fd2c03 471 struct aa_ns *ns = aa_get_ns(f->f_inode->i_private);
63e2b423 472
637f688d 473 label = begin_current_label_crit_section();
5ac8c355
JJ
474 /* high level check about policy management - fine grained in
475 * below after unpack
476 */
637f688d 477 error = aa_may_manage_policy(label, ns, AA_MAY_REMOVE_POLICY);
5ac8c355
JJ
478 if (error)
479 goto out;
480
63e2b423
JJ
481 /*
482 * aa_remove_profile needs a null terminated string so 1 extra
483 * byte is allocated and the copied data is null terminated.
484 */
5ef50d01 485 data = aa_simple_write_to_buffer(buf, size + 1, size, pos);
63e2b423
JJ
486
487 error = PTR_ERR(data);
488 if (!IS_ERR(data)) {
5ac8c355 489 data->data[size] = 0;
637f688d 490 error = aa_remove_profiles(ns, label, data->data, size);
5ac8c355 491 aa_put_loaddata(data);
63e2b423 492 }
5ac8c355 493 out:
637f688d 494 end_current_label_crit_section(label);
b7fd2c03 495 aa_put_ns(ns);
63e2b423
JJ
496 return error;
497}
498
499static const struct file_operations aa_fs_profile_remove = {
6038f373
AB
500 .write = profile_remove,
501 .llseek = default_llseek,
63e2b423
JJ
502};
503
d9bf2c26
JJ
504struct aa_revision {
505 struct aa_ns *ns;
506 long last_read;
507};
508
509/* revision file hook fn for policy loads */
510static int ns_revision_release(struct inode *inode, struct file *file)
511{
512 struct aa_revision *rev = file->private_data;
513
514 if (rev) {
515 aa_put_ns(rev->ns);
516 kfree(rev);
517 }
518
519 return 0;
520}
521
522static ssize_t ns_revision_read(struct file *file, char __user *buf,
523 size_t size, loff_t *ppos)
524{
525 struct aa_revision *rev = file->private_data;
526 char buffer[32];
527 long last_read;
528 int avail;
529
feb3c766 530 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
d9bf2c26
JJ
531 last_read = rev->last_read;
532 if (last_read == rev->ns->revision) {
533 mutex_unlock(&rev->ns->lock);
534 if (file->f_flags & O_NONBLOCK)
535 return -EAGAIN;
536 if (wait_event_interruptible(rev->ns->wait,
537 last_read !=
538 READ_ONCE(rev->ns->revision)))
539 return -ERESTARTSYS;
feb3c766 540 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
d9bf2c26
JJ
541 }
542
543 avail = sprintf(buffer, "%ld\n", rev->ns->revision);
544 if (*ppos + size > avail) {
545 rev->last_read = rev->ns->revision;
546 *ppos = 0;
547 }
548 mutex_unlock(&rev->ns->lock);
549
550 return simple_read_from_buffer(buf, size, ppos, buffer, avail);
551}
552
553static int ns_revision_open(struct inode *inode, struct file *file)
554{
555 struct aa_revision *rev = kzalloc(sizeof(*rev), GFP_KERNEL);
556
557 if (!rev)
558 return -ENOMEM;
559
560 rev->ns = aa_get_ns(inode->i_private);
561 if (!rev->ns)
562 rev->ns = aa_get_current_ns();
563 file->private_data = rev;
564
565 return 0;
566}
567
e6c5a7d9 568static __poll_t ns_revision_poll(struct file *file, poll_table *pt)
d9bf2c26
JJ
569{
570 struct aa_revision *rev = file->private_data;
e6c5a7d9 571 __poll_t mask = 0;
d9bf2c26
JJ
572
573 if (rev) {
feb3c766 574 mutex_lock_nested(&rev->ns->lock, rev->ns->level);
d9bf2c26
JJ
575 poll_wait(file, &rev->ns->wait, pt);
576 if (rev->last_read < rev->ns->revision)
a9a08845 577 mask |= EPOLLIN | EPOLLRDNORM;
d9bf2c26
JJ
578 mutex_unlock(&rev->ns->lock);
579 }
580
581 return mask;
582}
583
5d5182ca
JJ
584void __aa_bump_ns_revision(struct aa_ns *ns)
585{
586 ns->revision++;
d9bf2c26 587 wake_up_interruptible(&ns->wait);
5d5182ca
JJ
588}
589
d9bf2c26
JJ
590static const struct file_operations aa_fs_ns_revision_fops = {
591 .owner = THIS_MODULE,
592 .open = ns_revision_open,
593 .poll = ns_revision_poll,
594 .read = ns_revision_read,
595 .llseek = generic_file_llseek,
596 .release = ns_revision_release,
597};
598
4f3b3f2d
JJ
599static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
600 const char *match_str, size_t match_len)
601{
f4585bc2 602 struct aa_perms tmp = { };
4f3b3f2d
JJ
603 struct aa_dfa *dfa;
604 unsigned int state = 0;
605
637f688d 606 if (profile_unconfined(profile))
4f3b3f2d
JJ
607 return;
608 if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
609 dfa = profile->file.dfa;
610 state = aa_dfa_match_len(dfa, profile->file.start,
611 match_str + 1, match_len - 1);
4f3b3f2d
JJ
612 if (state) {
613 struct path_cond cond = { };
614
615 tmp = aa_compute_fperms(dfa, state, &cond);
616 }
617 } else if (profile->policy.dfa) {
b9590ad4 618 if (!PROFILE_MEDIATES(profile, *match_str))
4f3b3f2d
JJ
619 return; /* no change to current perms */
620 dfa = profile->policy.dfa;
621 state = aa_dfa_match_len(dfa, profile->policy.start[0],
622 match_str, match_len);
623 if (state)
624 aa_compute_perms(dfa, state, &tmp);
4f3b3f2d
JJ
625 }
626 aa_apply_modes_to_perms(profile, &tmp);
317d9a05 627 aa_perms_accum_raw(perms, &tmp);
4f3b3f2d
JJ
628}
629
630
e025be0f
WH
631/**
632 * query_data - queries a policy and writes its data to buf
633 * @buf: the resulting data is stored here (NOT NULL)
634 * @buf_len: size of buf
635 * @query: query string used to retrieve data
636 * @query_len: size of query including second NUL byte
637 *
638 * The buffers pointed to by buf and query may overlap. The query buffer is
639 * parsed before buf is written to.
640 *
641 * The query should look like "<LABEL>\0<KEY>\0", where <LABEL> is the name of
642 * the security confinement context and <KEY> is the name of the data to
643 * retrieve. <LABEL> and <KEY> must not be NUL-terminated.
644 *
645 * Don't expect the contents of buf to be preserved on failure.
646 *
647 * Returns: number of characters written to buf or -errno on failure
648 */
649static ssize_t query_data(char *buf, size_t buf_len,
650 char *query, size_t query_len)
651{
652 char *out;
653 const char *key;
317d9a05 654 struct label_it i;
637f688d 655 struct aa_label *label, *curr;
317d9a05 656 struct aa_profile *profile;
e025be0f
WH
657 struct aa_data *data;
658 u32 bytes, blocks;
659 __le32 outle32;
660
661 if (!query_len)
662 return -EINVAL; /* need a query */
663
664 key = query + strnlen(query, query_len) + 1;
665 if (key + 1 >= query + query_len)
666 return -EINVAL; /* not enough space for a non-empty key */
667 if (key + strnlen(key, query + query_len - key) >= query + query_len)
668 return -EINVAL; /* must end with NUL */
669
670 if (buf_len < sizeof(bytes) + sizeof(blocks))
671 return -EINVAL; /* not enough space */
672
637f688d
JJ
673 curr = begin_current_label_crit_section();
674 label = aa_label_parse(curr, query, GFP_KERNEL, false, false);
675 end_current_label_crit_section(curr);
676 if (IS_ERR(label))
677 return PTR_ERR(label);
e025be0f
WH
678
679 /* We are going to leave space for two numbers. The first is the total
680 * number of bytes we are writing after the first number. This is so
681 * users can read the full output without reallocation.
682 *
683 * The second number is the number of data blocks we're writing. An
684 * application might be confined by multiple policies having data in
685 * the same key.
686 */
687 memset(buf, 0, sizeof(bytes) + sizeof(blocks));
688 out = buf + sizeof(bytes) + sizeof(blocks);
689
690 blocks = 0;
317d9a05
JJ
691 label_for_each_confined(i, label, profile) {
692 if (!profile->data)
693 continue;
694
695 data = rhashtable_lookup_fast(profile->data, &key,
696 profile->data->p);
e025be0f
WH
697
698 if (data) {
317d9a05
JJ
699 if (out + sizeof(outle32) + data->size > buf +
700 buf_len) {
637f688d 701 aa_put_label(label);
e025be0f 702 return -EINVAL; /* not enough space */
637f688d 703 }
e025be0f
WH
704 outle32 = __cpu_to_le32(data->size);
705 memcpy(out, &outle32, sizeof(outle32));
706 out += sizeof(outle32);
707 memcpy(out, data->data, data->size);
708 out += data->size;
709 blocks++;
710 }
711 }
637f688d 712 aa_put_label(label);
e025be0f
WH
713
714 outle32 = __cpu_to_le32(out - buf - sizeof(bytes));
715 memcpy(buf, &outle32, sizeof(outle32));
716 outle32 = __cpu_to_le32(blocks);
717 memcpy(buf + sizeof(bytes), &outle32, sizeof(outle32));
718
719 return out - buf;
720}
721
4f3b3f2d
JJ
722/**
723 * query_label - queries a label and writes permissions to buf
724 * @buf: the resulting permissions string is stored here (NOT NULL)
725 * @buf_len: size of buf
726 * @query: binary query string to match against the dfa
727 * @query_len: size of query
728 * @view_only: only compute for querier's view
729 *
730 * The buffers pointed to by buf and query may overlap. The query buffer is
731 * parsed before buf is written to.
732 *
733 * The query should look like "LABEL_NAME\0DFA_STRING" where LABEL_NAME is
734 * the name of the label, in the current namespace, that is to be queried and
735 * DFA_STRING is a binary string to match against the label(s)'s DFA.
736 *
737 * LABEL_NAME must be NUL terminated. DFA_STRING may contain NUL characters
738 * but must *not* be NUL terminated.
739 *
740 * Returns: number of characters written to buf or -errno on failure
741 */
742static ssize_t query_label(char *buf, size_t buf_len,
743 char *query, size_t query_len, bool view_only)
744{
317d9a05 745 struct aa_profile *profile;
637f688d 746 struct aa_label *label, *curr;
4f3b3f2d
JJ
747 char *label_name, *match_str;
748 size_t label_name_len, match_len;
749 struct aa_perms perms;
317d9a05 750 struct label_it i;
4f3b3f2d
JJ
751
752 if (!query_len)
753 return -EINVAL;
754
755 label_name = query;
756 label_name_len = strnlen(query, query_len);
757 if (!label_name_len || label_name_len == query_len)
758 return -EINVAL;
759
760 /**
761 * The extra byte is to account for the null byte between the
762 * profile name and dfa string. profile_name_len is greater
763 * than zero and less than query_len, so a byte can be safely
764 * added or subtracted.
765 */
766 match_str = label_name + label_name_len + 1;
767 match_len = query_len - label_name_len - 1;
768
637f688d
JJ
769 curr = begin_current_label_crit_section();
770 label = aa_label_parse(curr, label_name, GFP_KERNEL, false, false);
771 end_current_label_crit_section(curr);
772 if (IS_ERR(label))
773 return PTR_ERR(label);
4f3b3f2d
JJ
774
775 perms = allperms;
317d9a05
JJ
776 if (view_only) {
777 label_for_each_in_ns(i, labels_ns(label), label, profile) {
778 profile_query_cb(profile, &perms, match_str, match_len);
779 }
780 } else {
781 label_for_each(i, label, profile) {
782 profile_query_cb(profile, &perms, match_str, match_len);
783 }
784 }
785 aa_put_label(label);
4f3b3f2d
JJ
786
787 return scnprintf(buf, buf_len,
788 "allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
789 perms.allow, perms.deny, perms.audit, perms.quiet);
790}
791
1dea3b41
JJ
792/*
793 * Transaction based IO.
794 * The file expects a write which triggers the transaction, and then
795 * possibly a read(s) which collects the result - which is stored in a
796 * file-local buffer. Once a new write is performed, a new set of results
797 * are stored in the file-local buffer.
798 */
799struct multi_transaction {
800 struct kref count;
801 ssize_t size;
802 char data[0];
803};
804
805#define MULTI_TRANSACTION_LIMIT (PAGE_SIZE - sizeof(struct multi_transaction))
806/* TODO: replace with per file lock */
807static DEFINE_SPINLOCK(multi_transaction_lock);
808
809static void multi_transaction_kref(struct kref *kref)
810{
811 struct multi_transaction *t;
812
813 t = container_of(kref, struct multi_transaction, count);
814 free_page((unsigned long) t);
815}
816
817static struct multi_transaction *
818get_multi_transaction(struct multi_transaction *t)
819{
820 if (t)
821 kref_get(&(t->count));
822
823 return t;
824}
825
826static void put_multi_transaction(struct multi_transaction *t)
827{
828 if (t)
829 kref_put(&(t->count), multi_transaction_kref);
830}
831
832/* does not increment @new's count */
833static void multi_transaction_set(struct file *file,
834 struct multi_transaction *new, size_t n)
835{
836 struct multi_transaction *old;
837
838 AA_BUG(n > MULTI_TRANSACTION_LIMIT);
839
840 new->size = n;
841 spin_lock(&multi_transaction_lock);
842 old = (struct multi_transaction *) file->private_data;
843 file->private_data = new;
844 spin_unlock(&multi_transaction_lock);
845 put_multi_transaction(old);
846}
847
848static struct multi_transaction *multi_transaction_new(struct file *file,
849 const char __user *buf,
850 size_t size)
851{
852 struct multi_transaction *t;
853
854 if (size > MULTI_TRANSACTION_LIMIT - 1)
855 return ERR_PTR(-EFBIG);
856
857 t = (struct multi_transaction *)get_zeroed_page(GFP_KERNEL);
858 if (!t)
859 return ERR_PTR(-ENOMEM);
860 kref_init(&t->count);
861 if (copy_from_user(t->data, buf, size))
862 return ERR_PTR(-EFAULT);
863
864 return t;
865}
866
867static ssize_t multi_transaction_read(struct file *file, char __user *buf,
868 size_t size, loff_t *pos)
869{
870 struct multi_transaction *t;
871 ssize_t ret;
872
873 spin_lock(&multi_transaction_lock);
874 t = get_multi_transaction(file->private_data);
875 spin_unlock(&multi_transaction_lock);
876 if (!t)
877 return 0;
878
879 ret = simple_read_from_buffer(buf, size, pos, t->data, t->size);
880 put_multi_transaction(t);
881
882 return ret;
883}
884
885static int multi_transaction_release(struct inode *inode, struct file *file)
886{
887 put_multi_transaction(file->private_data);
888
889 return 0;
890}
891
317d9a05
JJ
892#define QUERY_CMD_LABEL "label\0"
893#define QUERY_CMD_LABEL_LEN 6
4f3b3f2d
JJ
894#define QUERY_CMD_PROFILE "profile\0"
895#define QUERY_CMD_PROFILE_LEN 8
317d9a05
JJ
896#define QUERY_CMD_LABELALL "labelall\0"
897#define QUERY_CMD_LABELALL_LEN 9
e025be0f
WH
898#define QUERY_CMD_DATA "data\0"
899#define QUERY_CMD_DATA_LEN 5
900
901/**
902 * aa_write_access - generic permissions and data query
903 * @file: pointer to open apparmorfs/access file
904 * @ubuf: user buffer containing the complete query string (NOT NULL)
905 * @count: size of ubuf
906 * @ppos: position in the file (MUST BE ZERO)
907 *
908 * Allows for one permissions or data query per open(), write(), and read()
909 * sequence. The only queries currently supported are label-based queries for
910 * permissions or data.
911 *
912 * For permissions queries, ubuf must begin with "label\0", followed by the
913 * profile query specific format described in the query_label() function
914 * documentation.
915 *
916 * For data queries, ubuf must have the form "data\0<LABEL>\0<KEY>\0", where
917 * <LABEL> is the name of the security confinement context and <KEY> is the
918 * name of the data to retrieve.
919 *
920 * Returns: number of bytes written or -errno on failure
921 */
922static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
923 size_t count, loff_t *ppos)
924{
1dea3b41 925 struct multi_transaction *t;
e025be0f
WH
926 ssize_t len;
927
928 if (*ppos)
929 return -ESPIPE;
930
1dea3b41
JJ
931 t = multi_transaction_new(file, ubuf, count);
932 if (IS_ERR(t))
933 return PTR_ERR(t);
e025be0f 934
4f3b3f2d
JJ
935 if (count > QUERY_CMD_PROFILE_LEN &&
936 !memcmp(t->data, QUERY_CMD_PROFILE, QUERY_CMD_PROFILE_LEN)) {
937 len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
938 t->data + QUERY_CMD_PROFILE_LEN,
939 count - QUERY_CMD_PROFILE_LEN, true);
317d9a05
JJ
940 } else if (count > QUERY_CMD_LABEL_LEN &&
941 !memcmp(t->data, QUERY_CMD_LABEL, QUERY_CMD_LABEL_LEN)) {
942 len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
943 t->data + QUERY_CMD_LABEL_LEN,
944 count - QUERY_CMD_LABEL_LEN, true);
945 } else if (count > QUERY_CMD_LABELALL_LEN &&
946 !memcmp(t->data, QUERY_CMD_LABELALL,
947 QUERY_CMD_LABELALL_LEN)) {
948 len = query_label(t->data, MULTI_TRANSACTION_LIMIT,
949 t->data + QUERY_CMD_LABELALL_LEN,
950 count - QUERY_CMD_LABELALL_LEN, false);
4f3b3f2d 951 } else if (count > QUERY_CMD_DATA_LEN &&
1dea3b41
JJ
952 !memcmp(t->data, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
953 len = query_data(t->data, MULTI_TRANSACTION_LIMIT,
954 t->data + QUERY_CMD_DATA_LEN,
e025be0f
WH
955 count - QUERY_CMD_DATA_LEN);
956 } else
957 len = -EINVAL;
958
1dea3b41
JJ
959 if (len < 0) {
960 put_multi_transaction(t);
e025be0f 961 return len;
1dea3b41 962 }
e025be0f 963
1dea3b41 964 multi_transaction_set(file, t, len);
e025be0f
WH
965
966 return count;
967}
968
c97204ba 969static const struct file_operations aa_sfs_access = {
e025be0f 970 .write = aa_write_access,
1dea3b41
JJ
971 .read = multi_transaction_read,
972 .release = multi_transaction_release,
e025be0f
WH
973 .llseek = generic_file_llseek,
974};
975
c97204ba 976static int aa_sfs_seq_show(struct seq_file *seq, void *v)
e74abcf3 977{
c97204ba 978 struct aa_sfs_entry *fs_file = seq->private;
e74abcf3
KC
979
980 if (!fs_file)
981 return 0;
982
983 switch (fs_file->v_type) {
c97204ba 984 case AA_SFS_TYPE_BOOLEAN:
e74abcf3
KC
985 seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
986 break;
c97204ba 987 case AA_SFS_TYPE_STRING:
a9bf8e9f
KC
988 seq_printf(seq, "%s\n", fs_file->v.string);
989 break;
c97204ba 990 case AA_SFS_TYPE_U64:
e74abcf3
KC
991 seq_printf(seq, "%#08lx\n", fs_file->v.u64);
992 break;
993 default:
994 /* Ignore unpritable entry types. */
995 break;
996 }
997
998 return 0;
999}
1000
c97204ba 1001static int aa_sfs_seq_open(struct inode *inode, struct file *file)
e74abcf3 1002{
c97204ba 1003 return single_open(file, aa_sfs_seq_show, inode->i_private);
e74abcf3
KC
1004}
1005
c97204ba 1006const struct file_operations aa_sfs_seq_file_ops = {
e74abcf3 1007 .owner = THIS_MODULE,
c97204ba 1008 .open = aa_sfs_seq_open,
e74abcf3
KC
1009 .read = seq_read,
1010 .llseek = seq_lseek,
1011 .release = single_release,
1012};
1013
52b97de3
JJ
1014/*
1015 * profile based file operations
1016 * policy/profiles/XXXX/profiles/ *
1017 */
1018
1019#define SEQ_PROFILE_FOPS(NAME) \
1020static int seq_profile_ ##NAME ##_open(struct inode *inode, struct file *file)\
1021{ \
1022 return seq_profile_open(inode, file, seq_profile_ ##NAME ##_show); \
1023} \
1024 \
1025static const struct file_operations seq_profile_ ##NAME ##_fops = { \
1026 .owner = THIS_MODULE, \
1027 .open = seq_profile_ ##NAME ##_open, \
1028 .read = seq_read, \
1029 .llseek = seq_lseek, \
1030 .release = seq_profile_release, \
1031} \
1032
1033static int seq_profile_open(struct inode *inode, struct file *file,
1034 int (*show)(struct seq_file *, void *))
0d259f04 1035{
8399588a
JJ
1036 struct aa_proxy *proxy = aa_get_proxy(inode->i_private);
1037 int error = single_open(file, show, proxy);
0d259f04
JJ
1038
1039 if (error) {
1040 file->private_data = NULL;
8399588a 1041 aa_put_proxy(proxy);
0d259f04
JJ
1042 }
1043
1044 return error;
1045}
1046
52b97de3 1047static int seq_profile_release(struct inode *inode, struct file *file)
0d259f04
JJ
1048{
1049 struct seq_file *seq = (struct seq_file *) file->private_data;
1050 if (seq)
8399588a 1051 aa_put_proxy(seq->private);
0d259f04
JJ
1052 return single_release(inode, file);
1053}
1054
52b97de3 1055static int seq_profile_name_show(struct seq_file *seq, void *v)
0d259f04 1056{
8399588a 1057 struct aa_proxy *proxy = seq->private;
637f688d
JJ
1058 struct aa_label *label = aa_get_label_rcu(&proxy->label);
1059 struct aa_profile *profile = labels_profile(label);
0d259f04 1060 seq_printf(seq, "%s\n", profile->base.name);
637f688d 1061 aa_put_label(label);
0d259f04
JJ
1062
1063 return 0;
1064}
1065
52b97de3 1066static int seq_profile_mode_show(struct seq_file *seq, void *v)
0d259f04 1067{
8399588a 1068 struct aa_proxy *proxy = seq->private;
637f688d
JJ
1069 struct aa_label *label = aa_get_label_rcu(&proxy->label);
1070 struct aa_profile *profile = labels_profile(label);
0d259f04 1071 seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
637f688d 1072 aa_put_label(label);
0d259f04
JJ
1073
1074 return 0;
1075}
1076
52b97de3 1077static int seq_profile_attach_show(struct seq_file *seq, void *v)
556d0be7 1078{
8399588a 1079 struct aa_proxy *proxy = seq->private;
637f688d
JJ
1080 struct aa_label *label = aa_get_label_rcu(&proxy->label);
1081 struct aa_profile *profile = labels_profile(label);
556d0be7
JJ
1082 if (profile->attach)
1083 seq_printf(seq, "%s\n", profile->attach);
1084 else if (profile->xmatch)
1085 seq_puts(seq, "<unknown>\n");
1086 else
1087 seq_printf(seq, "%s\n", profile->base.name);
637f688d 1088 aa_put_label(label);
556d0be7
JJ
1089
1090 return 0;
1091}
1092
52b97de3 1093static int seq_profile_hash_show(struct seq_file *seq, void *v)
f8eb8a13 1094{
8399588a 1095 struct aa_proxy *proxy = seq->private;
637f688d
JJ
1096 struct aa_label *label = aa_get_label_rcu(&proxy->label);
1097 struct aa_profile *profile = labels_profile(label);
f8eb8a13
JJ
1098 unsigned int i, size = aa_hash_size();
1099
1100 if (profile->hash) {
1101 for (i = 0; i < size; i++)
1102 seq_printf(seq, "%.2x", profile->hash[i]);
47dbd1cd 1103 seq_putc(seq, '\n');
f8eb8a13 1104 }
637f688d 1105 aa_put_label(label);
f8eb8a13
JJ
1106
1107 return 0;
1108}
1109
52b97de3
JJ
1110SEQ_PROFILE_FOPS(name);
1111SEQ_PROFILE_FOPS(mode);
1112SEQ_PROFILE_FOPS(attach);
1113SEQ_PROFILE_FOPS(hash);
f8eb8a13 1114
64c86970
JJ
1115/*
1116 * namespace based files
1117 * several root files and
1118 * policy/ *
1119 */
f8eb8a13 1120
64c86970
JJ
1121#define SEQ_NS_FOPS(NAME) \
1122static int seq_ns_ ##NAME ##_open(struct inode *inode, struct file *file) \
1123{ \
1124 return single_open(file, seq_ns_ ##NAME ##_show, inode->i_private); \
1125} \
1126 \
1127static const struct file_operations seq_ns_ ##NAME ##_fops = { \
1128 .owner = THIS_MODULE, \
1129 .open = seq_ns_ ##NAME ##_open, \
1130 .read = seq_read, \
1131 .llseek = seq_lseek, \
1132 .release = single_release, \
1133} \
3e3e5695 1134
40cde7fc
JJ
1135static int seq_ns_stacked_show(struct seq_file *seq, void *v)
1136{
1137 struct aa_label *label;
1138
1139 label = begin_current_label_crit_section();
1140 seq_printf(seq, "%s\n", label->size > 1 ? "yes" : "no");
1141 end_current_label_crit_section(label);
1142
1143 return 0;
1144}
1145
1146static int seq_ns_nsstacked_show(struct seq_file *seq, void *v)
1147{
1148 struct aa_label *label;
1149 struct aa_profile *profile;
1150 struct label_it it;
1151 int count = 1;
1152
1153 label = begin_current_label_crit_section();
1154
1155 if (label->size > 1) {
1156 label_for_each(it, label, profile)
1157 if (profile->ns != labels_ns(label)) {
1158 count++;
1159 break;
1160 }
1161 }
1162
1163 seq_printf(seq, "%s\n", count > 1 ? "yes" : "no");
1164 end_current_label_crit_section(label);
1165
1166 return 0;
1167}
1168
64c86970 1169static int seq_ns_level_show(struct seq_file *seq, void *v)
a71ada30 1170{
637f688d 1171 struct aa_label *label;
a71ada30 1172
637f688d
JJ
1173 label = begin_current_label_crit_section();
1174 seq_printf(seq, "%d\n", labels_ns(label)->level);
1175 end_current_label_crit_section(label);
a71ada30
JJ
1176
1177 return 0;
1178}
1179
64c86970 1180static int seq_ns_name_show(struct seq_file *seq, void *v)
3e3e5695 1181{
637f688d 1182 struct aa_label *label = begin_current_label_crit_section();
040d9e2b 1183 seq_printf(seq, "%s\n", labels_ns(label)->base.name);
637f688d 1184 end_current_label_crit_section(label);
3e3e5695
JJ
1185
1186 return 0;
1187}
1188
40cde7fc
JJ
1189SEQ_NS_FOPS(stacked);
1190SEQ_NS_FOPS(nsstacked);
64c86970
JJ
1191SEQ_NS_FOPS(level);
1192SEQ_NS_FOPS(name);
3e3e5695 1193
5d5182ca
JJ
1194
1195/* policy/raw_data/ * file ops */
1196
1197#define SEQ_RAWDATA_FOPS(NAME) \
1198static int seq_rawdata_ ##NAME ##_open(struct inode *inode, struct file *file)\
1199{ \
1200 return seq_rawdata_open(inode, file, seq_rawdata_ ##NAME ##_show); \
1201} \
1202 \
1203static const struct file_operations seq_rawdata_ ##NAME ##_fops = { \
1204 .owner = THIS_MODULE, \
1205 .open = seq_rawdata_ ##NAME ##_open, \
1206 .read = seq_read, \
1207 .llseek = seq_lseek, \
1208 .release = seq_rawdata_release, \
1209} \
1210
1211static int seq_rawdata_open(struct inode *inode, struct file *file,
1212 int (*show)(struct seq_file *, void *))
5ac8c355 1213{
5d5182ca
JJ
1214 struct aa_loaddata *data = __aa_get_loaddata(inode->i_private);
1215 int error;
5ac8c355 1216
5d5182ca
JJ
1217 if (!data)
1218 /* lost race this ent is being reaped */
1219 return -ENOENT;
1220
1221 error = single_open(file, show, data);
1222 if (error) {
1223 AA_BUG(file->private_data &&
1224 ((struct seq_file *)file->private_data)->private);
1225 aa_put_loaddata(data);
1226 }
1227
1228 return error;
5ac8c355
JJ
1229}
1230
5d5182ca 1231static int seq_rawdata_release(struct inode *inode, struct file *file)
5ac8c355 1232{
5d5182ca 1233 struct seq_file *seq = (struct seq_file *) file->private_data;
5ac8c355 1234
5d5182ca
JJ
1235 if (seq)
1236 aa_put_loaddata(seq->private);
0ff3d97f 1237
5d5182ca
JJ
1238 return single_release(inode, file);
1239}
1240
1241static int seq_rawdata_abi_show(struct seq_file *seq, void *v)
1242{
1243 struct aa_loaddata *data = seq->private;
1244
1245 seq_printf(seq, "v%d\n", data->abi);
5ac8c355
JJ
1246
1247 return 0;
1248}
1249
5d5182ca 1250static int seq_rawdata_revision_show(struct seq_file *seq, void *v)
5ac8c355 1251{
5d5182ca 1252 struct aa_loaddata *data = seq->private;
5ac8c355 1253
5d5182ca
JJ
1254 seq_printf(seq, "%ld\n", data->revision);
1255
1256 return 0;
1257}
5ac8c355 1258
5d5182ca 1259static int seq_rawdata_hash_show(struct seq_file *seq, void *v)
5ac8c355 1260{
5d5182ca 1261 struct aa_loaddata *data = seq->private;
5ac8c355
JJ
1262 unsigned int i, size = aa_hash_size();
1263
5d5182ca 1264 if (data->hash) {
5ac8c355 1265 for (i = 0; i < size; i++)
5d5182ca 1266 seq_printf(seq, "%.2x", data->hash[i]);
47dbd1cd 1267 seq_putc(seq, '\n');
5ac8c355 1268 }
5ac8c355
JJ
1269
1270 return 0;
1271}
1272
5d5182ca
JJ
1273SEQ_RAWDATA_FOPS(abi);
1274SEQ_RAWDATA_FOPS(revision);
1275SEQ_RAWDATA_FOPS(hash);
5ac8c355
JJ
1276
1277static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
1278 loff_t *ppos)
1279{
1280 struct aa_loaddata *rawdata = file->private_data;
1281
1282 return simple_read_from_buffer(buf, size, ppos, rawdata->data,
1283 rawdata->size);
1284}
1285
5d5182ca 1286static int rawdata_release(struct inode *inode, struct file *file)
5ac8c355 1287{
5d5182ca
JJ
1288 aa_put_loaddata(file->private_data);
1289
1290 return 0;
1291}
5ac8c355 1292
5d5182ca
JJ
1293static int rawdata_open(struct inode *inode, struct file *file)
1294{
5ac8c355
JJ
1295 if (!policy_view_capable(NULL))
1296 return -EACCES;
5d5182ca
JJ
1297 file->private_data = __aa_get_loaddata(inode->i_private);
1298 if (!file->private_data)
1299 /* lost race: this entry is being reaped */
1300 return -ENOENT;
5ac8c355
JJ
1301
1302 return 0;
1303}
1304
5d5182ca 1305static const struct file_operations rawdata_fops = {
5ac8c355
JJ
1306 .open = rawdata_open,
1307 .read = rawdata_read,
1308 .llseek = generic_file_llseek,
1309 .release = rawdata_release,
1310};
1311
5d5182ca
JJ
1312static void remove_rawdata_dents(struct aa_loaddata *rawdata)
1313{
1314 int i;
1315
1316 for (i = 0; i < AAFS_LOADDATA_NDENTS; i++) {
1317 if (!IS_ERR_OR_NULL(rawdata->dents[i])) {
1318 /* no refcounts on i_private */
c961ee5f 1319 aafs_remove(rawdata->dents[i]);
5d5182ca
JJ
1320 rawdata->dents[i] = NULL;
1321 }
1322 }
1323}
1324
1325void __aa_fs_remove_rawdata(struct aa_loaddata *rawdata)
1326{
1327 AA_BUG(rawdata->ns && !mutex_is_locked(&rawdata->ns->lock));
1328
1329 if (rawdata->ns) {
1330 remove_rawdata_dents(rawdata);
1331 list_del_init(&rawdata->list);
1332 aa_put_ns(rawdata->ns);
1333 rawdata->ns = NULL;
1334 }
1335}
1336
1337int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata)
1338{
1339 struct dentry *dent, *dir;
1340
1341 AA_BUG(!ns);
1342 AA_BUG(!rawdata);
1343 AA_BUG(!mutex_is_locked(&ns->lock));
1344 AA_BUG(!ns_subdata_dir(ns));
1345
1346 /*
1347 * just use ns revision dir was originally created at. This is
1348 * under ns->lock and if load is successful revision will be
1349 * bumped and is guaranteed to be unique
1350 */
1351 rawdata->name = kasprintf(GFP_KERNEL, "%ld", ns->revision);
1352 if (!rawdata->name)
1353 return -ENOMEM;
1354
c961ee5f 1355 dir = aafs_create_dir(rawdata->name, ns_subdata_dir(ns));
5d5182ca
JJ
1356 if (IS_ERR(dir))
1357 /* ->name freed when rawdata freed */
1358 return PTR_ERR(dir);
1359 rawdata->dents[AAFS_LOADDATA_DIR] = dir;
1360
c961ee5f 1361 dent = aafs_create_file("abi", S_IFREG | 0444, dir, rawdata,
5d5182ca
JJ
1362 &seq_rawdata_abi_fops);
1363 if (IS_ERR(dent))
1364 goto fail;
1365 rawdata->dents[AAFS_LOADDATA_ABI] = dent;
1366
c961ee5f 1367 dent = aafs_create_file("revision", S_IFREG | 0444, dir, rawdata,
5d5182ca
JJ
1368 &seq_rawdata_revision_fops);
1369 if (IS_ERR(dent))
1370 goto fail;
1371 rawdata->dents[AAFS_LOADDATA_REVISION] = dent;
1372
1373 if (aa_g_hash_policy) {
c961ee5f 1374 dent = aafs_create_file("sha1", S_IFREG | 0444, dir,
5d5182ca
JJ
1375 rawdata, &seq_rawdata_hash_fops);
1376 if (IS_ERR(dent))
1377 goto fail;
1378 rawdata->dents[AAFS_LOADDATA_HASH] = dent;
1379 }
1380
c961ee5f 1381 dent = aafs_create_file("raw_data", S_IFREG | 0444,
5d5182ca
JJ
1382 dir, rawdata, &rawdata_fops);
1383 if (IS_ERR(dent))
1384 goto fail;
1385 rawdata->dents[AAFS_LOADDATA_DATA] = dent;
1386 d_inode(dent)->i_size = rawdata->size;
1387
1388 rawdata->ns = aa_get_ns(ns);
1389 list_add(&rawdata->list, &ns->rawdata_list);
1390 /* no refcount on inode rawdata */
1391
1392 return 0;
1393
1394fail:
1395 remove_rawdata_dents(rawdata);
1396
1397 return PTR_ERR(dent);
1398}
1399
0d259f04 1400/** fns to setup dynamic per profile/namespace files **/
c97204ba
JJ
1401
1402/**
1403 *
1404 * Requires: @profile->ns->lock held
1405 */
1406void __aafs_profile_rmdir(struct aa_profile *profile)
0d259f04
JJ
1407{
1408 struct aa_profile *child;
1409 int i;
1410
1411 if (!profile)
1412 return;
1413
1414 list_for_each_entry(child, &profile->base.profiles, base.list)
c97204ba 1415 __aafs_profile_rmdir(child);
0d259f04
JJ
1416
1417 for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) {
8399588a 1418 struct aa_proxy *proxy;
0d259f04
JJ
1419 if (!profile->dents[i])
1420 continue;
1421
8399588a 1422 proxy = d_inode(profile->dents[i])->i_private;
c961ee5f 1423 aafs_remove(profile->dents[i]);
8399588a 1424 aa_put_proxy(proxy);
0d259f04
JJ
1425 profile->dents[i] = NULL;
1426 }
1427}
1428
c97204ba
JJ
1429/**
1430 *
1431 * Requires: @old->ns->lock held
1432 */
1433void __aafs_profile_migrate_dents(struct aa_profile *old,
1434 struct aa_profile *new)
0d259f04
JJ
1435{
1436 int i;
1437
cbf2d0e1
JJ
1438 AA_BUG(!old);
1439 AA_BUG(!new);
1440 AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock));
1441
0d259f04
JJ
1442 for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
1443 new->dents[i] = old->dents[i];
d671e890 1444 if (new->dents[i])
078cd827 1445 new->dents[i]->d_inode->i_mtime = current_time(new->dents[i]->d_inode);
0d259f04
JJ
1446 old->dents[i] = NULL;
1447 }
1448}
1449
1450static struct dentry *create_profile_file(struct dentry *dir, const char *name,
1451 struct aa_profile *profile,
1452 const struct file_operations *fops)
1453{
637f688d 1454 struct aa_proxy *proxy = aa_get_proxy(profile->label.proxy);
0d259f04
JJ
1455 struct dentry *dent;
1456
c961ee5f 1457 dent = aafs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
0d259f04 1458 if (IS_ERR(dent))
8399588a 1459 aa_put_proxy(proxy);
0d259f04
JJ
1460
1461 return dent;
1462}
1463
5d5182ca
JJ
1464static int profile_depth(struct aa_profile *profile)
1465{
1466 int depth = 0;
1467
1468 rcu_read_lock();
1469 for (depth = 0; profile; profile = rcu_access_pointer(profile->parent))
1470 depth++;
1471 rcu_read_unlock();
1472
1473 return depth;
1474}
1475
1180b4c7 1476static char *gen_symlink_name(int depth, const char *dirname, const char *fname)
5d5182ca 1477{
1180b4c7 1478 char *buffer, *s;
5d5182ca 1479 int error;
1180b4c7
JJ
1480 int size = depth * 6 + strlen(dirname) + strlen(fname) + 11;
1481
1482 s = buffer = kmalloc(size, GFP_KERNEL);
1483 if (!buffer)
1484 return ERR_PTR(-ENOMEM);
5d5182ca
JJ
1485
1486 for (; depth > 0; depth--) {
1180b4c7
JJ
1487 strcpy(s, "../../");
1488 s += 6;
1489 size -= 6;
5d5182ca
JJ
1490 }
1491
1180b4c7 1492 error = snprintf(s, size, "raw_data/%s/%s", dirname, fname);
588558eb
CIK
1493 if (error >= size || error < 0) {
1494 kfree(buffer);
1180b4c7 1495 return ERR_PTR(-ENAMETOOLONG);
588558eb 1496 }
5d5182ca 1497
1180b4c7
JJ
1498 return buffer;
1499}
1500
1501static void rawdata_link_cb(void *arg)
1502{
1503 kfree(arg);
1504}
1505
1506static const char *rawdata_get_link_base(struct dentry *dentry,
1507 struct inode *inode,
1508 struct delayed_call *done,
1509 const char *name)
1510{
1511 struct aa_proxy *proxy = inode->i_private;
1512 struct aa_label *label;
1513 struct aa_profile *profile;
1514 char *target;
1515 int depth;
1516
1517 if (!dentry)
1518 return ERR_PTR(-ECHILD);
1519
1520 label = aa_get_label_rcu(&proxy->label);
1521 profile = labels_profile(label);
1522 depth = profile_depth(profile);
1523 target = gen_symlink_name(depth, profile->rawdata->name, name);
1524 aa_put_label(label);
1525
1526 if (IS_ERR(target))
1527 return target;
1528
1529 set_delayed_call(done, rawdata_link_cb, target);
1530
1531 return target;
1532}
1533
1534static const char *rawdata_get_link_sha1(struct dentry *dentry,
1535 struct inode *inode,
1536 struct delayed_call *done)
1537{
1538 return rawdata_get_link_base(dentry, inode, done, "sha1");
1539}
1540
1541static const char *rawdata_get_link_abi(struct dentry *dentry,
1542 struct inode *inode,
1543 struct delayed_call *done)
1544{
1545 return rawdata_get_link_base(dentry, inode, done, "abi");
5d5182ca
JJ
1546}
1547
1180b4c7
JJ
1548static const char *rawdata_get_link_data(struct dentry *dentry,
1549 struct inode *inode,
1550 struct delayed_call *done)
1551{
1552 return rawdata_get_link_base(dentry, inode, done, "raw_data");
5d5182ca
JJ
1553}
1554
1180b4c7
JJ
1555static const struct inode_operations rawdata_link_sha1_iops = {
1556 .get_link = rawdata_get_link_sha1,
1557};
1558
1559static const struct inode_operations rawdata_link_abi_iops = {
1560 .get_link = rawdata_get_link_abi,
1561};
1562static const struct inode_operations rawdata_link_data_iops = {
1563 .get_link = rawdata_get_link_data,
1564};
1565
1566
5d5182ca
JJ
1567/*
1568 * Requires: @profile->ns->lock held
1569 */
c97204ba 1570int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
0d259f04
JJ
1571{
1572 struct aa_profile *child;
1573 struct dentry *dent = NULL, *dir;
1574 int error;
1575
cbf2d0e1
JJ
1576 AA_BUG(!profile);
1577 AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
1578
0d259f04
JJ
1579 if (!parent) {
1580 struct aa_profile *p;
1581 p = aa_deref_parent(profile);
1582 dent = prof_dir(p);
1583 /* adding to parent that previously didn't have children */
c961ee5f 1584 dent = aafs_create_dir("profiles", dent);
0d259f04
JJ
1585 if (IS_ERR(dent))
1586 goto fail;
1587 prof_child_dir(p) = parent = dent;
1588 }
1589
1590 if (!profile->dirname) {
1591 int len, id_len;
1592 len = mangle_name(profile->base.name, NULL);
1593 id_len = snprintf(NULL, 0, ".%ld", profile->ns->uniq_id);
1594
1595 profile->dirname = kmalloc(len + id_len + 1, GFP_KERNEL);
ffac1de6
DC
1596 if (!profile->dirname) {
1597 error = -ENOMEM;
1598 goto fail2;
1599 }
0d259f04
JJ
1600
1601 mangle_name(profile->base.name, profile->dirname);
1602 sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++);
1603 }
1604
c961ee5f 1605 dent = aafs_create_dir(profile->dirname, parent);
0d259f04
JJ
1606 if (IS_ERR(dent))
1607 goto fail;
1608 prof_dir(profile) = dir = dent;
1609
52b97de3
JJ
1610 dent = create_profile_file(dir, "name", profile,
1611 &seq_profile_name_fops);
0d259f04
JJ
1612 if (IS_ERR(dent))
1613 goto fail;
1614 profile->dents[AAFS_PROF_NAME] = dent;
1615
52b97de3
JJ
1616 dent = create_profile_file(dir, "mode", profile,
1617 &seq_profile_mode_fops);
0d259f04
JJ
1618 if (IS_ERR(dent))
1619 goto fail;
1620 profile->dents[AAFS_PROF_MODE] = dent;
1621
556d0be7 1622 dent = create_profile_file(dir, "attach", profile,
52b97de3 1623 &seq_profile_attach_fops);
556d0be7
JJ
1624 if (IS_ERR(dent))
1625 goto fail;
1626 profile->dents[AAFS_PROF_ATTACH] = dent;
1627
f8eb8a13
JJ
1628 if (profile->hash) {
1629 dent = create_profile_file(dir, "sha1", profile,
52b97de3 1630 &seq_profile_hash_fops);
f8eb8a13
JJ
1631 if (IS_ERR(dent))
1632 goto fail;
1633 profile->dents[AAFS_PROF_HASH] = dent;
1634 }
1635
5ac8c355 1636 if (profile->rawdata) {
1180b4c7
JJ
1637 dent = aafs_create_symlink("raw_sha1", dir, NULL,
1638 profile->label.proxy,
1639 &rawdata_link_sha1_iops);
5ac8c355
JJ
1640 if (IS_ERR(dent))
1641 goto fail;
1180b4c7 1642 aa_get_proxy(profile->label.proxy);
5ac8c355
JJ
1643 profile->dents[AAFS_PROF_RAW_HASH] = dent;
1644
1180b4c7
JJ
1645 dent = aafs_create_symlink("raw_abi", dir, NULL,
1646 profile->label.proxy,
1647 &rawdata_link_abi_iops);
5ac8c355
JJ
1648 if (IS_ERR(dent))
1649 goto fail;
1180b4c7 1650 aa_get_proxy(profile->label.proxy);
5ac8c355
JJ
1651 profile->dents[AAFS_PROF_RAW_ABI] = dent;
1652
1180b4c7
JJ
1653 dent = aafs_create_symlink("raw_data", dir, NULL,
1654 profile->label.proxy,
1655 &rawdata_link_data_iops);
5ac8c355
JJ
1656 if (IS_ERR(dent))
1657 goto fail;
1180b4c7 1658 aa_get_proxy(profile->label.proxy);
5ac8c355 1659 profile->dents[AAFS_PROF_RAW_DATA] = dent;
5ac8c355
JJ
1660 }
1661
0d259f04 1662 list_for_each_entry(child, &profile->base.profiles, base.list) {
c97204ba 1663 error = __aafs_profile_mkdir(child, prof_child_dir(profile));
0d259f04
JJ
1664 if (error)
1665 goto fail2;
1666 }
1667
1668 return 0;
1669
1670fail:
1671 error = PTR_ERR(dent);
1672
1673fail2:
c97204ba 1674 __aafs_profile_rmdir(profile);
0d259f04
JJ
1675
1676 return error;
1677}
1678
4ae47f33
JJ
1679static int ns_mkdir_op(struct inode *dir, struct dentry *dentry, umode_t mode)
1680{
1681 struct aa_ns *ns, *parent;
1682 /* TODO: improve permission check */
637f688d
JJ
1683 struct aa_label *label;
1684 int error;
1685
1686 label = begin_current_label_crit_section();
1687 error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
1688 end_current_label_crit_section(label);
4ae47f33
JJ
1689 if (error)
1690 return error;
1691
1692 parent = aa_get_ns(dir->i_private);
1693 AA_BUG(d_inode(ns_subns_dir(parent)) != dir);
1694
1695 /* we have to unlock and then relock to get locking order right
1696 * for pin_fs
1697 */
1698 inode_unlock(dir);
1699 error = simple_pin_fs(&aafs_ops, &aafs_mnt, &aafs_count);
feb3c766 1700 mutex_lock_nested(&parent->lock, parent->level);
4ae47f33
JJ
1701 inode_lock_nested(dir, I_MUTEX_PARENT);
1702 if (error)
1703 goto out;
1704
1705 error = __aafs_setup_d_inode(dir, dentry, mode | S_IFDIR, NULL,
1706 NULL, NULL, NULL);
1707 if (error)
1708 goto out_pin;
1709
1710 ns = __aa_find_or_create_ns(parent, READ_ONCE(dentry->d_name.name),
1711 dentry);
1712 if (IS_ERR(ns)) {
1713 error = PTR_ERR(ns);
1714 ns = NULL;
1715 }
1716
1717 aa_put_ns(ns); /* list ref remains */
1718out_pin:
1719 if (error)
1720 simple_release_fs(&aafs_mnt, &aafs_count);
1721out:
1722 mutex_unlock(&parent->lock);
1723 aa_put_ns(parent);
1724
1725 return error;
1726}
1727
1728static int ns_rmdir_op(struct inode *dir, struct dentry *dentry)
1729{
1730 struct aa_ns *ns, *parent;
1731 /* TODO: improve permission check */
637f688d
JJ
1732 struct aa_label *label;
1733 int error;
1734
1735 label = begin_current_label_crit_section();
1736 error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY);
1737 end_current_label_crit_section(label);
4ae47f33
JJ
1738 if (error)
1739 return error;
1740
566f52ec 1741 parent = aa_get_ns(dir->i_private);
4ae47f33
JJ
1742 /* rmdir calls the generic securityfs functions to remove files
1743 * from the apparmor dir. It is up to the apparmor ns locking
1744 * to avoid races.
1745 */
1746 inode_unlock(dir);
1747 inode_unlock(dentry->d_inode);
1748
feb3c766 1749 mutex_lock_nested(&parent->lock, parent->level);
4ae47f33
JJ
1750 ns = aa_get_ns(__aa_findn_ns(&parent->sub_ns, dentry->d_name.name,
1751 dentry->d_name.len));
1752 if (!ns) {
1753 error = -ENOENT;
1754 goto out;
1755 }
1756 AA_BUG(ns_dir(ns) != dentry);
1757
1758 __aa_remove_ns(ns);
1759 aa_put_ns(ns);
1760
1761out:
1762 mutex_unlock(&parent->lock);
1763 inode_lock_nested(dir, I_MUTEX_PARENT);
1764 inode_lock(dentry->d_inode);
1765 aa_put_ns(parent);
1766
1767 return error;
1768}
1769
1770static const struct inode_operations ns_dir_inode_operations = {
1771 .lookup = simple_lookup,
1772 .mkdir = ns_mkdir_op,
1773 .rmdir = ns_rmdir_op,
1774};
1775
5d5182ca
JJ
1776static void __aa_fs_list_remove_rawdata(struct aa_ns *ns)
1777{
1778 struct aa_loaddata *ent, *tmp;
1779
1780 AA_BUG(!mutex_is_locked(&ns->lock));
1781
1782 list_for_each_entry_safe(ent, tmp, &ns->rawdata_list, list)
1783 __aa_fs_remove_rawdata(ent);
1784}
1785
c97204ba
JJ
1786/**
1787 *
1788 * Requires: @ns->lock held
1789 */
1790void __aafs_ns_rmdir(struct aa_ns *ns)
0d259f04 1791{
98849dff 1792 struct aa_ns *sub;
0d259f04
JJ
1793 struct aa_profile *child;
1794 int i;
1795
1796 if (!ns)
1797 return;
cbf2d0e1 1798 AA_BUG(!mutex_is_locked(&ns->lock));
0d259f04
JJ
1799
1800 list_for_each_entry(child, &ns->base.profiles, base.list)
c97204ba 1801 __aafs_profile_rmdir(child);
0d259f04
JJ
1802
1803 list_for_each_entry(sub, &ns->sub_ns, base.list) {
feb3c766 1804 mutex_lock_nested(&sub->lock, sub->level);
c97204ba 1805 __aafs_ns_rmdir(sub);
0d259f04
JJ
1806 mutex_unlock(&sub->lock);
1807 }
1808
5d5182ca
JJ
1809 __aa_fs_list_remove_rawdata(ns);
1810
b7fd2c03
JJ
1811 if (ns_subns_dir(ns)) {
1812 sub = d_inode(ns_subns_dir(ns))->i_private;
1813 aa_put_ns(sub);
1814 }
1815 if (ns_subload(ns)) {
1816 sub = d_inode(ns_subload(ns))->i_private;
1817 aa_put_ns(sub);
1818 }
1819 if (ns_subreplace(ns)) {
1820 sub = d_inode(ns_subreplace(ns))->i_private;
1821 aa_put_ns(sub);
1822 }
1823 if (ns_subremove(ns)) {
1824 sub = d_inode(ns_subremove(ns))->i_private;
1825 aa_put_ns(sub);
1826 }
d9bf2c26
JJ
1827 if (ns_subrevision(ns)) {
1828 sub = d_inode(ns_subrevision(ns))->i_private;
1829 aa_put_ns(sub);
1830 }
b7fd2c03 1831
0d259f04 1832 for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
c961ee5f 1833 aafs_remove(ns->dents[i]);
0d259f04
JJ
1834 ns->dents[i] = NULL;
1835 }
1836}
1837
b7fd2c03 1838/* assumes cleanup in caller */
c97204ba 1839static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir)
b7fd2c03
JJ
1840{
1841 struct dentry *dent;
1842
1843 AA_BUG(!ns);
1844 AA_BUG(!dir);
1845
c961ee5f 1846 dent = aafs_create_dir("profiles", dir);
b7fd2c03
JJ
1847 if (IS_ERR(dent))
1848 return PTR_ERR(dent);
1849 ns_subprofs_dir(ns) = dent;
1850
c961ee5f 1851 dent = aafs_create_dir("raw_data", dir);
b7fd2c03
JJ
1852 if (IS_ERR(dent))
1853 return PTR_ERR(dent);
1854 ns_subdata_dir(ns) = dent;
1855
d9bf2c26
JJ
1856 dent = aafs_create_file("revision", 0444, dir, ns,
1857 &aa_fs_ns_revision_fops);
1858 if (IS_ERR(dent))
1859 return PTR_ERR(dent);
1860 aa_get_ns(ns);
1861 ns_subrevision(ns) = dent;
1862
c961ee5f 1863 dent = aafs_create_file(".load", 0640, dir, ns,
b7fd2c03
JJ
1864 &aa_fs_profile_load);
1865 if (IS_ERR(dent))
1866 return PTR_ERR(dent);
1867 aa_get_ns(ns);
1868 ns_subload(ns) = dent;
1869
c961ee5f 1870 dent = aafs_create_file(".replace", 0640, dir, ns,
b7fd2c03
JJ
1871 &aa_fs_profile_replace);
1872 if (IS_ERR(dent))
1873 return PTR_ERR(dent);
1874 aa_get_ns(ns);
1875 ns_subreplace(ns) = dent;
1876
c961ee5f 1877 dent = aafs_create_file(".remove", 0640, dir, ns,
b7fd2c03
JJ
1878 &aa_fs_profile_remove);
1879 if (IS_ERR(dent))
1880 return PTR_ERR(dent);
1881 aa_get_ns(ns);
1882 ns_subremove(ns) = dent;
1883
4ae47f33
JJ
1884 /* use create_dentry so we can supply private data */
1885 dent = aafs_create("namespaces", S_IFDIR | 0755, dir, ns, NULL, NULL,
1886 &ns_dir_inode_operations);
b7fd2c03
JJ
1887 if (IS_ERR(dent))
1888 return PTR_ERR(dent);
1889 aa_get_ns(ns);
1890 ns_subns_dir(ns) = dent;
1891
1892 return 0;
1893}
1894
c97204ba
JJ
1895/*
1896 * Requires: @ns->lock held
1897 */
98407f0a
JJ
1898int __aafs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name,
1899 struct dentry *dent)
0d259f04 1900{
98849dff 1901 struct aa_ns *sub;
0d259f04 1902 struct aa_profile *child;
98407f0a 1903 struct dentry *dir;
0d259f04
JJ
1904 int error;
1905
b7fd2c03
JJ
1906 AA_BUG(!ns);
1907 AA_BUG(!parent);
1908 AA_BUG(!mutex_is_locked(&ns->lock));
1909
0d259f04
JJ
1910 if (!name)
1911 name = ns->base.name;
1912
c961ee5f
JJ
1913 if (!dent) {
1914 /* create ns dir if it doesn't already exist */
1915 dent = aafs_create_dir(name, parent);
1916 if (IS_ERR(dent))
1917 goto fail;
1918 } else
1919 dget(dent);
b7fd2c03 1920 ns_dir(ns) = dir = dent;
c97204ba 1921 error = __aafs_ns_mkdir_entries(ns, dir);
b7fd2c03
JJ
1922 if (error)
1923 goto fail2;
0d259f04 1924
b7fd2c03 1925 /* profiles */
0d259f04 1926 list_for_each_entry(child, &ns->base.profiles, base.list) {
c97204ba 1927 error = __aafs_profile_mkdir(child, ns_subprofs_dir(ns));
0d259f04
JJ
1928 if (error)
1929 goto fail2;
1930 }
1931
b7fd2c03 1932 /* subnamespaces */
0d259f04 1933 list_for_each_entry(sub, &ns->sub_ns, base.list) {
feb3c766 1934 mutex_lock_nested(&sub->lock, sub->level);
98407f0a 1935 error = __aafs_ns_mkdir(sub, ns_subns_dir(ns), NULL, NULL);
0d259f04
JJ
1936 mutex_unlock(&sub->lock);
1937 if (error)
1938 goto fail2;
1939 }
1940
1941 return 0;
1942
1943fail:
1944 error = PTR_ERR(dent);
1945
1946fail2:
c97204ba 1947 __aafs_ns_rmdir(ns);
0d259f04
JJ
1948
1949 return error;
1950}
1951
1952
29b3822f
JJ
1953#define list_entry_is_head(pos, head, member) (&pos->member == (head))
1954
1955/**
98849dff 1956 * __next_ns - find the next namespace to list
29b3822f
JJ
1957 * @root: root namespace to stop search at (NOT NULL)
1958 * @ns: current ns position (NOT NULL)
1959 *
1960 * Find the next namespace from @ns under @root and handle all locking needed
1961 * while switching current namespace.
1962 *
1963 * Returns: next namespace or NULL if at last namespace under @root
1964 * Requires: ns->parent->lock to be held
1965 * NOTE: will not unlock root->lock
1966 */
98849dff 1967static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
29b3822f 1968{
98849dff 1969 struct aa_ns *parent, *next;
29b3822f 1970
cbf2d0e1
JJ
1971 AA_BUG(!root);
1972 AA_BUG(!ns);
1973 AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock));
1974
29b3822f
JJ
1975 /* is next namespace a child */
1976 if (!list_empty(&ns->sub_ns)) {
1977 next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
feb3c766 1978 mutex_lock_nested(&next->lock, next->level);
29b3822f
JJ
1979 return next;
1980 }
1981
1982 /* check if the next ns is a sibling, parent, gp, .. */
1983 parent = ns->parent;
ed2c7da3 1984 while (ns != root) {
29b3822f 1985 mutex_unlock(&ns->lock);
38dbd7d8 1986 next = list_next_entry(ns, base.list);
29b3822f 1987 if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
feb3c766 1988 mutex_lock_nested(&next->lock, next->level);
29b3822f
JJ
1989 return next;
1990 }
29b3822f
JJ
1991 ns = parent;
1992 parent = parent->parent;
1993 }
1994
1995 return NULL;
1996}
1997
1998/**
1999 * __first_profile - find the first profile in a namespace
2000 * @root: namespace that is root of profiles being displayed (NOT NULL)
2001 * @ns: namespace to start in (NOT NULL)
2002 *
2003 * Returns: unrefcounted profile or NULL if no profile
2004 * Requires: profile->ns.lock to be held
2005 */
98849dff
JJ
2006static struct aa_profile *__first_profile(struct aa_ns *root,
2007 struct aa_ns *ns)
29b3822f 2008{
cbf2d0e1
JJ
2009 AA_BUG(!root);
2010 AA_BUG(ns && !mutex_is_locked(&ns->lock));
2011
98849dff 2012 for (; ns; ns = __next_ns(root, ns)) {
29b3822f
JJ
2013 if (!list_empty(&ns->base.profiles))
2014 return list_first_entry(&ns->base.profiles,
2015 struct aa_profile, base.list);
2016 }
2017 return NULL;
2018}
2019
2020/**
2021 * __next_profile - step to the next profile in a profile tree
2022 * @profile: current profile in tree (NOT NULL)
2023 *
2024 * Perform a depth first traversal on the profile tree in a namespace
2025 *
2026 * Returns: next profile or NULL if done
2027 * Requires: profile->ns.lock to be held
2028 */
2029static struct aa_profile *__next_profile(struct aa_profile *p)
2030{
2031 struct aa_profile *parent;
98849dff 2032 struct aa_ns *ns = p->ns;
29b3822f 2033
cbf2d0e1
JJ
2034 AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock));
2035
29b3822f
JJ
2036 /* is next profile a child */
2037 if (!list_empty(&p->base.profiles))
2038 return list_first_entry(&p->base.profiles, typeof(*p),
2039 base.list);
2040
2041 /* is next profile a sibling, parent sibling, gp, sibling, .. */
2042 parent = rcu_dereference_protected(p->parent,
2043 mutex_is_locked(&p->ns->lock));
2044 while (parent) {
38dbd7d8 2045 p = list_next_entry(p, base.list);
29b3822f
JJ
2046 if (!list_entry_is_head(p, &parent->base.profiles, base.list))
2047 return p;
2048 p = parent;
2049 parent = rcu_dereference_protected(parent->parent,
2050 mutex_is_locked(&parent->ns->lock));
2051 }
2052
2053 /* is next another profile in the namespace */
38dbd7d8 2054 p = list_next_entry(p, base.list);
29b3822f
JJ
2055 if (!list_entry_is_head(p, &ns->base.profiles, base.list))
2056 return p;
2057
2058 return NULL;
2059}
2060
2061/**
2062 * next_profile - step to the next profile in where ever it may be
2063 * @root: root namespace (NOT NULL)
2064 * @profile: current profile (NOT NULL)
2065 *
2066 * Returns: next profile or NULL if there isn't one
2067 */
98849dff 2068static struct aa_profile *next_profile(struct aa_ns *root,
29b3822f
JJ
2069 struct aa_profile *profile)
2070{
2071 struct aa_profile *next = __next_profile(profile);
2072 if (next)
2073 return next;
2074
2075 /* finished all profiles in namespace move to next namespace */
98849dff 2076 return __first_profile(root, __next_ns(root, profile->ns));
29b3822f
JJ
2077}
2078
2079/**
2080 * p_start - start a depth first traversal of profile tree
2081 * @f: seq_file to fill
2082 * @pos: current position
2083 *
2084 * Returns: first profile under current namespace or NULL if none found
2085 *
2086 * acquires first ns->lock
2087 */
2088static void *p_start(struct seq_file *f, loff_t *pos)
2089{
2090 struct aa_profile *profile = NULL;
cf797c0e 2091 struct aa_ns *root = aa_get_current_ns();
29b3822f 2092 loff_t l = *pos;
cf797c0e 2093 f->private = root;
29b3822f
JJ
2094
2095 /* find the first profile */
feb3c766 2096 mutex_lock_nested(&root->lock, root->level);
29b3822f
JJ
2097 profile = __first_profile(root, root);
2098
2099 /* skip to position */
2100 for (; profile && l > 0; l--)
2101 profile = next_profile(root, profile);
2102
2103 return profile;
2104}
2105
2106/**
2107 * p_next - read the next profile entry
2108 * @f: seq_file to fill
2109 * @p: profile previously returned
2110 * @pos: current position
2111 *
2112 * Returns: next profile after @p or NULL if none
2113 *
2114 * may acquire/release locks in namespace tree as necessary
2115 */
2116static void *p_next(struct seq_file *f, void *p, loff_t *pos)
2117{
2118 struct aa_profile *profile = p;
98849dff 2119 struct aa_ns *ns = f->private;
29b3822f
JJ
2120 (*pos)++;
2121
2122 return next_profile(ns, profile);
2123}
2124
2125/**
2126 * p_stop - stop depth first traversal
2127 * @f: seq_file we are filling
2128 * @p: the last profile writen
2129 *
2130 * Release all locking done by p_start/p_next on namespace tree
2131 */
2132static void p_stop(struct seq_file *f, void *p)
2133{
2134 struct aa_profile *profile = p;
98849dff 2135 struct aa_ns *root = f->private, *ns;
29b3822f
JJ
2136
2137 if (profile) {
2138 for (ns = profile->ns; ns && ns != root; ns = ns->parent)
2139 mutex_unlock(&ns->lock);
2140 }
2141 mutex_unlock(&root->lock);
98849dff 2142 aa_put_ns(root);
29b3822f
JJ
2143}
2144
2145/**
2146 * seq_show_profile - show a profile entry
2147 * @f: seq_file to file
2148 * @p: current position (profile) (NOT NULL)
2149 *
2150 * Returns: error on failure
2151 */
2152static int seq_show_profile(struct seq_file *f, void *p)
2153{
2154 struct aa_profile *profile = (struct aa_profile *)p;
98849dff 2155 struct aa_ns *root = f->private;
29b3822f 2156
637f688d
JJ
2157 aa_label_seq_xprint(f, root, &profile->label,
2158 FLAG_SHOW_MODE | FLAG_VIEW_SUBNS, GFP_KERNEL);
2159 seq_putc(f, '\n');
29b3822f
JJ
2160
2161 return 0;
2162}
2163
c97204ba 2164static const struct seq_operations aa_sfs_profiles_op = {
29b3822f
JJ
2165 .start = p_start,
2166 .next = p_next,
2167 .stop = p_stop,
2168 .show = seq_show_profile,
2169};
2170
2171static int profiles_open(struct inode *inode, struct file *file)
2172{
5ac8c355
JJ
2173 if (!policy_view_capable(NULL))
2174 return -EACCES;
2175
c97204ba 2176 return seq_open(file, &aa_sfs_profiles_op);
29b3822f
JJ
2177}
2178
2179static int profiles_release(struct inode *inode, struct file *file)
2180{
2181 return seq_release(inode, file);
2182}
2183
c97204ba 2184static const struct file_operations aa_sfs_profiles_fops = {
29b3822f
JJ
2185 .open = profiles_open,
2186 .read = seq_read,
2187 .llseek = seq_lseek,
2188 .release = profiles_release,
2189};
2190
2191
0d259f04 2192/** Base file system setup **/
c97204ba
JJ
2193static struct aa_sfs_entry aa_sfs_entry_file[] = {
2194 AA_SFS_FILE_STRING("mask",
2195 "create read write exec append mmap_exec link lock"),
a9bf8e9f
KC
2196 { }
2197};
2198
290f458a
JJ
2199static struct aa_sfs_entry aa_sfs_entry_ptrace[] = {
2200 AA_SFS_FILE_STRING("mask", "read trace"),
2201 { }
2202};
2203
cd1dbf76
JJ
2204static struct aa_sfs_entry aa_sfs_entry_signal[] = {
2205 AA_SFS_FILE_STRING("mask", AA_SFS_SIG_MASK),
2206 { }
2207};
2208
73f488cd
JJ
2209static struct aa_sfs_entry aa_sfs_entry_attach[] = {
2210 AA_SFS_FILE_BOOLEAN("xattr", 1),
2211 { }
2212};
c97204ba
JJ
2213static struct aa_sfs_entry aa_sfs_entry_domain[] = {
2214 AA_SFS_FILE_BOOLEAN("change_hat", 1),
2215 AA_SFS_FILE_BOOLEAN("change_hatv", 1),
2216 AA_SFS_FILE_BOOLEAN("change_onexec", 1),
2217 AA_SFS_FILE_BOOLEAN("change_profile", 1),
6c5fc8f1 2218 AA_SFS_FILE_BOOLEAN("stack", 1),
c97204ba 2219 AA_SFS_FILE_BOOLEAN("fix_binfmt_elf_mmap", 1),
9fcf78cc 2220 AA_SFS_FILE_BOOLEAN("post_nnp_subset", 1),
21f60661 2221 AA_SFS_FILE_BOOLEAN("computed_longest_left", 1),
73f488cd 2222 AA_SFS_DIR("attach_conditions", aa_sfs_entry_attach),
c97204ba 2223 AA_SFS_FILE_STRING("version", "1.2"),
e74abcf3
KC
2224 { }
2225};
2226
c97204ba
JJ
2227static struct aa_sfs_entry aa_sfs_entry_versions[] = {
2228 AA_SFS_FILE_BOOLEAN("v5", 1),
5379a331
JJ
2229 AA_SFS_FILE_BOOLEAN("v6", 1),
2230 AA_SFS_FILE_BOOLEAN("v7", 1),
56974a6f 2231 AA_SFS_FILE_BOOLEAN("v8", 1),
474d6b75
JJ
2232 { }
2233};
2234
c97204ba
JJ
2235static struct aa_sfs_entry aa_sfs_entry_policy[] = {
2236 AA_SFS_DIR("versions", aa_sfs_entry_versions),
2237 AA_SFS_FILE_BOOLEAN("set_load", 1),
474d6b75 2238 { }
9d910a3b
JJ
2239};
2240
2ea3ffb7
JJ
2241static struct aa_sfs_entry aa_sfs_entry_mount[] = {
2242 AA_SFS_FILE_STRING("mask", "mount umount pivot_root"),
2243 { }
2244};
2245
33f2eada
JJ
2246static struct aa_sfs_entry aa_sfs_entry_ns[] = {
2247 AA_SFS_FILE_BOOLEAN("profile", 1),
2ea3ffb7 2248 AA_SFS_FILE_BOOLEAN("pivot_root", 0),
33f2eada
JJ
2249 { }
2250};
2251
a83bd86e 2252static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
4f3b3f2d 2253 AA_SFS_FILE_STRING("perms", "allow deny audit quiet"),
a83bd86e 2254 AA_SFS_FILE_BOOLEAN("data", 1),
1dea3b41 2255 AA_SFS_FILE_BOOLEAN("multi_transaction", 1),
a83bd86e
JJ
2256 { }
2257};
2258
2259static struct aa_sfs_entry aa_sfs_entry_query[] = {
2260 AA_SFS_DIR("label", aa_sfs_entry_query_label),
2261 { }
2262};
c97204ba
JJ
2263static struct aa_sfs_entry aa_sfs_entry_features[] = {
2264 AA_SFS_DIR("policy", aa_sfs_entry_policy),
2265 AA_SFS_DIR("domain", aa_sfs_entry_domain),
2266 AA_SFS_DIR("file", aa_sfs_entry_file),
56974a6f 2267 AA_SFS_DIR("network_v8", aa_sfs_entry_network),
2ea3ffb7 2268 AA_SFS_DIR("mount", aa_sfs_entry_mount),
33f2eada 2269 AA_SFS_DIR("namespaces", aa_sfs_entry_ns),
c97204ba
JJ
2270 AA_SFS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
2271 AA_SFS_DIR("rlimit", aa_sfs_entry_rlimit),
2272 AA_SFS_DIR("caps", aa_sfs_entry_caps),
290f458a 2273 AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
cd1dbf76 2274 AA_SFS_DIR("signal", aa_sfs_entry_signal),
a83bd86e 2275 AA_SFS_DIR("query", aa_sfs_entry_query),
e74abcf3
KC
2276 { }
2277};
2278
c97204ba 2279static struct aa_sfs_entry aa_sfs_entry_apparmor[] = {
bf81100f 2280 AA_SFS_FILE_FOPS(".access", 0666, &aa_sfs_access),
6c5fc8f1
JJ
2281 AA_SFS_FILE_FOPS(".stacked", 0444, &seq_ns_stacked_fops),
2282 AA_SFS_FILE_FOPS(".ns_stacked", 0444, &seq_ns_nsstacked_fops),
bf81100f
JJ
2283 AA_SFS_FILE_FOPS(".ns_level", 0444, &seq_ns_level_fops),
2284 AA_SFS_FILE_FOPS(".ns_name", 0444, &seq_ns_name_fops),
2285 AA_SFS_FILE_FOPS("profiles", 0444, &aa_sfs_profiles_fops),
c97204ba 2286 AA_SFS_DIR("features", aa_sfs_entry_features),
9acd494b
KC
2287 { }
2288};
63e2b423 2289
c97204ba
JJ
2290static struct aa_sfs_entry aa_sfs_entry =
2291 AA_SFS_DIR("apparmor", aa_sfs_entry_apparmor);
63e2b423 2292
9acd494b 2293/**
a481f4d9 2294 * entry_create_file - create a file entry in the apparmor securityfs
c97204ba 2295 * @fs_file: aa_sfs_entry to build an entry for (NOT NULL)
9acd494b
KC
2296 * @parent: the parent dentry in the securityfs
2297 *
a481f4d9 2298 * Use entry_remove_file to remove entries created with this fn.
9acd494b 2299 */
c97204ba 2300static int __init entry_create_file(struct aa_sfs_entry *fs_file,
a481f4d9 2301 struct dentry *parent)
9acd494b
KC
2302{
2303 int error = 0;
2304
2305 fs_file->dentry = securityfs_create_file(fs_file->name,
2306 S_IFREG | fs_file->mode,
2307 parent, fs_file,
2308 fs_file->file_ops);
2309 if (IS_ERR(fs_file->dentry)) {
2310 error = PTR_ERR(fs_file->dentry);
2311 fs_file->dentry = NULL;
63e2b423 2312 }
9acd494b 2313 return error;
63e2b423
JJ
2314}
2315
c97204ba 2316static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir);
63e2b423 2317/**
a481f4d9 2318 * entry_create_dir - recursively create a directory entry in the securityfs
c97204ba 2319 * @fs_dir: aa_sfs_entry (and all child entries) to build (NOT NULL)
9acd494b 2320 * @parent: the parent dentry in the securityfs
63e2b423 2321 *
a481f4d9 2322 * Use entry_remove_dir to remove entries created with this fn.
63e2b423 2323 */
c97204ba
JJ
2324static int __init entry_create_dir(struct aa_sfs_entry *fs_dir,
2325 struct dentry *parent)
63e2b423 2326{
c97204ba 2327 struct aa_sfs_entry *fs_file;
0d259f04
JJ
2328 struct dentry *dir;
2329 int error;
63e2b423 2330
0d259f04
JJ
2331 dir = securityfs_create_dir(fs_dir->name, parent);
2332 if (IS_ERR(dir))
2333 return PTR_ERR(dir);
2334 fs_dir->dentry = dir;
63e2b423 2335
0d259f04 2336 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
c97204ba 2337 if (fs_file->v_type == AA_SFS_TYPE_DIR)
a481f4d9 2338 error = entry_create_dir(fs_file, fs_dir->dentry);
9acd494b 2339 else
a481f4d9 2340 error = entry_create_file(fs_file, fs_dir->dentry);
9acd494b
KC
2341 if (error)
2342 goto failed;
2343 }
2344
2345 return 0;
2346
2347failed:
a481f4d9 2348 entry_remove_dir(fs_dir);
0d259f04 2349
9acd494b
KC
2350 return error;
2351}
2352
2353/**
c97204ba
JJ
2354 * entry_remove_file - drop a single file entry in the apparmor securityfs
2355 * @fs_file: aa_sfs_entry to detach from the securityfs (NOT NULL)
9acd494b 2356 */
c97204ba 2357static void __init entry_remove_file(struct aa_sfs_entry *fs_file)
9acd494b
KC
2358{
2359 if (!fs_file->dentry)
2360 return;
2361
2362 securityfs_remove(fs_file->dentry);
2363 fs_file->dentry = NULL;
2364}
2365
2366/**
a481f4d9 2367 * entry_remove_dir - recursively drop a directory entry from the securityfs
c97204ba 2368 * @fs_dir: aa_sfs_entry (and all child entries) to detach (NOT NULL)
9acd494b 2369 */
c97204ba 2370static void __init entry_remove_dir(struct aa_sfs_entry *fs_dir)
9acd494b 2371{
c97204ba 2372 struct aa_sfs_entry *fs_file;
9acd494b 2373
0d259f04 2374 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
c97204ba 2375 if (fs_file->v_type == AA_SFS_TYPE_DIR)
a481f4d9 2376 entry_remove_dir(fs_file);
9acd494b 2377 else
c97204ba 2378 entry_remove_file(fs_file);
9acd494b
KC
2379 }
2380
c97204ba 2381 entry_remove_file(fs_dir);
63e2b423
JJ
2382}
2383
2384/**
2385 * aa_destroy_aafs - cleanup and free aafs
2386 *
2387 * releases dentries allocated by aa_create_aafs
2388 */
2389void __init aa_destroy_aafs(void)
2390{
c97204ba 2391 entry_remove_dir(&aa_sfs_entry);
63e2b423
JJ
2392}
2393
a71ada30
JJ
2394
2395#define NULL_FILE_NAME ".null"
2396struct path aa_null;
2397
2398static int aa_mk_null_file(struct dentry *parent)
2399{
2400 struct vfsmount *mount = NULL;
2401 struct dentry *dentry;
2402 struct inode *inode;
2403 int count = 0;
2404 int error = simple_pin_fs(parent->d_sb->s_type, &mount, &count);
2405
2406 if (error)
2407 return error;
2408
2409 inode_lock(d_inode(parent));
2410 dentry = lookup_one_len(NULL_FILE_NAME, parent, strlen(NULL_FILE_NAME));
2411 if (IS_ERR(dentry)) {
2412 error = PTR_ERR(dentry);
2413 goto out;
2414 }
2415 inode = new_inode(parent->d_inode->i_sb);
2416 if (!inode) {
2417 error = -ENOMEM;
2418 goto out1;
2419 }
2420
2421 inode->i_ino = get_next_ino();
2422 inode->i_mode = S_IFCHR | S_IRUGO | S_IWUGO;
24d0d03c 2423 inode->i_atime = inode->i_mtime = inode->i_ctime = current_time(inode);
a71ada30
JJ
2424 init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO,
2425 MKDEV(MEM_MAJOR, 3));
2426 d_instantiate(dentry, inode);
2427 aa_null.dentry = dget(dentry);
2428 aa_null.mnt = mntget(mount);
2429
2430 error = 0;
2431
2432out1:
2433 dput(dentry);
2434out:
2435 inode_unlock(d_inode(parent));
2436 simple_release_fs(&mount, &count);
2437 return error;
2438}
2439
a481f4d9
JJ
2440
2441
2442static const char *policy_get_link(struct dentry *dentry,
2443 struct inode *inode,
2444 struct delayed_call *done)
2445{
2446 struct aa_ns *ns;
2447 struct path path;
2448
2449 if (!dentry)
2450 return ERR_PTR(-ECHILD);
2451 ns = aa_get_current_ns();
2452 path.mnt = mntget(aafs_mnt);
2453 path.dentry = dget(ns_dir(ns));
2454 nd_jump_link(&path);
2455 aa_put_ns(ns);
2456
2457 return NULL;
2458}
2459
a481f4d9
JJ
2460static int policy_readlink(struct dentry *dentry, char __user *buffer,
2461 int buflen)
2462{
a481f4d9
JJ
2463 char name[32];
2464 int res;
2465
a0781209
JJ
2466 res = snprintf(name, sizeof(name), "%s:[%lu]", AAFS_NAME,
2467 d_inode(dentry)->i_ino);
2468 if (res > 0 && res < sizeof(name))
a481f4d9 2469 res = readlink_copy(buffer, buflen, name);
a0781209
JJ
2470 else
2471 res = -ENOENT;
a481f4d9
JJ
2472
2473 return res;
2474}
2475
2476static const struct inode_operations policy_link_iops = {
2477 .readlink = policy_readlink,
2478 .get_link = policy_get_link,
2479};
2480
2481
63e2b423
JJ
2482/**
2483 * aa_create_aafs - create the apparmor security filesystem
2484 *
2485 * dentries created here are released by aa_destroy_aafs
2486 *
2487 * Returns: error on failure
2488 */
3417d8d5 2489static int __init aa_create_aafs(void)
63e2b423 2490{
b7fd2c03 2491 struct dentry *dent;
63e2b423
JJ
2492 int error;
2493
2494 if (!apparmor_initialized)
2495 return 0;
2496
c97204ba 2497 if (aa_sfs_entry.dentry) {
63e2b423
JJ
2498 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
2499 return -EEXIST;
2500 }
2501
a481f4d9
JJ
2502 /* setup apparmorfs used to virtualize policy/ */
2503 aafs_mnt = kern_mount(&aafs_ops);
2504 if (IS_ERR(aafs_mnt))
2505 panic("can't set apparmorfs up\n");
1751e8a6 2506 aafs_mnt->mnt_sb->s_flags &= ~SB_NOUSER;
a481f4d9 2507
9acd494b 2508 /* Populate fs tree. */
c97204ba 2509 error = entry_create_dir(&aa_sfs_entry, NULL);
63e2b423
JJ
2510 if (error)
2511 goto error;
2512
c97204ba 2513 dent = securityfs_create_file(".load", 0666, aa_sfs_entry.dentry,
b7fd2c03 2514 NULL, &aa_fs_profile_load);
cf916000
JJ
2515 if (IS_ERR(dent))
2516 goto dent_error;
b7fd2c03
JJ
2517 ns_subload(root_ns) = dent;
2518
c97204ba 2519 dent = securityfs_create_file(".replace", 0666, aa_sfs_entry.dentry,
b7fd2c03 2520 NULL, &aa_fs_profile_replace);
cf916000
JJ
2521 if (IS_ERR(dent))
2522 goto dent_error;
b7fd2c03
JJ
2523 ns_subreplace(root_ns) = dent;
2524
c97204ba 2525 dent = securityfs_create_file(".remove", 0666, aa_sfs_entry.dentry,
b7fd2c03 2526 NULL, &aa_fs_profile_remove);
cf916000
JJ
2527 if (IS_ERR(dent))
2528 goto dent_error;
b7fd2c03
JJ
2529 ns_subremove(root_ns) = dent;
2530
d9bf2c26
JJ
2531 dent = securityfs_create_file("revision", 0444, aa_sfs_entry.dentry,
2532 NULL, &aa_fs_ns_revision_fops);
cf916000
JJ
2533 if (IS_ERR(dent))
2534 goto dent_error;
d9bf2c26
JJ
2535 ns_subrevision(root_ns) = dent;
2536
2537 /* policy tree referenced by magic policy symlink */
feb3c766 2538 mutex_lock_nested(&root_ns->lock, root_ns->level);
c961ee5f
JJ
2539 error = __aafs_ns_mkdir(root_ns, aafs_mnt->mnt_root, ".policy",
2540 aafs_mnt->mnt_root);
b7fd2c03 2541 mutex_unlock(&root_ns->lock);
0d259f04
JJ
2542 if (error)
2543 goto error;
2544
c961ee5f
JJ
2545 /* magic symlink similar to nsfs redirects based on task policy */
2546 dent = securityfs_create_symlink("policy", aa_sfs_entry.dentry,
2547 NULL, &policy_link_iops);
cf916000
JJ
2548 if (IS_ERR(dent))
2549 goto dent_error;
c961ee5f 2550
c97204ba 2551 error = aa_mk_null_file(aa_sfs_entry.dentry);
a71ada30
JJ
2552 if (error)
2553 goto error;
2554
2555 /* TODO: add default profile to apparmorfs */
63e2b423
JJ
2556
2557 /* Report that AppArmor fs is enabled */
2558 aa_info_message("AppArmor Filesystem Enabled");
2559 return 0;
2560
cf916000
JJ
2561dent_error:
2562 error = PTR_ERR(dent);
63e2b423
JJ
2563error:
2564 aa_destroy_aafs();
2565 AA_ERROR("Error creating AppArmor securityfs\n");
2566 return error;
2567}
2568
2569fs_initcall(aa_create_aafs);