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