1 /* 2 * AppArmor security module 3 * 4 * This file contains AppArmor mediation of files 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/tty.h> 16 #include <linux/fdtable.h> 17 #include <linux/file.h> 18 19 #include "include/apparmor.h" 20 #include "include/audit.h" 21 #include "include/context.h" 22 #include "include/file.h" 23 #include "include/match.h" 24 #include "include/path.h" 25 #include "include/policy.h" 26 #include "include/label.h" 27 28 static u32 map_mask_to_chr_mask(u32 mask) 29 { 30 u32 m = mask & PERMS_CHRS_MASK; 31 32 if (mask & AA_MAY_GETATTR) 33 m |= MAY_READ; 34 if (mask & (AA_MAY_SETATTR | AA_MAY_CHMOD | AA_MAY_CHOWN)) 35 m |= MAY_WRITE; 36 37 return m; 38 } 39 40 /** 41 * audit_file_mask - convert mask to permission string 42 * @buffer: buffer to write string to (NOT NULL) 43 * @mask: permission mask to convert 44 */ 45 static void audit_file_mask(struct audit_buffer *ab, u32 mask) 46 { 47 char str[10]; 48 49 aa_perm_mask_to_str(str, aa_file_perm_chrs, map_mask_to_chr_mask(mask)); 50 audit_log_string(ab, str); 51 } 52 53 /** 54 * file_audit_cb - call back for file specific audit fields 55 * @ab: audit_buffer (NOT NULL) 56 * @va: audit struct to audit values of (NOT NULL) 57 */ 58 static void file_audit_cb(struct audit_buffer *ab, void *va) 59 { 60 struct common_audit_data *sa = va; 61 kuid_t fsuid = current_fsuid(); 62 63 if (aad(sa)->request & AA_AUDIT_FILE_MASK) { 64 audit_log_format(ab, " requested_mask="); 65 audit_file_mask(ab, aad(sa)->request); 66 } 67 if (aad(sa)->denied & AA_AUDIT_FILE_MASK) { 68 audit_log_format(ab, " denied_mask="); 69 audit_file_mask(ab, aad(sa)->denied); 70 } 71 if (aad(sa)->request & AA_AUDIT_FILE_MASK) { 72 audit_log_format(ab, " fsuid=%d", 73 from_kuid(&init_user_ns, fsuid)); 74 audit_log_format(ab, " ouid=%d", 75 from_kuid(&init_user_ns, aad(sa)->fs.ouid)); 76 } 77 78 if (aad(sa)->peer) { 79 audit_log_format(ab, " target="); 80 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, 81 FLAG_VIEW_SUBNS, GFP_ATOMIC); 82 } else if (aad(sa)->fs.target) { 83 audit_log_format(ab, " target="); 84 audit_log_untrustedstring(ab, aad(sa)->fs.target); 85 } 86 } 87 88 /** 89 * aa_audit_file - handle the auditing of file operations 90 * @profile: the profile being enforced (NOT NULL) 91 * @perms: the permissions computed for the request (NOT NULL) 92 * @op: operation being mediated 93 * @request: permissions requested 94 * @name: name of object being mediated (MAYBE NULL) 95 * @target: name of target (MAYBE NULL) 96 * @tlabel: target label (MAY BE NULL) 97 * @ouid: object uid 98 * @info: extra information message (MAYBE NULL) 99 * @error: 0 if operation allowed else failure error code 100 * 101 * Returns: %0 or error on failure 102 */ 103 int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms, 104 const char *op, u32 request, const char *name, 105 const char *target, struct aa_label *tlabel, 106 kuid_t ouid, const char *info, int error) 107 { 108 int type = AUDIT_APPARMOR_AUTO; 109 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op); 110 111 sa.u.tsk = NULL; 112 aad(&sa)->request = request; 113 aad(&sa)->name = name; 114 aad(&sa)->fs.target = target; 115 aad(&sa)->peer = tlabel; 116 aad(&sa)->fs.ouid = ouid; 117 aad(&sa)->info = info; 118 aad(&sa)->error = error; 119 sa.u.tsk = NULL; 120 121 if (likely(!aad(&sa)->error)) { 122 u32 mask = perms->audit; 123 124 if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL)) 125 mask = 0xffff; 126 127 /* mask off perms that are not being force audited */ 128 aad(&sa)->request &= mask; 129 130 if (likely(!aad(&sa)->request)) 131 return 0; 132 type = AUDIT_APPARMOR_AUDIT; 133 } else { 134 /* only report permissions that were denied */ 135 aad(&sa)->request = aad(&sa)->request & ~perms->allow; 136 AA_BUG(!aad(&sa)->request); 137 138 if (aad(&sa)->request & perms->kill) 139 type = AUDIT_APPARMOR_KILL; 140 141 /* quiet known rejects, assumes quiet and kill do not overlap */ 142 if ((aad(&sa)->request & perms->quiet) && 143 AUDIT_MODE(profile) != AUDIT_NOQUIET && 144 AUDIT_MODE(profile) != AUDIT_ALL) 145 aad(&sa)->request &= ~perms->quiet; 146 147 if (!aad(&sa)->request) 148 return aad(&sa)->error; 149 } 150 151 aad(&sa)->denied = aad(&sa)->request & ~perms->allow; 152 return aa_audit(type, profile, &sa, file_audit_cb); 153 } 154 155 /** 156 * is_deleted - test if a file has been completely unlinked 157 * @dentry: dentry of file to test for deletion (NOT NULL) 158 * 159 * Returns: %1 if deleted else %0 160 */ 161 static inline bool is_deleted(struct dentry *dentry) 162 { 163 if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0) 164 return 1; 165 return 0; 166 } 167 168 static int path_name(const char *op, struct aa_label *label, 169 const struct path *path, int flags, char *buffer, 170 const char **name, struct path_cond *cond, u32 request) 171 { 172 struct aa_profile *profile; 173 const char *info = NULL; 174 int error; 175 176 error = aa_path_name(path, flags, buffer, name, &info, 177 labels_profile(label)->disconnected); 178 if (error) { 179 fn_for_each_confined(label, profile, 180 aa_audit_file(profile, &nullperms, op, request, *name, 181 NULL, NULL, cond->uid, info, error)); 182 return error; 183 } 184 185 return 0; 186 } 187 188 /** 189 * map_old_perms - map old file perms layout to the new layout 190 * @old: permission set in old mapping 191 * 192 * Returns: new permission mapping 193 */ 194 static u32 map_old_perms(u32 old) 195 { 196 u32 new = old & 0xf; 197 if (old & MAY_READ) 198 new |= AA_MAY_GETATTR | AA_MAY_OPEN; 199 if (old & MAY_WRITE) 200 new |= AA_MAY_SETATTR | AA_MAY_CREATE | AA_MAY_DELETE | 201 AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_OPEN; 202 if (old & 0x10) 203 new |= AA_MAY_LINK; 204 /* the old mapping lock and link_subset flags where overlaid 205 * and use was determined by part of a pair that they were in 206 */ 207 if (old & 0x20) 208 new |= AA_MAY_LOCK | AA_LINK_SUBSET; 209 if (old & 0x40) /* AA_EXEC_MMAP */ 210 new |= AA_EXEC_MMAP; 211 212 return new; 213 } 214 215 /** 216 * aa_compute_fperms - convert dfa compressed perms to internal perms 217 * @dfa: dfa to compute perms for (NOT NULL) 218 * @state: state in dfa 219 * @cond: conditions to consider (NOT NULL) 220 * 221 * TODO: convert from dfa + state to permission entry, do computation conversion 222 * at load time. 223 * 224 * Returns: computed permission set 225 */ 226 struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state, 227 struct path_cond *cond) 228 { 229 /* FIXME: change over to new dfa format 230 * currently file perms are encoded in the dfa, new format 231 * splits the permissions from the dfa. This mapping can be 232 * done at profile load 233 */ 234 struct aa_perms perms = { }; 235 236 if (uid_eq(current_fsuid(), cond->uid)) { 237 perms.allow = map_old_perms(dfa_user_allow(dfa, state)); 238 perms.audit = map_old_perms(dfa_user_audit(dfa, state)); 239 perms.quiet = map_old_perms(dfa_user_quiet(dfa, state)); 240 perms.xindex = dfa_user_xindex(dfa, state); 241 } else { 242 perms.allow = map_old_perms(dfa_other_allow(dfa, state)); 243 perms.audit = map_old_perms(dfa_other_audit(dfa, state)); 244 perms.quiet = map_old_perms(dfa_other_quiet(dfa, state)); 245 perms.xindex = dfa_other_xindex(dfa, state); 246 } 247 perms.allow |= AA_MAY_GETATTR; 248 249 /* change_profile wasn't determined by ownership in old mapping */ 250 if (ACCEPT_TABLE(dfa)[state] & 0x80000000) 251 perms.allow |= AA_MAY_CHANGE_PROFILE; 252 if (ACCEPT_TABLE(dfa)[state] & 0x40000000) 253 perms.allow |= AA_MAY_ONEXEC; 254 255 return perms; 256 } 257 258 /** 259 * aa_str_perms - find permission that match @name 260 * @dfa: to match against (MAYBE NULL) 261 * @state: state to start matching in 262 * @name: string to match against dfa (NOT NULL) 263 * @cond: conditions to consider for permission set computation (NOT NULL) 264 * @perms: Returns - the permissions found when matching @name 265 * 266 * Returns: the final state in @dfa when beginning @start and walking @name 267 */ 268 unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start, 269 const char *name, struct path_cond *cond, 270 struct aa_perms *perms) 271 { 272 unsigned int state; 273 state = aa_dfa_match(dfa, start, name); 274 *perms = aa_compute_fperms(dfa, state, cond); 275 276 return state; 277 } 278 279 int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name, 280 u32 request, struct path_cond *cond, int flags, 281 struct aa_perms *perms) 282 { 283 int e = 0; 284 285 if (profile_unconfined(profile)) 286 return 0; 287 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms); 288 if (request & ~perms->allow) 289 e = -EACCES; 290 return aa_audit_file(profile, perms, op, request, name, NULL, NULL, 291 cond->uid, NULL, e); 292 } 293 294 295 static int profile_path_perm(const char *op, struct aa_profile *profile, 296 const struct path *path, char *buffer, u32 request, 297 struct path_cond *cond, int flags, 298 struct aa_perms *perms) 299 { 300 const char *name; 301 int error; 302 303 if (profile_unconfined(profile)) 304 return 0; 305 306 error = path_name(op, &profile->label, path, 307 flags | profile->path_flags, buffer, &name, cond, 308 request); 309 if (error) 310 return error; 311 return __aa_path_perm(op, profile, name, request, cond, flags, 312 perms); 313 } 314 315 /** 316 * aa_path_perm - do permissions check & audit for @path 317 * @op: operation being checked 318 * @label: profile being enforced (NOT NULL) 319 * @path: path to check permissions of (NOT NULL) 320 * @flags: any additional path flags beyond what the profile specifies 321 * @request: requested permissions 322 * @cond: conditional info for this request (NOT NULL) 323 * 324 * Returns: %0 else error if access denied or other error 325 */ 326 int aa_path_perm(const char *op, struct aa_label *label, 327 const struct path *path, int flags, u32 request, 328 struct path_cond *cond) 329 { 330 struct aa_perms perms = {}; 331 struct aa_profile *profile; 332 char *buffer = NULL; 333 int error; 334 335 flags |= PATH_DELEGATE_DELETED | (S_ISDIR(cond->mode) ? PATH_IS_DIR : 336 0); 337 get_buffers(buffer); 338 error = fn_for_each_confined(label, profile, 339 profile_path_perm(op, profile, path, buffer, request, 340 cond, flags, &perms)); 341 342 put_buffers(buffer); 343 344 return error; 345 } 346 347 /** 348 * xindex_is_subset - helper for aa_path_link 349 * @link: link permission set 350 * @target: target permission set 351 * 352 * test target x permissions are equal OR a subset of link x permissions 353 * this is done as part of the subset test, where a hardlink must have 354 * a subset of permissions that the target has. 355 * 356 * Returns: %1 if subset else %0 357 */ 358 static inline bool xindex_is_subset(u32 link, u32 target) 359 { 360 if (((link & ~AA_X_UNSAFE) != (target & ~AA_X_UNSAFE)) || 361 ((link & AA_X_UNSAFE) && !(target & AA_X_UNSAFE))) 362 return 0; 363 364 return 1; 365 } 366 367 static int profile_path_link(struct aa_profile *profile, 368 const struct path *link, char *buffer, 369 const struct path *target, char *buffer2, 370 struct path_cond *cond) 371 { 372 const char *lname, *tname = NULL; 373 struct aa_perms lperms = {}, perms; 374 const char *info = NULL; 375 u32 request = AA_MAY_LINK; 376 unsigned int state; 377 int error; 378 379 error = path_name(OP_LINK, &profile->label, link, profile->path_flags, 380 buffer, &lname, cond, AA_MAY_LINK); 381 if (error) 382 goto audit; 383 384 /* buffer2 freed below, tname is pointer in buffer2 */ 385 error = path_name(OP_LINK, &profile->label, target, profile->path_flags, 386 buffer2, &tname, cond, AA_MAY_LINK); 387 if (error) 388 goto audit; 389 390 error = -EACCES; 391 /* aa_str_perms - handles the case of the dfa being NULL */ 392 state = aa_str_perms(profile->file.dfa, profile->file.start, lname, 393 cond, &lperms); 394 395 if (!(lperms.allow & AA_MAY_LINK)) 396 goto audit; 397 398 /* test to see if target can be paired with link */ 399 state = aa_dfa_null_transition(profile->file.dfa, state); 400 aa_str_perms(profile->file.dfa, state, tname, cond, &perms); 401 402 /* force audit/quiet masks for link are stored in the second entry 403 * in the link pair. 404 */ 405 lperms.audit = perms.audit; 406 lperms.quiet = perms.quiet; 407 lperms.kill = perms.kill; 408 409 if (!(perms.allow & AA_MAY_LINK)) { 410 info = "target restricted"; 411 lperms = perms; 412 goto audit; 413 } 414 415 /* done if link subset test is not required */ 416 if (!(perms.allow & AA_LINK_SUBSET)) 417 goto done_tests; 418 419 /* Do link perm subset test requiring allowed permission on link are 420 * a subset of the allowed permissions on target. 421 */ 422 aa_str_perms(profile->file.dfa, profile->file.start, tname, cond, 423 &perms); 424 425 /* AA_MAY_LINK is not considered in the subset test */ 426 request = lperms.allow & ~AA_MAY_LINK; 427 lperms.allow &= perms.allow | AA_MAY_LINK; 428 429 request |= AA_AUDIT_FILE_MASK & (lperms.allow & ~perms.allow); 430 if (request & ~lperms.allow) { 431 goto audit; 432 } else if ((lperms.allow & MAY_EXEC) && 433 !xindex_is_subset(lperms.xindex, perms.xindex)) { 434 lperms.allow &= ~MAY_EXEC; 435 request |= MAY_EXEC; 436 info = "link not subset of target"; 437 goto audit; 438 } 439 440 done_tests: 441 error = 0; 442 443 audit: 444 return aa_audit_file(profile, &lperms, OP_LINK, request, lname, tname, 445 NULL, cond->uid, info, error); 446 } 447 448 /** 449 * aa_path_link - Handle hard link permission check 450 * @label: the label being enforced (NOT NULL) 451 * @old_dentry: the target dentry (NOT NULL) 452 * @new_dir: directory the new link will be created in (NOT NULL) 453 * @new_dentry: the link being created (NOT NULL) 454 * 455 * Handle the permission test for a link & target pair. Permission 456 * is encoded as a pair where the link permission is determined 457 * first, and if allowed, the target is tested. The target test 458 * is done from the point of the link match (not start of DFA) 459 * making the target permission dependent on the link permission match. 460 * 461 * The subset test if required forces that permissions granted 462 * on link are a subset of the permission granted to target. 463 * 464 * Returns: %0 if allowed else error 465 */ 466 int aa_path_link(struct aa_label *label, struct dentry *old_dentry, 467 const struct path *new_dir, struct dentry *new_dentry) 468 { 469 struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry }; 470 struct path target = { .mnt = new_dir->mnt, .dentry = old_dentry }; 471 struct path_cond cond = { 472 d_backing_inode(old_dentry)->i_uid, 473 d_backing_inode(old_dentry)->i_mode 474 }; 475 char *buffer = NULL, *buffer2 = NULL; 476 struct aa_profile *profile; 477 int error; 478 479 /* buffer freed below, lname is pointer in buffer */ 480 get_buffers(buffer, buffer2); 481 error = fn_for_each_confined(label, profile, 482 profile_path_link(profile, &link, buffer, &target, 483 buffer2, &cond)); 484 put_buffers(buffer, buffer2); 485 486 return error; 487 } 488 489 static void update_file_ctx(struct aa_file_ctx *fctx, struct aa_label *label, 490 u32 request) 491 { 492 struct aa_label *l, *old; 493 494 /* update caching of label on file_ctx */ 495 spin_lock(&fctx->lock); 496 old = rcu_dereference_protected(fctx->label, 497 spin_is_locked(&fctx->lock)); 498 l = aa_label_merge(old, label, GFP_ATOMIC); 499 if (l) { 500 if (l != old) { 501 rcu_assign_pointer(fctx->label, l); 502 aa_put_label(old); 503 } else 504 aa_put_label(l); 505 fctx->allow |= request; 506 } 507 spin_unlock(&fctx->lock); 508 } 509 510 static int __file_path_perm(const char *op, struct aa_label *label, 511 struct aa_label *flabel, struct file *file, 512 u32 request, u32 denied) 513 { 514 struct aa_profile *profile; 515 struct aa_perms perms = {}; 516 struct path_cond cond = { 517 .uid = file_inode(file)->i_uid, 518 .mode = file_inode(file)->i_mode 519 }; 520 char *buffer; 521 int flags, error; 522 523 /* revalidation due to label out of date. No revocation at this time */ 524 if (!denied && aa_label_is_subset(flabel, label)) 525 /* TODO: check for revocation on stale profiles */ 526 return 0; 527 528 flags = PATH_DELEGATE_DELETED | (S_ISDIR(cond.mode) ? PATH_IS_DIR : 0); 529 get_buffers(buffer); 530 531 /* check every profile in task label not in current cache */ 532 error = fn_for_each_not_in_set(flabel, label, profile, 533 profile_path_perm(op, profile, &file->f_path, buffer, 534 request, &cond, flags, &perms)); 535 if (denied && !error) { 536 /* 537 * check every profile in file label that was not tested 538 * in the initial check above. 539 * 540 * TODO: cache full perms so this only happens because of 541 * conditionals 542 * TODO: don't audit here 543 */ 544 if (label == flabel) 545 error = fn_for_each(label, profile, 546 profile_path_perm(op, profile, &file->f_path, 547 buffer, request, &cond, flags, 548 &perms)); 549 else 550 error = fn_for_each_not_in_set(label, flabel, profile, 551 profile_path_perm(op, profile, &file->f_path, 552 buffer, request, &cond, flags, 553 &perms)); 554 } 555 if (!error) 556 update_file_ctx(file_ctx(file), label, request); 557 558 put_buffers(buffer); 559 560 return error; 561 } 562 563 /** 564 * aa_file_perm - do permission revalidation check & audit for @file 565 * @op: operation being checked 566 * @label: label being enforced (NOT NULL) 567 * @file: file to revalidate access permissions on (NOT NULL) 568 * @request: requested permissions 569 * 570 * Returns: %0 if access allowed else error 571 */ 572 int aa_file_perm(const char *op, struct aa_label *label, struct file *file, 573 u32 request) 574 { 575 struct aa_file_ctx *fctx; 576 struct aa_label *flabel; 577 u32 denied; 578 int error = 0; 579 580 AA_BUG(!label); 581 AA_BUG(!file); 582 583 fctx = file_ctx(file); 584 585 rcu_read_lock(); 586 flabel = rcu_dereference(fctx->label); 587 AA_BUG(!flabel); 588 589 /* revalidate access, if task is unconfined, or the cached cred 590 * doesn't match or if the request is for more permissions than 591 * was granted. 592 * 593 * Note: the test for !unconfined(flabel) is to handle file 594 * delegation from unconfined tasks 595 */ 596 denied = request & ~fctx->allow; 597 if (unconfined(label) || unconfined(flabel) || 598 (!denied && aa_label_is_subset(flabel, label))) 599 goto done; 600 601 /* TODO: label cross check */ 602 603 if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry)) 604 error = __file_path_perm(op, label, flabel, file, request, 605 denied); 606 607 done: 608 rcu_read_unlock(); 609 610 return error; 611 } 612 613 static void revalidate_tty(struct aa_label *label) 614 { 615 struct tty_struct *tty; 616 int drop_tty = 0; 617 618 tty = get_current_tty(); 619 if (!tty) 620 return; 621 622 spin_lock(&tty->files_lock); 623 if (!list_empty(&tty->tty_files)) { 624 struct tty_file_private *file_priv; 625 struct file *file; 626 /* TODO: Revalidate access to controlling tty. */ 627 file_priv = list_first_entry(&tty->tty_files, 628 struct tty_file_private, list); 629 file = file_priv->file; 630 631 if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE)) 632 drop_tty = 1; 633 } 634 spin_unlock(&tty->files_lock); 635 tty_kref_put(tty); 636 637 if (drop_tty) 638 no_tty(); 639 } 640 641 static int match_file(const void *p, struct file *file, unsigned int fd) 642 { 643 struct aa_label *label = (struct aa_label *)p; 644 645 if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file))) 646 return fd + 1; 647 return 0; 648 } 649 650 651 /* based on selinux's flush_unauthorized_files */ 652 void aa_inherit_files(const struct cred *cred, struct files_struct *files) 653 { 654 struct aa_label *label = aa_get_newest_cred_label(cred); 655 struct file *devnull = NULL; 656 unsigned int n; 657 658 revalidate_tty(label); 659 660 /* Revalidate access to inherited open files. */ 661 n = iterate_fd(files, 0, match_file, label); 662 if (!n) /* none found? */ 663 goto out; 664 665 devnull = dentry_open(&aa_null, O_RDWR, cred); 666 if (IS_ERR(devnull)) 667 devnull = NULL; 668 /* replace all the matching ones with this */ 669 do { 670 replace_fd(n - 1, devnull, 0); 671 } while ((n = iterate_fd(files, n, match_file, label)) != 0); 672 if (devnull) 673 fput(devnull); 674 out: 675 aa_put_label(label); 676 } 677