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