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