]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - security/apparmor/apparmorfs.c
apparmor: add __aa_find_ns fn
[mirror_ubuntu-zesty-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>
80594fc2 21#include <linux/mount.h>
63e2b423 22#include <linux/namei.h>
e74abcf3 23#include <linux/capability.h>
29b3822f 24#include <linux/rcupdate.h>
80594fc2 25#include <uapi/linux/major.h>
63e2b423
JJ
26
27#include "include/apparmor.h"
28#include "include/apparmorfs.h"
29#include "include/audit.h"
30#include "include/context.h"
f8eb8a13 31#include "include/crypto.h"
80594fc2
JJ
32#include "include/ipc.h"
33#include "include/policy_ns.h"
34#include "include/label.h"
63e2b423 35#include "include/policy.h"
d384b0a1 36#include "include/resource.h"
80594fc2 37#include "include/lib.h"
3b8ad847 38#include "include/policy_unpack.h"
63e2b423 39
0d259f04
JJ
40/**
41 * aa_mangle_name - mangle a profile name to std profile layout form
42 * @name: profile name to mangle (NOT NULL)
43 * @target: buffer to store mangled name, same length as @name (MAYBE NULL)
44 *
45 * Returns: length of mangled name
46 */
80594fc2 47static int mangle_name(const char *name, char *target)
0d259f04
JJ
48{
49 char *t = target;
50
51 while (*name == '/' || *name == '.')
52 name++;
53
54 if (target) {
55 for (; *name; name++) {
56 if (*name == '/')
57 *(t)++ = '.';
58 else if (isspace(*name))
59 *(t)++ = '_';
60 else if (isalnum(*name) || strchr("._-", *name))
61 *(t)++ = *name;
62 }
63
64 *t = 0;
65 } else {
66 int len = 0;
67 for (; *name; name++) {
68 if (isalnum(*name) || isspace(*name) ||
69 strchr("/._-", *name))
70 len++;
71 }
72
73 return len;
74 }
75
76 return t - target;
77}
78
63e2b423
JJ
79/**
80 * aa_simple_write_to_buffer - common routine for getting policy from user
63e2b423 81 * @userbuf: user buffer to copy data from (NOT NULL)
3ed02ada 82 * @alloc_size: size of user buffer (REQUIRES: @alloc_size >= @copy_size)
63e2b423
JJ
83 * @copy_size: size of data to copy from user buffer
84 * @pos: position write is at in the file (NOT NULL)
85 *
86 * Returns: kernel buffer containing copy of user buffer data or an
87 * ERR_PTR on failure.
88 */
3b8ad847
JJ
89static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf,
90 size_t alloc_size,
91 size_t copy_size,
92 loff_t *pos)
63e2b423 93{
3b8ad847 94 struct aa_loaddata *data;
63e2b423 95
3ed02ada
JJ
96 BUG_ON(copy_size > alloc_size);
97
63e2b423
JJ
98 if (*pos != 0)
99 /* only writes from pos 0, that is complete writes */
100 return ERR_PTR(-ESPIPE);
101
63e2b423 102 /* freed by caller to simple_write_to_buffer */
3b8ad847 103 data = kvmalloc(sizeof(*data) + alloc_size);
63e2b423
JJ
104 if (data == NULL)
105 return ERR_PTR(-ENOMEM);
3b8ad847
JJ
106 kref_init(&data->count);
107 data->size = copy_size;
108 data->hash = NULL;
109 data->abi = 0;
63e2b423 110
3b8ad847 111 if (copy_from_user(data->data, userbuf, copy_size)) {
63e2b423
JJ
112 kvfree(data);
113 return ERR_PTR(-EFAULT);
114 }
115
116 return data;
117}
118
80594fc2
JJ
119static ssize_t policy_update(u32 mask, const char __user *buf, size_t size,
120 loff_t *pos)
63e2b423 121{
80594fc2 122 struct aa_label *label;
63e2b423 123 ssize_t error;
3b8ad847 124 struct aa_loaddata *data;
63e2b423 125
80594fc2 126 label = aa_begin_current_label(DO_UPDATE);
63e2b423 127
80594fc2
JJ
128 /* high level check about policy management - fine grained in
129 * below after unpack
130 */
131 error = aa_may_manage_policy(label, mask);
132 if (error)
133 return error;
134
135 data = aa_simple_write_to_buffer(buf, size, size, pos);
63e2b423
JJ
136 error = PTR_ERR(data);
137 if (!IS_ERR(data)) {
3b8ad847
JJ
138 error = aa_replace_profiles(label, mask, data);
139 aa_put_loaddata(data);
63e2b423 140 }
80594fc2 141 aa_end_current_label(label);
63e2b423
JJ
142
143 return error;
144}
145
80594fc2
JJ
146/* .load file hook fn to load policy */
147static ssize_t profile_load(struct file *f, const char __user *buf, size_t size,
148 loff_t *pos)
149{
150 return policy_update(AA_MAY_LOAD_POLICY, buf, size, pos);
151}
152
63e2b423 153static const struct file_operations aa_fs_profile_load = {
6038f373
AB
154 .write = profile_load,
155 .llseek = default_llseek,
63e2b423
JJ
156};
157
158/* .replace file hook fn to load and/or replace policy */
159static ssize_t profile_replace(struct file *f, const char __user *buf,
160 size_t size, loff_t *pos)
161{
80594fc2
JJ
162 return policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY,
163 buf, size, pos);
63e2b423
JJ
164}
165
166static const struct file_operations aa_fs_profile_replace = {
6038f373
AB
167 .write = profile_replace,
168 .llseek = default_llseek,
63e2b423
JJ
169};
170
171/* .remove file hook fn to remove loaded policy */
172static ssize_t profile_remove(struct file *f, const char __user *buf,
173 size_t size, loff_t *pos)
174{
3b8ad847 175 struct aa_loaddata *data;
80594fc2 176 struct aa_label *label;
63e2b423 177 ssize_t error;
80594fc2
JJ
178
179 label = aa_begin_current_label(DO_UPDATE);
180 /* high level check about policy management - fine grained in
181 * below after unpack
182 */
183 error = aa_may_manage_policy(label, AA_MAY_REMOVE_POLICY);
184 if (error)
185 return error;
63e2b423
JJ
186
187 /*
188 * aa_remove_profile needs a null terminated string so 1 extra
189 * byte is allocated and the copied data is null terminated.
190 */
80594fc2 191 data = aa_simple_write_to_buffer(buf, size + 1, size, pos);
63e2b423
JJ
192
193 error = PTR_ERR(data);
194 if (!IS_ERR(data)) {
3b8ad847
JJ
195 data->data[size] = 0;
196 error = aa_remove_profiles(label, data->data, size);
197 aa_put_loaddata(data);
63e2b423 198 }
80594fc2 199 aa_end_current_label(label);
63e2b423
JJ
200
201 return error;
202}
203
204static const struct file_operations aa_fs_profile_remove = {
6038f373
AB
205 .write = profile_remove,
206 .llseek = default_llseek,
63e2b423
JJ
207};
208
80594fc2
JJ
209
210static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
211 const char *match_str, size_t match_len)
212{
213 struct aa_perms tmp;
214 struct aa_dfa *dfa;
215 unsigned int state = 0;
216
217 if (profile_unconfined(profile))
218 return;
219 if (profile->file.dfa && *match_str == AA_CLASS_FILE) {
220 dfa = profile->file.dfa;
221 state = aa_dfa_match_len(dfa, profile->file.start,
222 match_str + 1, match_len - 1);
223 tmp = nullperms;
224 if (state) {
225 struct path_cond cond = { };
226 tmp = aa_compute_fperms(dfa, state, &cond);
227 }
228 } else if (profile->policy.dfa) {
229 if (!PROFILE_MEDIATES_SAFE(profile, *match_str))
230 return; /* no change to current perms */
231 dfa = profile->policy.dfa;
232 state = aa_dfa_match_len(dfa, profile->policy.start[0],
233 match_str, match_len);
234 if (state)
235 aa_compute_perms(dfa, state, &tmp);
236 else
237 tmp = nullperms;
238 }
239 aa_apply_modes_to_perms(profile, &tmp);
240 aa_perms_accum_raw(perms, &tmp);
241}
242
b7370901
WH
243/**
244 * query_data - queries a policy and writes its data to buf
245 * @buf: the resulting data is stored here (NOT NULL)
246 * @buf_len: size of buf
247 * @query: query string used to retrieve data
248 * @query_len: size of query including second NUL byte
249 *
250 * The buffers pointed to by buf and query may overlap. The query buffer is
251 * parsed before buf is written to.
252 *
253 * The query should look like "<LABEL>\0<KEY>\0", where <LABEL> is the name of
254 * the security confinement context and <KEY> is the name of the data to
255 * retrieve. <LABEL> and <KEY> must not be NUL-terminated.
256 *
257 * Don't expect the contents of buf to be preserved on failure.
258 *
259 * Returns: number of characters written to buf or -errno on failure
260 */
261static ssize_t query_data(char *buf, size_t buf_len,
262 char *query, size_t query_len)
263{
264 char *out;
265 const char *key;
266 struct label_it i;
267 struct aa_label *label, *curr;
268 struct aa_profile *profile;
269 struct aa_data *data;
270 u32 bytes;
271 u32 blocks;
272 u32 size;
273
274 if (!query_len)
275 return -EINVAL; /* need a query */
276
277 key = query + strnlen(query, query_len) + 1;
278 if (key + 1 >= query + query_len)
279 return -EINVAL; /* not enough space for a non-empty key */
280 if (key + strnlen(key, query + query_len - key) >= query + query_len)
281 return -EINVAL; /* must end with NUL */
282
283 if (buf_len < sizeof(bytes) + sizeof(blocks))
284 return -EINVAL; /* not enough space */
285
286 curr = aa_begin_current_label(DO_UPDATE);
287 label = aa_label_parse(curr, query, GFP_KERNEL, false, false);
288 aa_end_current_label(curr);
289 if (IS_ERR(label))
290 return PTR_ERR(label);
291
292 /* We are going to leave space for two numbers. The first is the total
293 * number of bytes we are writing after the first number. This is so
294 * users can read the full output without reallocation.
295 *
296 * The second number is the number of data blocks we're writing. An
297 * application might be confined by multiple policies having data in
298 * the same key.
299 */
300 memset(buf, 0, sizeof(bytes) + sizeof(blocks));
301 out = buf + sizeof(bytes) + sizeof(blocks);
302
303 blocks = 0;
304 label_for_each_confined(i, label, profile) {
305 if (!profile->data)
306 continue;
307
308 data = rhashtable_lookup_fast(profile->data, &key,
309 profile->data->p);
310
311 if (data) {
312 if (out + sizeof(size) + data->size > buf + buf_len) {
313 aa_put_label(label);
314 return -EINVAL; /* not enough space */
315 }
316 size = __cpu_to_le32(data->size);
317 memcpy(out, &size, sizeof(size));
318 out += sizeof(size);
319 memcpy(out, data->data, data->size);
320 out += data->size;
321 blocks++;
322 }
323 }
324 aa_put_label(label);
325
326 bytes = out - buf - sizeof(bytes);
327 bytes = __cpu_to_le32(bytes);
328 blocks = __cpu_to_le32(blocks);
329 memcpy(buf, &bytes, sizeof(bytes));
330 memcpy(buf + sizeof(bytes), &blocks, sizeof(blocks));
331
332 return out - buf;
333}
334
80594fc2
JJ
335/**
336 * query_label - queries a label and writes permissions to buf
337 * @buf: the resulting permissions string is stored here (NOT NULL)
338 * @buf_len: size of buf
339 * @query: binary query string to match against the dfa
340 * @query_len: size of query
341 *
342 * The buffers pointed to by buf and query may overlap. The query buffer is
343 * parsed before buf is written to.
344 *
345 * The query should look like "LABEL_NAME\0DFA_STRING" where LABEL_NAME is
346 * the name of the label, in the current namespace, that is to be queried and
347 * DFA_STRING is a binary string to match against the label(s)'s DFA.
348 *
349 * LABEL_NAME must be NUL terminated. DFA_STRING may contain NUL characters
350 * but must *not* be NUL terminated.
351 *
352 * Returns: number of characters written to buf or -errno on failure
353 */
354static ssize_t query_label(char *buf, size_t buf_len,
355 char *query, size_t query_len, bool ns_only)
356{
357 struct aa_profile *profile;
358 struct aa_label *label, *curr;
359 char *label_name, *match_str;
360 size_t label_name_len, match_len;
361 struct aa_perms perms;
362 struct label_it i;
363
364 if (!query_len)
365 return -EINVAL;
366
367 label_name = query;
368 label_name_len = strnlen(query, query_len);
369 if (!label_name_len || label_name_len == query_len)
370 return -EINVAL;
371
372 /**
373 * The extra byte is to account for the null byte between the
374 * profile name and dfa string. profile_name_len is greater
375 * than zero and less than query_len, so a byte can be safely
376 * added or subtracted.
377 */
378 match_str = label_name + label_name_len + 1;
379 match_len = query_len - label_name_len - 1;
380
381 curr = aa_begin_current_label(DO_UPDATE);
382 label = aa_label_parse(curr, label_name, GFP_KERNEL, false, false);
383 aa_end_current_label(curr);
384 if (IS_ERR(label))
385 return PTR_ERR(label);
386
387 perms = allperms;
388 if (ns_only) {
389 label_for_each_in_ns(i, labels_ns(label), label, profile) {
390 profile_query_cb(profile, &perms, match_str, match_len);
391 }
392 } else {
393 label_for_each(i, label, profile) {
394 profile_query_cb(profile, &perms, match_str, match_len);
395 }
396 }
397 aa_put_label(label);
398
399 return scnprintf(buf, buf_len,
400 "allow 0x%08x\ndeny 0x%08x\naudit 0x%08x\nquiet 0x%08x\n",
401 perms.allow, perms.deny, perms.audit, perms.quiet);
402}
403
404#define QUERY_CMD_LABEL "label\0"
405#define QUERY_CMD_LABEL_LEN 6
406#define QUERY_CMD_PROFILE "profile\0"
407#define QUERY_CMD_PROFILE_LEN 8
408#define QUERY_CMD_LABELALL "labelall\0"
409#define QUERY_CMD_LABELALL_LEN 9
b7370901
WH
410#define QUERY_CMD_DATA "data\0"
411#define QUERY_CMD_DATA_LEN 5
80594fc2
JJ
412
413/**
b7370901 414 * aa_write_access - generic permissions and data query
80594fc2
JJ
415 * @file: pointer to open apparmorfs/access file
416 * @ubuf: user buffer containing the complete query string (NOT NULL)
417 * @count: size of ubuf
418 * @ppos: position in the file (MUST BE ZERO)
419 *
b7370901
WH
420 * Allows for one permissions or data query per open(), write(), and read()
421 * sequence. The only queries currently supported are label-based queries for
422 * permissions or data.
423 *
424 * For permissions queries, ubuf must begin with "label\0", followed by the
425 * profile query specific format described in the query_label() function
426 * documentation.
427 *
428 * For data queries, ubuf must have the form "data\0<LABEL>\0<KEY>\0", where
429 * <LABEL> is the name of the security confinement context and <KEY> is the
430 * name of the data to retrieve.
80594fc2
JJ
431 *
432 * Returns: number of bytes written or -errno on failure
433 */
434static ssize_t aa_write_access(struct file *file, const char __user *ubuf,
435 size_t count, loff_t *ppos)
436{
437 char *buf;
438 ssize_t len;
439
440 if (*ppos)
441 return -ESPIPE;
442
443 buf = simple_transaction_get(file, ubuf, count);
444 if (IS_ERR(buf))
445 return PTR_ERR(buf);
446
447 if (count > QUERY_CMD_PROFILE_LEN &&
448 !memcmp(buf, QUERY_CMD_PROFILE, QUERY_CMD_PROFILE_LEN)) {
449 len = query_label(buf, SIMPLE_TRANSACTION_LIMIT,
450 buf + QUERY_CMD_PROFILE_LEN,
451 count - QUERY_CMD_PROFILE_LEN, true);
452 } else if (count > QUERY_CMD_LABEL_LEN &&
453 !memcmp(buf, QUERY_CMD_LABEL, QUERY_CMD_LABEL_LEN)) {
454 len = query_label(buf, SIMPLE_TRANSACTION_LIMIT,
455 buf + QUERY_CMD_LABEL_LEN,
456 count - QUERY_CMD_LABEL_LEN, true);
457 } else if (count > QUERY_CMD_LABELALL_LEN &&
458 !memcmp(buf, QUERY_CMD_LABELALL, QUERY_CMD_LABELALL_LEN)) {
459 len = query_label(buf, SIMPLE_TRANSACTION_LIMIT,
460 buf + QUERY_CMD_LABELALL_LEN,
461 count - QUERY_CMD_LABELALL_LEN, false);
b7370901
WH
462 } else if (count > QUERY_CMD_DATA_LEN &&
463 !memcmp(buf, QUERY_CMD_DATA, QUERY_CMD_DATA_LEN)) {
464 len = query_data(buf, SIMPLE_TRANSACTION_LIMIT,
465 buf + QUERY_CMD_DATA_LEN,
466 count - QUERY_CMD_DATA_LEN);
80594fc2
JJ
467 } else
468 len = -EINVAL;
469
470 if (len < 0)
471 return len;
472
473 simple_transaction_set(file, len);
474
475 return count;
476}
477
478static const struct file_operations aa_fs_access = {
479 .write = aa_write_access,
480 .read = simple_transaction_read,
481 .release = simple_transaction_release,
482 .llseek = generic_file_llseek,
483};
484
e74abcf3
KC
485static int aa_fs_seq_show(struct seq_file *seq, void *v)
486{
487 struct aa_fs_entry *fs_file = seq->private;
488
489 if (!fs_file)
490 return 0;
491
492 switch (fs_file->v_type) {
493 case AA_FS_TYPE_BOOLEAN:
494 seq_printf(seq, "%s\n", fs_file->v.boolean ? "yes" : "no");
495 break;
a9bf8e9f
KC
496 case AA_FS_TYPE_STRING:
497 seq_printf(seq, "%s\n", fs_file->v.string);
498 break;
e74abcf3
KC
499 case AA_FS_TYPE_U64:
500 seq_printf(seq, "%#08lx\n", fs_file->v.u64);
501 break;
502 default:
503 /* Ignore unpritable entry types. */
504 break;
505 }
506
507 return 0;
508}
509
510static int aa_fs_seq_open(struct inode *inode, struct file *file)
511{
512 return single_open(file, aa_fs_seq_show, inode->i_private);
513}
514
515const struct file_operations aa_fs_seq_file_ops = {
516 .owner = THIS_MODULE,
517 .open = aa_fs_seq_open,
518 .read = seq_read,
519 .llseek = seq_lseek,
520 .release = single_release,
521};
522
0d259f04
JJ
523static int aa_fs_seq_profile_open(struct inode *inode, struct file *file,
524 int (*show)(struct seq_file *, void *))
525{
80594fc2
JJ
526 struct aa_proxy *proxy = aa_get_proxy(inode->i_private);
527 int error = single_open(file, show, proxy);
0d259f04
JJ
528
529 if (error) {
530 file->private_data = NULL;
80594fc2 531 aa_put_proxy(proxy);
0d259f04
JJ
532 }
533
534 return error;
535}
536
537static int aa_fs_seq_profile_release(struct inode *inode, struct file *file)
538{
539 struct seq_file *seq = (struct seq_file *) file->private_data;
540 if (seq)
80594fc2 541 aa_put_proxy(seq->private);
0d259f04
JJ
542 return single_release(inode, file);
543}
544
545static int aa_fs_seq_profname_show(struct seq_file *seq, void *v)
546{
80594fc2
JJ
547 struct aa_proxy *proxy = seq->private;
548 struct aa_label *label = aa_get_label_rcu(&proxy->label);
549 struct aa_profile *profile = labels_profile(label);
0d259f04 550 seq_printf(seq, "%s\n", profile->base.name);
80594fc2 551 aa_put_label(label);
0d259f04
JJ
552
553 return 0;
554}
555
556static int aa_fs_seq_profname_open(struct inode *inode, struct file *file)
557{
558 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profname_show);
559}
560
561static const struct file_operations aa_fs_profname_fops = {
562 .owner = THIS_MODULE,
563 .open = aa_fs_seq_profname_open,
564 .read = seq_read,
565 .llseek = seq_lseek,
566 .release = aa_fs_seq_profile_release,
567};
568
569static int aa_fs_seq_profmode_show(struct seq_file *seq, void *v)
570{
80594fc2
JJ
571 struct aa_proxy *proxy = seq->private;
572 struct aa_label *label = aa_get_label_rcu(&proxy->label);
573 struct aa_profile *profile = labels_profile(label);
0d259f04 574 seq_printf(seq, "%s\n", aa_profile_mode_names[profile->mode]);
80594fc2 575 aa_put_label(label);
0d259f04
JJ
576
577 return 0;
578}
579
580static int aa_fs_seq_profmode_open(struct inode *inode, struct file *file)
581{
582 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profmode_show);
583}
584
585static const struct file_operations aa_fs_profmode_fops = {
586 .owner = THIS_MODULE,
587 .open = aa_fs_seq_profmode_open,
588 .read = seq_read,
589 .llseek = seq_lseek,
590 .release = aa_fs_seq_profile_release,
591};
592
556d0be7
JJ
593static int aa_fs_seq_profattach_show(struct seq_file *seq, void *v)
594{
80594fc2
JJ
595 struct aa_proxy *proxy = seq->private;
596 struct aa_label *label = aa_get_label_rcu(&proxy->label);
597 struct aa_profile *profile = labels_profile(label);
556d0be7
JJ
598 if (profile->attach)
599 seq_printf(seq, "%s\n", profile->attach);
600 else if (profile->xmatch)
601 seq_puts(seq, "<unknown>\n");
602 else
603 seq_printf(seq, "%s\n", profile->base.name);
80594fc2 604 aa_put_label(label);
556d0be7
JJ
605
606 return 0;
607}
608
609static int aa_fs_seq_profattach_open(struct inode *inode, struct file *file)
610{
611 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_profattach_show);
612}
613
614static const struct file_operations aa_fs_profattach_fops = {
615 .owner = THIS_MODULE,
616 .open = aa_fs_seq_profattach_open,
617 .read = seq_read,
618 .llseek = seq_lseek,
619 .release = aa_fs_seq_profile_release,
620};
621
f8eb8a13
JJ
622static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
623{
80594fc2
JJ
624 struct aa_proxy *proxy = seq->private;
625 struct aa_label *label = aa_get_label_rcu(&proxy->label);
626 struct aa_profile *profile = labels_profile(label);
f8eb8a13
JJ
627 unsigned int i, size = aa_hash_size();
628
629 if (profile->hash) {
630 for (i = 0; i < size; i++)
631 seq_printf(seq, "%.2x", profile->hash[i]);
632 seq_puts(seq, "\n");
633 }
80594fc2 634 aa_put_label(label);
f8eb8a13
JJ
635
636 return 0;
637}
638
639static int aa_fs_seq_hash_open(struct inode *inode, struct file *file)
640{
641 return single_open(file, aa_fs_seq_hash_show, inode->i_private);
642}
643
644static const struct file_operations aa_fs_seq_hash_fops = {
645 .owner = THIS_MODULE,
646 .open = aa_fs_seq_hash_open,
647 .read = seq_read,
648 .llseek = seq_lseek,
649 .release = single_release,
650};
651
3b8ad847
JJ
652static int rawdata_release(struct inode *inode, struct file *file)
653{
654 /* TODO: switch to loaddata when profile switched to symlink */
655 aa_put_proxy(file->private_data);
656
657 return 0;
658}
659
660static int aa_fs_seq_raw_abi_show(struct seq_file *seq, void *v)
661{
662 struct aa_proxy *proxy = seq->private;
663 struct aa_label *label = aa_get_label_rcu(&proxy->label);
664 struct aa_profile *profile = labels_profile(label);
665
666 if (profile->rawdata->abi) {
667 seq_printf(seq, "v%d", profile->rawdata->abi);
668 seq_puts(seq, "\n");
669 }
670 aa_put_label(label);
671
672 return 0;
673}
674
675static int aa_fs_seq_raw_abi_open(struct inode *inode, struct file *file)
676{
677 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_raw_abi_show);
678}
679
680static const struct file_operations aa_fs_seq_raw_abi_fops = {
681 .owner = THIS_MODULE,
682 .open = aa_fs_seq_raw_abi_open,
683 .read = seq_read,
684 .llseek = seq_lseek,
685 .release = aa_fs_seq_profile_release,
686};
687
688static int aa_fs_seq_raw_hash_show(struct seq_file *seq, void *v)
689{
690 struct aa_proxy *proxy = seq->private;
691 struct aa_label *label = aa_get_label_rcu(&proxy->label);
692 struct aa_profile *profile = labels_profile(label);
693 unsigned int i, size = aa_hash_size();
694
695 if (profile->rawdata->hash) {
696 for (i = 0; i < size; i++)
697 seq_printf(seq, "%.2x", profile->rawdata->hash[i]);
698 seq_puts(seq, "\n");
699 }
700 aa_put_label(label);
701
702 return 0;
703}
704
705static int aa_fs_seq_raw_hash_open(struct inode *inode, struct file *file)
706{
707 return aa_fs_seq_profile_open(inode, file, aa_fs_seq_raw_hash_show);
708}
709
710static const struct file_operations aa_fs_seq_raw_hash_fops = {
711 .owner = THIS_MODULE,
712 .open = aa_fs_seq_raw_hash_open,
713 .read = seq_read,
714 .llseek = seq_lseek,
715 .release = aa_fs_seq_profile_release,
716};
717
718static ssize_t rawdata_read(struct file *file, char __user *buf, size_t size,
719 loff_t *ppos)
720{
721 struct aa_proxy *proxy = file->private_data;
722 struct aa_label *label = aa_get_label_rcu(&proxy->label);
723 struct aa_profile *profile = labels_profile(label);
724
725 ssize_t ret = simple_read_from_buffer(buf, size, ppos, profile->rawdata->data, profile->rawdata->size);
726 aa_put_label(label);
727
728 return ret;
729}
730
731static int rawdata_open(struct inode *inode, struct file *file)
732{
733 if (!policy_view_capable())
734 return -EACCES;
735
736 file->private_data = aa_get_proxy(inode->i_private);
737
738 return 0;
739}
740
741static const struct file_operations aa_fs_rawdata_fops = {
742 .open = rawdata_open,
743 .read = rawdata_read,
744 .llseek = generic_file_llseek,
745 .release = rawdata_release,
746};
747
0d259f04 748/** fns to setup dynamic per profile/namespace files **/
80594fc2
JJ
749
750/**
751 *
752 * Requires: @profile->ns->lock held
753 */
0d259f04
JJ
754void __aa_fs_profile_rmdir(struct aa_profile *profile)
755{
756 struct aa_profile *child;
757 int i;
758
759 if (!profile)
760 return;
80594fc2 761 AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
0d259f04
JJ
762
763 list_for_each_entry(child, &profile->base.profiles, base.list)
764 __aa_fs_profile_rmdir(child);
765
766 for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) {
80594fc2 767 struct aa_proxy *proxy;
0d259f04
JJ
768 if (!profile->dents[i])
769 continue;
770
80594fc2 771 proxy = d_inode(profile->dents[i])->i_private;
0d259f04 772 securityfs_remove(profile->dents[i]);
80594fc2 773 aa_put_proxy(proxy);
0d259f04
JJ
774 profile->dents[i] = NULL;
775 }
776}
777
80594fc2
JJ
778/**
779 *
780 * Requires: @old->ns->lock held
781 */
0d259f04
JJ
782void __aa_fs_profile_migrate_dents(struct aa_profile *old,
783 struct aa_profile *new)
784{
785 int i;
786
80594fc2
JJ
787 AA_BUG(!old);
788 AA_BUG(!new);
789 AA_BUG(!mutex_is_locked(&profiles_ns(old)->lock));
790
0d259f04
JJ
791 for (i = 0; i < AAFS_PROF_SIZEOF; i++) {
792 new->dents[i] = old->dents[i];
d671e890 793 if (new->dents[i])
078cd827 794 new->dents[i]->d_inode->i_mtime = current_time(new->dents[i]->d_inode);
0d259f04
JJ
795 old->dents[i] = NULL;
796 }
797}
798
799static struct dentry *create_profile_file(struct dentry *dir, const char *name,
800 struct aa_profile *profile,
801 const struct file_operations *fops)
802{
80594fc2 803 struct aa_proxy *proxy = aa_get_proxy(profile->label.proxy);
0d259f04
JJ
804 struct dentry *dent;
805
80594fc2 806 dent = securityfs_create_file(name, S_IFREG | 0444, dir, proxy, fops);
0d259f04 807 if (IS_ERR(dent))
80594fc2 808 aa_put_proxy(proxy);
0d259f04
JJ
809
810 return dent;
811}
812
80594fc2
JJ
813/**
814 *
815 * Requires: @profile->ns->lock held
816 */
0d259f04
JJ
817int __aa_fs_profile_mkdir(struct aa_profile *profile, struct dentry *parent)
818{
819 struct aa_profile *child;
820 struct dentry *dent = NULL, *dir;
821 int error;
822
80594fc2
JJ
823 AA_BUG(!profile);
824 AA_BUG(!mutex_is_locked(&profiles_ns(profile)->lock));
825
0d259f04
JJ
826 if (!parent) {
827 struct aa_profile *p;
828 p = aa_deref_parent(profile);
829 dent = prof_dir(p);
830 /* adding to parent that previously didn't have children */
831 dent = securityfs_create_dir("profiles", dent);
832 if (IS_ERR(dent))
833 goto fail;
834 prof_child_dir(p) = parent = dent;
835 }
836
837 if (!profile->dirname) {
838 int len, id_len;
839 len = mangle_name(profile->base.name, NULL);
840 id_len = snprintf(NULL, 0, ".%ld", profile->ns->uniq_id);
841
842 profile->dirname = kmalloc(len + id_len + 1, GFP_KERNEL);
843 if (!profile->dirname)
844 goto fail;
845
846 mangle_name(profile->base.name, profile->dirname);
847 sprintf(profile->dirname + len, ".%ld", profile->ns->uniq_id++);
848 }
849
850 dent = securityfs_create_dir(profile->dirname, parent);
851 if (IS_ERR(dent))
852 goto fail;
853 prof_dir(profile) = dir = dent;
854
855 dent = create_profile_file(dir, "name", profile, &aa_fs_profname_fops);
856 if (IS_ERR(dent))
857 goto fail;
858 profile->dents[AAFS_PROF_NAME] = dent;
859
860 dent = create_profile_file(dir, "mode", profile, &aa_fs_profmode_fops);
861 if (IS_ERR(dent))
862 goto fail;
863 profile->dents[AAFS_PROF_MODE] = dent;
864
556d0be7
JJ
865 dent = create_profile_file(dir, "attach", profile,
866 &aa_fs_profattach_fops);
867 if (IS_ERR(dent))
868 goto fail;
869 profile->dents[AAFS_PROF_ATTACH] = dent;
870
f8eb8a13
JJ
871 if (profile->hash) {
872 dent = create_profile_file(dir, "sha1", profile,
873 &aa_fs_seq_hash_fops);
874 if (IS_ERR(dent))
875 goto fail;
876 profile->dents[AAFS_PROF_HASH] = dent;
877 }
878
3b8ad847
JJ
879 if (profile->rawdata) {
880 dent = create_profile_file(dir, "raw_hash", profile,
881 &aa_fs_seq_raw_hash_fops);
882 if (IS_ERR(dent))
883 goto fail;
884 profile->dents[AAFS_PROF_RAW_HASH] = dent;
885
886 dent = create_profile_file(dir, "raw_abi", profile,
887 &aa_fs_seq_raw_abi_fops);
888 if (IS_ERR(dent))
889 goto fail;
890 profile->dents[AAFS_PROF_RAW_ABI] = dent;
891
892 dent = securityfs_create_file("raw_data", S_IFREG | 0444, dir,
893 profile->label.proxy,
894 &aa_fs_rawdata_fops);
895 if (IS_ERR(dent))
896 goto fail;
897 profile->dents[AAFS_PROF_RAW_DATA] = dent;
898 d_inode(dent)->i_size = profile->rawdata->size;
899 aa_get_proxy(profile->label.proxy);
900 }
901
0d259f04
JJ
902 list_for_each_entry(child, &profile->base.profiles, base.list) {
903 error = __aa_fs_profile_mkdir(child, prof_child_dir(profile));
904 if (error)
905 goto fail2;
906 }
907
908 return 0;
909
910fail:
911 error = PTR_ERR(dent);
912
913fail2:
914 __aa_fs_profile_rmdir(profile);
915
916 return error;
917}
918
80594fc2
JJ
919/**
920 *
921 * Requires: @ns->lock held
922 */
923void __aa_fs_ns_rmdir(struct aa_ns *ns)
0d259f04 924{
80594fc2 925 struct aa_ns *sub;
0d259f04
JJ
926 struct aa_profile *child;
927 int i;
928
929 if (!ns)
930 return;
80594fc2 931 AA_BUG(!mutex_is_locked(&ns->lock));
0d259f04
JJ
932
933 list_for_each_entry(child, &ns->base.profiles, base.list)
934 __aa_fs_profile_rmdir(child);
935
936 list_for_each_entry(sub, &ns->sub_ns, base.list) {
937 mutex_lock(&sub->lock);
80594fc2 938 __aa_fs_ns_rmdir(sub);
0d259f04
JJ
939 mutex_unlock(&sub->lock);
940 }
941
942 for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) {
943 securityfs_remove(ns->dents[i]);
944 ns->dents[i] = NULL;
945 }
946}
947
80594fc2
JJ
948/**
949 *
950 * Requires: @ns->lock held
951 */
952int __aa_fs_ns_mkdir(struct aa_ns *ns, struct dentry *parent, const char *name)
0d259f04 953{
80594fc2 954 struct aa_ns *sub;
0d259f04
JJ
955 struct aa_profile *child;
956 struct dentry *dent, *dir;
957 int error;
958
80594fc2
JJ
959 AA_BUG(!ns);
960 AA_BUG(!parent);
961 AA_BUG(!mutex_is_locked(&ns->lock));
962
0d259f04
JJ
963 if (!name)
964 name = ns->base.name;
965
966 dent = securityfs_create_dir(name, parent);
967 if (IS_ERR(dent))
968 goto fail;
969 ns_dir(ns) = dir = dent;
970
971 dent = securityfs_create_dir("profiles", dir);
972 if (IS_ERR(dent))
973 goto fail;
974 ns_subprofs_dir(ns) = dent;
63e2b423 975
3b8ad847
JJ
976 dent = securityfs_create_dir("raw_data", dir);
977 if (IS_ERR(dent))
978 goto fail;
979 ns_subdata_dir(ns) = dent;
980
0d259f04
JJ
981 dent = securityfs_create_dir("namespaces", dir);
982 if (IS_ERR(dent))
983 goto fail;
984 ns_subns_dir(ns) = dent;
985
986 list_for_each_entry(child, &ns->base.profiles, base.list) {
987 error = __aa_fs_profile_mkdir(child, ns_subprofs_dir(ns));
988 if (error)
989 goto fail2;
990 }
991
992 list_for_each_entry(sub, &ns->sub_ns, base.list) {
993 mutex_lock(&sub->lock);
80594fc2 994 error = __aa_fs_ns_mkdir(sub, ns_subns_dir(ns), NULL);
0d259f04
JJ
995 mutex_unlock(&sub->lock);
996 if (error)
997 goto fail2;
998 }
999
1000 return 0;
1001
1002fail:
1003 error = PTR_ERR(dent);
1004
1005fail2:
80594fc2 1006 __aa_fs_ns_rmdir(ns);
0d259f04
JJ
1007
1008 return error;
1009}
1010
1011
29b3822f
JJ
1012#define list_entry_is_head(pos, head, member) (&pos->member == (head))
1013
1014/**
80594fc2 1015 * __next_ns - find the next namespace to list
29b3822f
JJ
1016 * @root: root namespace to stop search at (NOT NULL)
1017 * @ns: current ns position (NOT NULL)
1018 *
1019 * Find the next namespace from @ns under @root and handle all locking needed
1020 * while switching current namespace.
1021 *
1022 * Returns: next namespace or NULL if at last namespace under @root
1023 * Requires: ns->parent->lock to be held
1024 * NOTE: will not unlock root->lock
1025 */
80594fc2 1026static struct aa_ns *__next_ns(struct aa_ns *root, struct aa_ns *ns)
29b3822f 1027{
80594fc2
JJ
1028 struct aa_ns *parent, *next;
1029
1030 AA_BUG(!root);
1031 AA_BUG(!ns);
1032 AA_BUG(ns != root && !mutex_is_locked(&ns->parent->lock));
29b3822f
JJ
1033
1034 /* is next namespace a child */
1035 if (!list_empty(&ns->sub_ns)) {
1036 next = list_first_entry(&ns->sub_ns, typeof(*ns), base.list);
1037 mutex_lock(&next->lock);
1038 return next;
1039 }
1040
1041 /* check if the next ns is a sibling, parent, gp, .. */
1042 parent = ns->parent;
ed2c7da3 1043 while (ns != root) {
29b3822f 1044 mutex_unlock(&ns->lock);
38dbd7d8 1045 next = list_next_entry(ns, base.list);
29b3822f
JJ
1046 if (!list_entry_is_head(next, &parent->sub_ns, base.list)) {
1047 mutex_lock(&next->lock);
1048 return next;
1049 }
29b3822f
JJ
1050 ns = parent;
1051 parent = parent->parent;
1052 }
1053
1054 return NULL;
1055}
1056
1057/**
1058 * __first_profile - find the first profile in a namespace
1059 * @root: namespace that is root of profiles being displayed (NOT NULL)
80594fc2 1060 * @ns: namespace to start in (MAY BE NULL)
29b3822f
JJ
1061 *
1062 * Returns: unrefcounted profile or NULL if no profile
80594fc2 1063 * Requires: ns.lock to be held
29b3822f 1064 */
80594fc2 1065static struct aa_profile *__first_profile(struct aa_ns *root, struct aa_ns *ns)
29b3822f 1066{
80594fc2
JJ
1067 AA_BUG(!root);
1068 AA_BUG(ns && !mutex_is_locked(&ns->lock));
1069
1070 for (; ns; ns = __next_ns(root, ns)) {
29b3822f
JJ
1071 if (!list_empty(&ns->base.profiles))
1072 return list_first_entry(&ns->base.profiles,
1073 struct aa_profile, base.list);
1074 }
1075 return NULL;
1076}
1077
1078/**
1079 * __next_profile - step to the next profile in a profile tree
1080 * @profile: current profile in tree (NOT NULL)
1081 *
1082 * Perform a depth first traversal on the profile tree in a namespace
1083 *
1084 * Returns: next profile or NULL if done
1085 * Requires: profile->ns.lock to be held
1086 */
1087static struct aa_profile *__next_profile(struct aa_profile *p)
1088{
1089 struct aa_profile *parent;
80594fc2
JJ
1090 struct aa_ns *ns = p->ns;
1091
1092 AA_BUG(!mutex_is_locked(&profiles_ns(p)->lock));
29b3822f
JJ
1093
1094 /* is next profile a child */
1095 if (!list_empty(&p->base.profiles))
1096 return list_first_entry(&p->base.profiles, typeof(*p),
1097 base.list);
1098
1099 /* is next profile a sibling, parent sibling, gp, sibling, .. */
1100 parent = rcu_dereference_protected(p->parent,
1101 mutex_is_locked(&p->ns->lock));
1102 while (parent) {
38dbd7d8 1103 p = list_next_entry(p, base.list);
29b3822f
JJ
1104 if (!list_entry_is_head(p, &parent->base.profiles, base.list))
1105 return p;
1106 p = parent;
1107 parent = rcu_dereference_protected(parent->parent,
1108 mutex_is_locked(&parent->ns->lock));
1109 }
1110
1111 /* is next another profile in the namespace */
38dbd7d8 1112 p = list_next_entry(p, base.list);
29b3822f
JJ
1113 if (!list_entry_is_head(p, &ns->base.profiles, base.list))
1114 return p;
1115
1116 return NULL;
1117}
1118
1119/**
1120 * next_profile - step to the next profile in where ever it may be
1121 * @root: root namespace (NOT NULL)
1122 * @profile: current profile (NOT NULL)
1123 *
1124 * Returns: next profile or NULL if there isn't one
1125 */
80594fc2 1126static struct aa_profile *next_profile(struct aa_ns *root,
29b3822f
JJ
1127 struct aa_profile *profile)
1128{
1129 struct aa_profile *next = __next_profile(profile);
1130 if (next)
1131 return next;
1132
1133 /* finished all profiles in namespace move to next namespace */
80594fc2 1134 return __first_profile(root, __next_ns(root, profile->ns));
29b3822f
JJ
1135}
1136
1137/**
1138 * p_start - start a depth first traversal of profile tree
1139 * @f: seq_file to fill
1140 * @pos: current position
1141 *
1142 * Returns: first profile under current namespace or NULL if none found
1143 *
1144 * acquires first ns->lock
1145 */
1146static void *p_start(struct seq_file *f, loff_t *pos)
1147{
1148 struct aa_profile *profile = NULL;
80594fc2 1149 struct aa_ns *root = aa_get_current_ns();
29b3822f 1150 loff_t l = *pos;
80594fc2 1151 f->private = root;
29b3822f
JJ
1152
1153 /* find the first profile */
1154 mutex_lock(&root->lock);
1155 profile = __first_profile(root, root);
1156
1157 /* skip to position */
1158 for (; profile && l > 0; l--)
1159 profile = next_profile(root, profile);
1160
1161 return profile;
1162}
1163
1164/**
1165 * p_next - read the next profile entry
1166 * @f: seq_file to fill
1167 * @p: profile previously returned
1168 * @pos: current position
1169 *
1170 * Returns: next profile after @p or NULL if none
1171 *
1172 * may acquire/release locks in namespace tree as necessary
1173 */
1174static void *p_next(struct seq_file *f, void *p, loff_t *pos)
1175{
1176 struct aa_profile *profile = p;
80594fc2 1177 struct aa_ns *ns = f->private;
29b3822f
JJ
1178 (*pos)++;
1179
1180 return next_profile(ns, profile);
1181}
1182
1183/**
1184 * p_stop - stop depth first traversal
1185 * @f: seq_file we are filling
1186 * @p: the last profile writen
1187 *
1188 * Release all locking done by p_start/p_next on namespace tree
1189 */
1190static void p_stop(struct seq_file *f, void *p)
1191{
1192 struct aa_profile *profile = p;
80594fc2 1193 struct aa_ns *root = f->private, *ns;
29b3822f
JJ
1194
1195 if (profile) {
1196 for (ns = profile->ns; ns && ns != root; ns = ns->parent)
1197 mutex_unlock(&ns->lock);
1198 }
1199 mutex_unlock(&root->lock);
80594fc2 1200 aa_put_ns(root);
29b3822f
JJ
1201}
1202
1203/**
1204 * seq_show_profile - show a profile entry
1205 * @f: seq_file to file
1206 * @p: current position (profile) (NOT NULL)
1207 *
1208 * Returns: error on failure
1209 */
1210static int seq_show_profile(struct seq_file *f, void *p)
1211{
1212 struct aa_profile *profile = (struct aa_profile *)p;
80594fc2 1213 struct aa_ns *root = f->private;
29b3822f 1214
80594fc2
JJ
1215 aa_label_seq_xprint(f, root, &profile->label,
1216 FLAG_SHOW_MODE | FLAG_VIEW_SUBNS, GFP_KERNEL);
1217 seq_printf(f, "\n");
29b3822f
JJ
1218
1219 return 0;
1220}
1221
1222static const struct seq_operations aa_fs_profiles_op = {
1223 .start = p_start,
1224 .next = p_next,
1225 .stop = p_stop,
1226 .show = seq_show_profile,
1227};
1228
1229static int profiles_open(struct inode *inode, struct file *file)
1230{
451dc704 1231 if (!policy_view_capable())
80594fc2
JJ
1232 return -EACCES;
1233
29b3822f
JJ
1234 return seq_open(file, &aa_fs_profiles_op);
1235}
1236
1237static int profiles_release(struct inode *inode, struct file *file)
1238{
1239 return seq_release(inode, file);
1240}
1241
1242static const struct file_operations aa_fs_profiles_fops = {
1243 .open = profiles_open,
1244 .read = seq_read,
1245 .llseek = seq_lseek,
1246 .release = profiles_release,
1247};
1248
1249
0d259f04 1250/** Base file system setup **/
a9bf8e9f
KC
1251static struct aa_fs_entry aa_fs_entry_file[] = {
1252 AA_FS_FILE_STRING("mask", "create read write exec append mmap_exec " \
1253 "link lock"),
1254 { }
1255};
1256
80594fc2
JJ
1257static struct aa_fs_entry aa_fs_entry_ptrace[] = {
1258 AA_FS_FILE_STRING("mask", "read trace"),
1259 { }
1260};
1261
1262static struct aa_fs_entry aa_fs_entry_signal[] = {
1263 AA_FS_FILE_STRING("mask", AA_FS_SIG_MASK),
1264 { }
1265};
1266
e74abcf3
KC
1267static struct aa_fs_entry aa_fs_entry_domain[] = {
1268 AA_FS_FILE_BOOLEAN("change_hat", 1),
1269 AA_FS_FILE_BOOLEAN("change_hatv", 1),
1270 AA_FS_FILE_BOOLEAN("change_onexec", 1),
1271 AA_FS_FILE_BOOLEAN("change_profile", 1),
80594fc2 1272 AA_FS_FILE_BOOLEAN("stack", 1),
f5f10a2c 1273 AA_FS_FILE_STRING("version", "1.1"),
80594fc2
JJ
1274 { }
1275};
1276
1277static struct aa_fs_entry aa_fs_entry_versions[] = {
1278 AA_FS_FILE_BOOLEAN("v5", 1),
1279 AA_FS_FILE_BOOLEAN("v6", 1),
1280 AA_FS_FILE_BOOLEAN("v7", 1),
e74abcf3
KC
1281 { }
1282};
1283
9d910a3b 1284static struct aa_fs_entry aa_fs_entry_policy[] = {
80594fc2
JJ
1285 AA_FS_DIR("versions", aa_fs_entry_versions),
1286 AA_FS_FILE_BOOLEAN("set_load", 1),
1287 { }
1288};
1289
1290static struct aa_fs_entry aa_fs_entry_mount[] = {
1291 AA_FS_FILE_STRING("mask", "mount umount"),
1292 { }
1293};
1294
1295static struct aa_fs_entry aa_fs_entry_ns[] = {
1296 AA_FS_FILE_BOOLEAN("profile", 1),
1297 AA_FS_FILE_BOOLEAN("pivot_root", 1),
1298 { }
1299};
1300
1301static struct aa_fs_entry aa_fs_entry_dbus[] = {
1302 AA_FS_FILE_STRING("mask", "acquire send receive"),
1303 { }
9d910a3b
JJ
1304};
1305
e74abcf3 1306static struct aa_fs_entry aa_fs_entry_features[] = {
9d910a3b 1307 AA_FS_DIR("policy", aa_fs_entry_policy),
e74abcf3 1308 AA_FS_DIR("domain", aa_fs_entry_domain),
a9bf8e9f 1309 AA_FS_DIR("file", aa_fs_entry_file),
80594fc2
JJ
1310 AA_FS_DIR("network", aa_fs_entry_network),
1311 AA_FS_DIR("mount", aa_fs_entry_mount),
1312 AA_FS_DIR("namespaces", aa_fs_entry_ns),
e74abcf3 1313 AA_FS_FILE_U64("capability", VFS_CAP_FLAGS_MASK),
d384b0a1 1314 AA_FS_DIR("rlimit", aa_fs_entry_rlimit),
84f1f787 1315 AA_FS_DIR("caps", aa_fs_entry_caps),
80594fc2
JJ
1316 AA_FS_DIR("ptrace", aa_fs_entry_ptrace),
1317 AA_FS_DIR("signal", aa_fs_entry_signal),
1318 AA_FS_DIR("dbus", aa_fs_entry_dbus),
e74abcf3
KC
1319 { }
1320};
1321
9acd494b 1322static struct aa_fs_entry aa_fs_entry_apparmor[] = {
80594fc2
JJ
1323 AA_FS_FILE_FOPS(".load", 0666, &aa_fs_profile_load),
1324 AA_FS_FILE_FOPS(".replace", 0666, &aa_fs_profile_replace),
1325 AA_FS_FILE_FOPS(".remove", 0666, &aa_fs_profile_remove),
1326 AA_FS_FILE_FOPS(".access", 0666, &aa_fs_access),
1327 AA_FS_FILE_FOPS("profiles", 0444, &aa_fs_profiles_fops),
e74abcf3 1328 AA_FS_DIR("features", aa_fs_entry_features),
9acd494b
KC
1329 { }
1330};
63e2b423 1331
9acd494b
KC
1332static struct aa_fs_entry aa_fs_entry =
1333 AA_FS_DIR("apparmor", aa_fs_entry_apparmor);
63e2b423 1334
9acd494b
KC
1335/**
1336 * aafs_create_file - create a file entry in the apparmor securityfs
1337 * @fs_file: aa_fs_entry to build an entry for (NOT NULL)
1338 * @parent: the parent dentry in the securityfs
1339 *
1340 * Use aafs_remove_file to remove entries created with this fn.
1341 */
1342static int __init aafs_create_file(struct aa_fs_entry *fs_file,
1343 struct dentry *parent)
1344{
1345 int error = 0;
1346
1347 fs_file->dentry = securityfs_create_file(fs_file->name,
1348 S_IFREG | fs_file->mode,
1349 parent, fs_file,
1350 fs_file->file_ops);
1351 if (IS_ERR(fs_file->dentry)) {
1352 error = PTR_ERR(fs_file->dentry);
1353 fs_file->dentry = NULL;
63e2b423 1354 }
9acd494b 1355 return error;
63e2b423
JJ
1356}
1357
0d259f04 1358static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir);
63e2b423 1359/**
9acd494b
KC
1360 * aafs_create_dir - recursively create a directory entry in the securityfs
1361 * @fs_dir: aa_fs_entry (and all child entries) to build (NOT NULL)
1362 * @parent: the parent dentry in the securityfs
63e2b423 1363 *
9acd494b 1364 * Use aafs_remove_dir to remove entries created with this fn.
63e2b423 1365 */
9acd494b
KC
1366static int __init aafs_create_dir(struct aa_fs_entry *fs_dir,
1367 struct dentry *parent)
63e2b423 1368{
9acd494b 1369 struct aa_fs_entry *fs_file;
0d259f04
JJ
1370 struct dentry *dir;
1371 int error;
63e2b423 1372
0d259f04
JJ
1373 dir = securityfs_create_dir(fs_dir->name, parent);
1374 if (IS_ERR(dir))
1375 return PTR_ERR(dir);
1376 fs_dir->dentry = dir;
63e2b423 1377
0d259f04 1378 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
9acd494b
KC
1379 if (fs_file->v_type == AA_FS_TYPE_DIR)
1380 error = aafs_create_dir(fs_file, fs_dir->dentry);
1381 else
1382 error = aafs_create_file(fs_file, fs_dir->dentry);
1383 if (error)
1384 goto failed;
1385 }
1386
1387 return 0;
1388
1389failed:
0d259f04
JJ
1390 aafs_remove_dir(fs_dir);
1391
9acd494b
KC
1392 return error;
1393}
1394
1395/**
1396 * aafs_remove_file - drop a single file entry in the apparmor securityfs
1397 * @fs_file: aa_fs_entry to detach from the securityfs (NOT NULL)
1398 */
1399static void __init aafs_remove_file(struct aa_fs_entry *fs_file)
1400{
1401 if (!fs_file->dentry)
1402 return;
1403
1404 securityfs_remove(fs_file->dentry);
1405 fs_file->dentry = NULL;
1406}
1407
1408/**
1409 * aafs_remove_dir - recursively drop a directory entry from the securityfs
1410 * @fs_dir: aa_fs_entry (and all child entries) to detach (NOT NULL)
1411 */
1412static void __init aafs_remove_dir(struct aa_fs_entry *fs_dir)
1413{
1414 struct aa_fs_entry *fs_file;
1415
0d259f04 1416 for (fs_file = fs_dir->v.files; fs_file && fs_file->name; ++fs_file) {
9acd494b
KC
1417 if (fs_file->v_type == AA_FS_TYPE_DIR)
1418 aafs_remove_dir(fs_file);
1419 else
1420 aafs_remove_file(fs_file);
1421 }
1422
1423 aafs_remove_file(fs_dir);
63e2b423
JJ
1424}
1425
1426/**
1427 * aa_destroy_aafs - cleanup and free aafs
1428 *
1429 * releases dentries allocated by aa_create_aafs
1430 */
1431void __init aa_destroy_aafs(void)
1432{
9acd494b 1433 aafs_remove_dir(&aa_fs_entry);
63e2b423
JJ
1434}
1435
80594fc2
JJ
1436
1437#define NULL_FILE_NAME ".null"
1438struct path aa_null;
1439
1440static int aa_mk_null_file(struct dentry *parent)
1441{
1442 struct vfsmount *mount = NULL;
1443 struct dentry *dentry;
1444 struct inode *inode;
1445 int count = 0;
1446 int error = simple_pin_fs(parent->d_sb->s_type, &mount, &count);
1447 if (error)
1448 return error;
1449
1450 inode_lock(d_inode(parent));
1451 dentry = lookup_one_len(NULL_FILE_NAME, parent, strlen(NULL_FILE_NAME));
1452 if (IS_ERR(dentry)) {
1453 error = PTR_ERR(dentry);
1454 goto out;
1455 }
1456 inode = new_inode(parent->d_inode->i_sb);
1457 if (!inode) {
1458 error = -ENOMEM;
1459 goto out1;
1460 }
1461
1462 inode->i_ino = get_next_ino();
1463 inode->i_mode = S_IFCHR | S_IRUGO | S_IWUGO;
1464 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
1465 init_special_inode(inode, S_IFCHR | S_IRUGO | S_IWUGO,
1466 MKDEV(MEM_MAJOR, 3));
1467 d_instantiate(dentry, inode);
1468 aa_null.dentry = dget(dentry);
1469 aa_null.mnt = mntget(mount);
1470
1471 error = 0;
1472
1473out1:
1474 dput(dentry);
1475out:
1476 inode_unlock(d_inode(parent));
1477 simple_release_fs(&mount, &count);
1478 return error;
1479}
1480
63e2b423
JJ
1481/**
1482 * aa_create_aafs - create the apparmor security filesystem
1483 *
1484 * dentries created here are released by aa_destroy_aafs
1485 *
1486 * Returns: error on failure
1487 */
3417d8d5 1488static int __init aa_create_aafs(void)
63e2b423
JJ
1489{
1490 int error;
1491
1492 if (!apparmor_initialized)
1493 return 0;
1494
9acd494b 1495 if (aa_fs_entry.dentry) {
63e2b423
JJ
1496 AA_ERROR("%s: AppArmor securityfs already exists\n", __func__);
1497 return -EEXIST;
1498 }
1499
9acd494b
KC
1500 /* Populate fs tree. */
1501 error = aafs_create_dir(&aa_fs_entry, NULL);
63e2b423
JJ
1502 if (error)
1503 goto error;
1504
80594fc2
JJ
1505 mutex_lock(&root_ns->lock);
1506 error = __aa_fs_ns_mkdir(root_ns, aa_fs_entry.dentry, "policy");
1507 mutex_unlock(&root_ns->lock);
1508
1509 if (error)
1510 goto error;
1511
1512 error = aa_mk_null_file(aa_fs_entry.dentry);
0d259f04
JJ
1513 if (error)
1514 goto error;
1515
80594fc2
JJ
1516 if (!aa_g_unconfined_init) {
1517 /* TODO: add default profile to apparmorfs */
1518 }
63e2b423
JJ
1519
1520 /* Report that AppArmor fs is enabled */
1521 aa_info_message("AppArmor Filesystem Enabled");
1522 return 0;
1523
1524error:
1525 aa_destroy_aafs();
1526 AA_ERROR("Error creating AppArmor securityfs\n");
1527 return error;
1528}
1529
1530fs_initcall(aa_create_aafs);