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