0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/tty.h>
0012 #include <linux/fdtable.h>
0013 #include <linux/file.h>
0014 #include <linux/fs.h>
0015 #include <linux/mount.h>
0016
0017 #include "include/apparmor.h"
0018 #include "include/audit.h"
0019 #include "include/cred.h"
0020 #include "include/file.h"
0021 #include "include/match.h"
0022 #include "include/net.h"
0023 #include "include/path.h"
0024 #include "include/policy.h"
0025 #include "include/label.h"
0026
0027 static u32 map_mask_to_chr_mask(u32 mask)
0028 {
0029 u32 m = mask & PERMS_CHRS_MASK;
0030
0031 if (mask & AA_MAY_GETATTR)
0032 m |= MAY_READ;
0033 if (mask & (AA_MAY_SETATTR | AA_MAY_CHMOD | AA_MAY_CHOWN))
0034 m |= MAY_WRITE;
0035
0036 return m;
0037 }
0038
0039
0040
0041
0042
0043
0044 static void file_audit_cb(struct audit_buffer *ab, void *va)
0045 {
0046 struct common_audit_data *sa = va;
0047 kuid_t fsuid = current_fsuid();
0048 char str[10];
0049
0050 if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
0051 aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
0052 map_mask_to_chr_mask(aad(sa)->request));
0053 audit_log_format(ab, " requested_mask=\"%s\"", str);
0054 }
0055 if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
0056 aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
0057 map_mask_to_chr_mask(aad(sa)->denied));
0058 audit_log_format(ab, " denied_mask=\"%s\"", str);
0059 }
0060 if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
0061 audit_log_format(ab, " fsuid=%d",
0062 from_kuid(&init_user_ns, fsuid));
0063 audit_log_format(ab, " ouid=%d",
0064 from_kuid(&init_user_ns, aad(sa)->fs.ouid));
0065 }
0066
0067 if (aad(sa)->peer) {
0068 audit_log_format(ab, " target=");
0069 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
0070 FLAG_VIEW_SUBNS, GFP_KERNEL);
0071 } else if (aad(sa)->fs.target) {
0072 audit_log_format(ab, " target=");
0073 audit_log_untrustedstring(ab, aad(sa)->fs.target);
0074 }
0075 }
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms,
0093 const char *op, u32 request, const char *name,
0094 const char *target, struct aa_label *tlabel,
0095 kuid_t ouid, const char *info, int error)
0096 {
0097 int type = AUDIT_APPARMOR_AUTO;
0098 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, op);
0099
0100 sa.u.tsk = NULL;
0101 aad(&sa)->request = request;
0102 aad(&sa)->name = name;
0103 aad(&sa)->fs.target = target;
0104 aad(&sa)->peer = tlabel;
0105 aad(&sa)->fs.ouid = ouid;
0106 aad(&sa)->info = info;
0107 aad(&sa)->error = error;
0108 sa.u.tsk = NULL;
0109
0110 if (likely(!aad(&sa)->error)) {
0111 u32 mask = perms->audit;
0112
0113 if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL))
0114 mask = 0xffff;
0115
0116
0117 aad(&sa)->request &= mask;
0118
0119 if (likely(!aad(&sa)->request))
0120 return 0;
0121 type = AUDIT_APPARMOR_AUDIT;
0122 } else {
0123
0124 aad(&sa)->request = aad(&sa)->request & ~perms->allow;
0125 AA_BUG(!aad(&sa)->request);
0126
0127 if (aad(&sa)->request & perms->kill)
0128 type = AUDIT_APPARMOR_KILL;
0129
0130
0131 if ((aad(&sa)->request & perms->quiet) &&
0132 AUDIT_MODE(profile) != AUDIT_NOQUIET &&
0133 AUDIT_MODE(profile) != AUDIT_ALL)
0134 aad(&sa)->request &= ~perms->quiet;
0135
0136 if (!aad(&sa)->request)
0137 return aad(&sa)->error;
0138 }
0139
0140 aad(&sa)->denied = aad(&sa)->request & ~perms->allow;
0141 return aa_audit(type, profile, &sa, file_audit_cb);
0142 }
0143
0144
0145
0146
0147
0148
0149
0150 static inline bool is_deleted(struct dentry *dentry)
0151 {
0152 if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0)
0153 return true;
0154 return false;
0155 }
0156
0157 static int path_name(const char *op, struct aa_label *label,
0158 const struct path *path, int flags, char *buffer,
0159 const char **name, struct path_cond *cond, u32 request)
0160 {
0161 struct aa_profile *profile;
0162 const char *info = NULL;
0163 int error;
0164
0165 error = aa_path_name(path, flags, buffer, name, &info,
0166 labels_profile(label)->disconnected);
0167 if (error) {
0168 fn_for_each_confined(label, profile,
0169 aa_audit_file(profile, &nullperms, op, request, *name,
0170 NULL, NULL, cond->uid, info, error));
0171 return error;
0172 }
0173
0174 return 0;
0175 }
0176
0177
0178
0179
0180
0181
0182
0183 static u32 map_old_perms(u32 old)
0184 {
0185 u32 new = old & 0xf;
0186 if (old & MAY_READ)
0187 new |= AA_MAY_GETATTR | AA_MAY_OPEN;
0188 if (old & MAY_WRITE)
0189 new |= AA_MAY_SETATTR | AA_MAY_CREATE | AA_MAY_DELETE |
0190 AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_OPEN;
0191 if (old & 0x10)
0192 new |= AA_MAY_LINK;
0193
0194
0195
0196 if (old & 0x20)
0197 new |= AA_MAY_LOCK | AA_LINK_SUBSET;
0198 if (old & 0x40)
0199 new |= AA_EXEC_MMAP;
0200
0201 return new;
0202 }
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 struct aa_perms aa_compute_fperms(struct aa_dfa *dfa, unsigned int state,
0216 struct path_cond *cond)
0217 {
0218
0219
0220
0221
0222
0223 struct aa_perms perms = { };
0224
0225 if (uid_eq(current_fsuid(), cond->uid)) {
0226 perms.allow = map_old_perms(dfa_user_allow(dfa, state));
0227 perms.audit = map_old_perms(dfa_user_audit(dfa, state));
0228 perms.quiet = map_old_perms(dfa_user_quiet(dfa, state));
0229 perms.xindex = dfa_user_xindex(dfa, state);
0230 } else {
0231 perms.allow = map_old_perms(dfa_other_allow(dfa, state));
0232 perms.audit = map_old_perms(dfa_other_audit(dfa, state));
0233 perms.quiet = map_old_perms(dfa_other_quiet(dfa, state));
0234 perms.xindex = dfa_other_xindex(dfa, state);
0235 }
0236 perms.allow |= AA_MAY_GETATTR;
0237
0238
0239 if (ACCEPT_TABLE(dfa)[state] & 0x80000000)
0240 perms.allow |= AA_MAY_CHANGE_PROFILE;
0241 if (ACCEPT_TABLE(dfa)[state] & 0x40000000)
0242 perms.allow |= AA_MAY_ONEXEC;
0243
0244 return perms;
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 unsigned int aa_str_perms(struct aa_dfa *dfa, unsigned int start,
0258 const char *name, struct path_cond *cond,
0259 struct aa_perms *perms)
0260 {
0261 unsigned int state;
0262 state = aa_dfa_match(dfa, start, name);
0263 *perms = aa_compute_fperms(dfa, state, cond);
0264
0265 return state;
0266 }
0267
0268 int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
0269 u32 request, struct path_cond *cond, int flags,
0270 struct aa_perms *perms)
0271 {
0272 int e = 0;
0273
0274 if (profile_unconfined(profile))
0275 return 0;
0276 aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms);
0277 if (request & ~perms->allow)
0278 e = -EACCES;
0279 return aa_audit_file(profile, perms, op, request, name, NULL, NULL,
0280 cond->uid, NULL, e);
0281 }
0282
0283
0284 static int profile_path_perm(const char *op, struct aa_profile *profile,
0285 const struct path *path, char *buffer, u32 request,
0286 struct path_cond *cond, int flags,
0287 struct aa_perms *perms)
0288 {
0289 const char *name;
0290 int error;
0291
0292 if (profile_unconfined(profile))
0293 return 0;
0294
0295 error = path_name(op, &profile->label, path,
0296 flags | profile->path_flags, buffer, &name, cond,
0297 request);
0298 if (error)
0299 return error;
0300 return __aa_path_perm(op, profile, name, request, cond, flags,
0301 perms);
0302 }
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 int aa_path_perm(const char *op, struct aa_label *label,
0316 const struct path *path, int flags, u32 request,
0317 struct path_cond *cond)
0318 {
0319 struct aa_perms perms = {};
0320 struct aa_profile *profile;
0321 char *buffer = NULL;
0322 int error;
0323
0324 flags |= PATH_DELEGATE_DELETED | (S_ISDIR(cond->mode) ? PATH_IS_DIR :
0325 0);
0326 buffer = aa_get_buffer(false);
0327 if (!buffer)
0328 return -ENOMEM;
0329 error = fn_for_each_confined(label, profile,
0330 profile_path_perm(op, profile, path, buffer, request,
0331 cond, flags, &perms));
0332
0333 aa_put_buffer(buffer);
0334
0335 return error;
0336 }
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349 static inline bool xindex_is_subset(u32 link, u32 target)
0350 {
0351 if (((link & ~AA_X_UNSAFE) != (target & ~AA_X_UNSAFE)) ||
0352 ((link & AA_X_UNSAFE) && !(target & AA_X_UNSAFE)))
0353 return false;
0354
0355 return true;
0356 }
0357
0358 static int profile_path_link(struct aa_profile *profile,
0359 const struct path *link, char *buffer,
0360 const struct path *target, char *buffer2,
0361 struct path_cond *cond)
0362 {
0363 const char *lname, *tname = NULL;
0364 struct aa_perms lperms = {}, perms;
0365 const char *info = NULL;
0366 u32 request = AA_MAY_LINK;
0367 unsigned int state;
0368 int error;
0369
0370 error = path_name(OP_LINK, &profile->label, link, profile->path_flags,
0371 buffer, &lname, cond, AA_MAY_LINK);
0372 if (error)
0373 goto audit;
0374
0375
0376 error = path_name(OP_LINK, &profile->label, target, profile->path_flags,
0377 buffer2, &tname, cond, AA_MAY_LINK);
0378 if (error)
0379 goto audit;
0380
0381 error = -EACCES;
0382
0383 state = aa_str_perms(profile->file.dfa, profile->file.start, lname,
0384 cond, &lperms);
0385
0386 if (!(lperms.allow & AA_MAY_LINK))
0387 goto audit;
0388
0389
0390 state = aa_dfa_null_transition(profile->file.dfa, state);
0391 aa_str_perms(profile->file.dfa, state, tname, cond, &perms);
0392
0393
0394
0395
0396 lperms.audit = perms.audit;
0397 lperms.quiet = perms.quiet;
0398 lperms.kill = perms.kill;
0399
0400 if (!(perms.allow & AA_MAY_LINK)) {
0401 info = "target restricted";
0402 lperms = perms;
0403 goto audit;
0404 }
0405
0406
0407 if (!(perms.allow & AA_LINK_SUBSET))
0408 goto done_tests;
0409
0410
0411
0412
0413 aa_str_perms(profile->file.dfa, profile->file.start, tname, cond,
0414 &perms);
0415
0416
0417 request = lperms.allow & ~AA_MAY_LINK;
0418 lperms.allow &= perms.allow | AA_MAY_LINK;
0419
0420 request |= AA_AUDIT_FILE_MASK & (lperms.allow & ~perms.allow);
0421 if (request & ~lperms.allow) {
0422 goto audit;
0423 } else if ((lperms.allow & MAY_EXEC) &&
0424 !xindex_is_subset(lperms.xindex, perms.xindex)) {
0425 lperms.allow &= ~MAY_EXEC;
0426 request |= MAY_EXEC;
0427 info = "link not subset of target";
0428 goto audit;
0429 }
0430
0431 done_tests:
0432 error = 0;
0433
0434 audit:
0435 return aa_audit_file(profile, &lperms, OP_LINK, request, lname, tname,
0436 NULL, cond->uid, info, error);
0437 }
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457 int aa_path_link(struct aa_label *label, struct dentry *old_dentry,
0458 const struct path *new_dir, struct dentry *new_dentry)
0459 {
0460 struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry };
0461 struct path target = { .mnt = new_dir->mnt, .dentry = old_dentry };
0462 struct path_cond cond = {
0463 d_backing_inode(old_dentry)->i_uid,
0464 d_backing_inode(old_dentry)->i_mode
0465 };
0466 char *buffer = NULL, *buffer2 = NULL;
0467 struct aa_profile *profile;
0468 int error;
0469
0470
0471 buffer = aa_get_buffer(false);
0472 buffer2 = aa_get_buffer(false);
0473 error = -ENOMEM;
0474 if (!buffer || !buffer2)
0475 goto out;
0476
0477 error = fn_for_each_confined(label, profile,
0478 profile_path_link(profile, &link, buffer, &target,
0479 buffer2, &cond));
0480 out:
0481 aa_put_buffer(buffer);
0482 aa_put_buffer(buffer2);
0483 return error;
0484 }
0485
0486 static void update_file_ctx(struct aa_file_ctx *fctx, struct aa_label *label,
0487 u32 request)
0488 {
0489 struct aa_label *l, *old;
0490
0491
0492 spin_lock(&fctx->lock);
0493 old = rcu_dereference_protected(fctx->label,
0494 lockdep_is_held(&fctx->lock));
0495 l = aa_label_merge(old, label, GFP_ATOMIC);
0496 if (l) {
0497 if (l != old) {
0498 rcu_assign_pointer(fctx->label, l);
0499 aa_put_label(old);
0500 } else
0501 aa_put_label(l);
0502 fctx->allow |= request;
0503 }
0504 spin_unlock(&fctx->lock);
0505 }
0506
0507 static int __file_path_perm(const char *op, struct aa_label *label,
0508 struct aa_label *flabel, struct file *file,
0509 u32 request, u32 denied, bool in_atomic)
0510 {
0511 struct aa_profile *profile;
0512 struct aa_perms perms = {};
0513 struct path_cond cond = {
0514 .uid = i_uid_into_mnt(file_mnt_user_ns(file), file_inode(file)),
0515 .mode = file_inode(file)->i_mode
0516 };
0517 char *buffer;
0518 int flags, error;
0519
0520
0521 if (!denied && aa_label_is_subset(flabel, label))
0522
0523 return 0;
0524
0525 flags = PATH_DELEGATE_DELETED | (S_ISDIR(cond.mode) ? PATH_IS_DIR : 0);
0526 buffer = aa_get_buffer(in_atomic);
0527 if (!buffer)
0528 return -ENOMEM;
0529
0530
0531 error = fn_for_each_not_in_set(flabel, label, profile,
0532 profile_path_perm(op, profile, &file->f_path, buffer,
0533 request, &cond, flags, &perms));
0534 if (denied && !error) {
0535
0536
0537
0538
0539
0540
0541
0542
0543 if (label == flabel)
0544 error = fn_for_each(label, profile,
0545 profile_path_perm(op, profile, &file->f_path,
0546 buffer, request, &cond, flags,
0547 &perms));
0548 else
0549 error = fn_for_each_not_in_set(label, flabel, profile,
0550 profile_path_perm(op, profile, &file->f_path,
0551 buffer, request, &cond, flags,
0552 &perms));
0553 }
0554 if (!error)
0555 update_file_ctx(file_ctx(file), label, request);
0556
0557 aa_put_buffer(buffer);
0558
0559 return error;
0560 }
0561
0562 static int __file_sock_perm(const char *op, struct aa_label *label,
0563 struct aa_label *flabel, struct file *file,
0564 u32 request, u32 denied)
0565 {
0566 struct socket *sock = (struct socket *) file->private_data;
0567 int error;
0568
0569 AA_BUG(!sock);
0570
0571
0572 if (!denied && aa_label_is_subset(flabel, label))
0573 return 0;
0574
0575
0576 error = aa_sock_file_perm(label, op, request, sock);
0577 if (denied) {
0578
0579
0580 last_error(error, aa_sock_file_perm(flabel, op, request, sock));
0581 }
0582 if (!error)
0583 update_file_ctx(file_ctx(file), label, request);
0584
0585 return error;
0586 }
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598 int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
0599 u32 request, bool in_atomic)
0600 {
0601 struct aa_file_ctx *fctx;
0602 struct aa_label *flabel;
0603 u32 denied;
0604 int error = 0;
0605
0606 AA_BUG(!label);
0607 AA_BUG(!file);
0608
0609 fctx = file_ctx(file);
0610
0611 rcu_read_lock();
0612 flabel = rcu_dereference(fctx->label);
0613 AA_BUG(!flabel);
0614
0615
0616
0617
0618
0619
0620
0621
0622 denied = request & ~fctx->allow;
0623 if (unconfined(label) || unconfined(flabel) ||
0624 (!denied && aa_label_is_subset(flabel, label))) {
0625 rcu_read_unlock();
0626 goto done;
0627 }
0628
0629 flabel = aa_get_newest_label(flabel);
0630 rcu_read_unlock();
0631
0632
0633 if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry))
0634 error = __file_path_perm(op, label, flabel, file, request,
0635 denied, in_atomic);
0636
0637 else if (S_ISSOCK(file_inode(file)->i_mode))
0638 error = __file_sock_perm(op, label, flabel, file, request,
0639 denied);
0640 aa_put_label(flabel);
0641
0642 done:
0643 return error;
0644 }
0645
0646 static void revalidate_tty(struct aa_label *label)
0647 {
0648 struct tty_struct *tty;
0649 int drop_tty = 0;
0650
0651 tty = get_current_tty();
0652 if (!tty)
0653 return;
0654
0655 spin_lock(&tty->files_lock);
0656 if (!list_empty(&tty->tty_files)) {
0657 struct tty_file_private *file_priv;
0658 struct file *file;
0659
0660 file_priv = list_first_entry(&tty->tty_files,
0661 struct tty_file_private, list);
0662 file = file_priv->file;
0663
0664 if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE,
0665 IN_ATOMIC))
0666 drop_tty = 1;
0667 }
0668 spin_unlock(&tty->files_lock);
0669 tty_kref_put(tty);
0670
0671 if (drop_tty)
0672 no_tty();
0673 }
0674
0675 static int match_file(const void *p, struct file *file, unsigned int fd)
0676 {
0677 struct aa_label *label = (struct aa_label *)p;
0678
0679 if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file),
0680 IN_ATOMIC))
0681 return fd + 1;
0682 return 0;
0683 }
0684
0685
0686
0687 void aa_inherit_files(const struct cred *cred, struct files_struct *files)
0688 {
0689 struct aa_label *label = aa_get_newest_cred_label(cred);
0690 struct file *devnull = NULL;
0691 unsigned int n;
0692
0693 revalidate_tty(label);
0694
0695
0696 n = iterate_fd(files, 0, match_file, label);
0697 if (!n)
0698 goto out;
0699
0700 devnull = dentry_open(&aa_null, O_RDWR, cred);
0701 if (IS_ERR(devnull))
0702 devnull = NULL;
0703
0704 do {
0705 replace_fd(n - 1, devnull, 0);
0706 } while ((n = iterate_fd(files, n, match_file, label)) != 0);
0707 if (devnull)
0708 fput(devnull);
0709 out:
0710 aa_put_label(label);
0711 }