0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/errno.h>
0012 #include <linux/fdtable.h>
0013 #include <linux/fs.h>
0014 #include <linux/file.h>
0015 #include <linux/mount.h>
0016 #include <linux/syscalls.h>
0017 #include <linux/personality.h>
0018 #include <linux/xattr.h>
0019 #include <linux/user_namespace.h>
0020
0021 #include "include/audit.h"
0022 #include "include/apparmorfs.h"
0023 #include "include/cred.h"
0024 #include "include/domain.h"
0025 #include "include/file.h"
0026 #include "include/ipc.h"
0027 #include "include/match.h"
0028 #include "include/path.h"
0029 #include "include/policy.h"
0030 #include "include/policy_ns.h"
0031
0032
0033
0034
0035
0036 void aa_free_domain_entries(struct aa_domain *domain)
0037 {
0038 int i;
0039 if (domain) {
0040 if (!domain->table)
0041 return;
0042
0043 for (i = 0; i < domain->size; i++)
0044 kfree_sensitive(domain->table[i]);
0045 kfree_sensitive(domain->table);
0046 domain->table = NULL;
0047 }
0048 }
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060 static int may_change_ptraced_domain(struct aa_label *to_label,
0061 const char **info)
0062 {
0063 struct task_struct *tracer;
0064 struct aa_label *tracerl = NULL;
0065 int error = 0;
0066
0067 rcu_read_lock();
0068 tracer = ptrace_parent(current);
0069 if (tracer)
0070
0071 tracerl = aa_get_task_label(tracer);
0072
0073
0074 if (!tracer || unconfined(tracerl))
0075 goto out;
0076
0077 error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH);
0078
0079 out:
0080 rcu_read_unlock();
0081 aa_put_label(tracerl);
0082
0083 if (error)
0084 *info = "ptrace prevents transition";
0085 return error;
0086 }
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098 static inline unsigned int match_component(struct aa_profile *profile,
0099 struct aa_profile *tp,
0100 bool stack, unsigned int state)
0101 {
0102 const char *ns_name;
0103
0104 if (stack)
0105 state = aa_dfa_match(profile->file.dfa, state, "&");
0106 if (profile->ns == tp->ns)
0107 return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
0108
0109
0110 ns_name = aa_ns_name(profile->ns, tp->ns, true);
0111 state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
0112 state = aa_dfa_match(profile->file.dfa, state, ns_name);
0113 state = aa_dfa_match_len(profile->file.dfa, state, ":", 1);
0114 return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
0115 }
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 static int label_compound_match(struct aa_profile *profile,
0134 struct aa_label *label, bool stack,
0135 unsigned int state, bool subns, u32 request,
0136 struct aa_perms *perms)
0137 {
0138 struct aa_profile *tp;
0139 struct label_it i;
0140 struct path_cond cond = { };
0141
0142
0143 label_for_each(i, label, tp) {
0144 if (!aa_ns_visible(profile->ns, tp->ns, subns))
0145 continue;
0146 state = match_component(profile, tp, stack, state);
0147 if (!state)
0148 goto fail;
0149 goto next;
0150 }
0151
0152
0153 *perms = allperms;
0154 return 0;
0155
0156 next:
0157 label_for_each_cont(i, label, tp) {
0158 if (!aa_ns_visible(profile->ns, tp->ns, subns))
0159 continue;
0160 state = aa_dfa_match(profile->file.dfa, state, "//&");
0161 state = match_component(profile, tp, false, state);
0162 if (!state)
0163 goto fail;
0164 }
0165 *perms = aa_compute_fperms(profile->file.dfa, state, &cond);
0166 aa_apply_modes_to_perms(profile, perms);
0167 if ((perms->allow & request) != request)
0168 return -EACCES;
0169
0170 return 0;
0171
0172 fail:
0173 *perms = nullperms;
0174 return -EACCES;
0175 }
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193 static int label_components_match(struct aa_profile *profile,
0194 struct aa_label *label, bool stack,
0195 unsigned int start, bool subns, u32 request,
0196 struct aa_perms *perms)
0197 {
0198 struct aa_profile *tp;
0199 struct label_it i;
0200 struct aa_perms tmp;
0201 struct path_cond cond = { };
0202 unsigned int state = 0;
0203
0204
0205 label_for_each(i, label, tp) {
0206 if (!aa_ns_visible(profile->ns, tp->ns, subns))
0207 continue;
0208 state = match_component(profile, tp, stack, start);
0209 if (!state)
0210 goto fail;
0211 goto next;
0212 }
0213
0214
0215 return 0;
0216
0217 next:
0218 tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
0219 aa_apply_modes_to_perms(profile, &tmp);
0220 aa_perms_accum(perms, &tmp);
0221 label_for_each_cont(i, label, tp) {
0222 if (!aa_ns_visible(profile->ns, tp->ns, subns))
0223 continue;
0224 state = match_component(profile, tp, stack, start);
0225 if (!state)
0226 goto fail;
0227 tmp = aa_compute_fperms(profile->file.dfa, state, &cond);
0228 aa_apply_modes_to_perms(profile, &tmp);
0229 aa_perms_accum(perms, &tmp);
0230 }
0231
0232 if ((perms->allow & request) != request)
0233 return -EACCES;
0234
0235 return 0;
0236
0237 fail:
0238 *perms = nullperms;
0239 return -EACCES;
0240 }
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254 static int label_match(struct aa_profile *profile, struct aa_label *label,
0255 bool stack, unsigned int state, bool subns, u32 request,
0256 struct aa_perms *perms)
0257 {
0258 int error;
0259
0260 *perms = nullperms;
0261 error = label_compound_match(profile, label, stack, state, subns,
0262 request, perms);
0263 if (!error)
0264 return error;
0265
0266 *perms = allperms;
0267 return label_components_match(profile, label, stack, state, subns,
0268 request, perms);
0269 }
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287 static int change_profile_perms(struct aa_profile *profile,
0288 struct aa_label *target, bool stack,
0289 u32 request, unsigned int start,
0290 struct aa_perms *perms)
0291 {
0292 if (profile_unconfined(profile)) {
0293 perms->allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
0294 perms->audit = perms->quiet = perms->kill = 0;
0295 return 0;
0296 }
0297
0298
0299 return label_match(profile, target, stack, start, true, request, perms);
0300 }
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310 static int aa_xattrs_match(const struct linux_binprm *bprm,
0311 struct aa_profile *profile, unsigned int state)
0312 {
0313 int i;
0314 ssize_t size;
0315 struct dentry *d;
0316 char *value = NULL;
0317 int value_size = 0, ret = profile->xattr_count;
0318
0319 if (!bprm || !profile->xattr_count)
0320 return 0;
0321 might_sleep();
0322
0323
0324 state = aa_dfa_outofband_transition(profile->xmatch, state);
0325 d = bprm->file->f_path.dentry;
0326
0327 for (i = 0; i < profile->xattr_count; i++) {
0328 size = vfs_getxattr_alloc(&init_user_ns, d, profile->xattrs[i],
0329 &value, value_size, GFP_KERNEL);
0330 if (size >= 0) {
0331 u32 perm;
0332
0333
0334
0335
0336
0337
0338 state = aa_dfa_null_transition(profile->xmatch, state);
0339
0340 state = aa_dfa_match_len(profile->xmatch, state, value,
0341 size);
0342 perm = dfa_user_allow(profile->xmatch, state);
0343 if (!(perm & MAY_EXEC)) {
0344 ret = -EINVAL;
0345 goto out;
0346 }
0347 }
0348
0349 state = aa_dfa_outofband_transition(profile->xmatch, state);
0350 if (size < 0) {
0351
0352
0353
0354
0355
0356 if (!state) {
0357 ret = -EINVAL;
0358 goto out;
0359 }
0360
0361 ret--;
0362 }
0363 }
0364
0365 out:
0366 kfree(value);
0367 return ret;
0368 }
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387 static struct aa_label *find_attach(const struct linux_binprm *bprm,
0388 struct aa_ns *ns, struct list_head *head,
0389 const char *name, const char **info)
0390 {
0391 int candidate_len = 0, candidate_xattrs = 0;
0392 bool conflict = false;
0393 struct aa_profile *profile, *candidate = NULL;
0394
0395 AA_BUG(!name);
0396 AA_BUG(!head);
0397
0398 rcu_read_lock();
0399 restart:
0400 list_for_each_entry_rcu(profile, head, base.list) {
0401 if (profile->label.flags & FLAG_NULL &&
0402 &profile->label == ns_unconfined(profile->ns))
0403 continue;
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416 if (profile->xmatch) {
0417 unsigned int state, count;
0418 u32 perm;
0419
0420 state = aa_dfa_leftmatch(profile->xmatch, DFA_START,
0421 name, &count);
0422 perm = dfa_user_allow(profile->xmatch, state);
0423
0424 if (perm & MAY_EXEC) {
0425 int ret = 0;
0426
0427 if (count < candidate_len)
0428 continue;
0429
0430 if (bprm && profile->xattr_count) {
0431 long rev = READ_ONCE(ns->revision);
0432
0433 if (!aa_get_profile_not0(profile))
0434 goto restart;
0435 rcu_read_unlock();
0436 ret = aa_xattrs_match(bprm, profile,
0437 state);
0438 rcu_read_lock();
0439 aa_put_profile(profile);
0440 if (rev !=
0441 READ_ONCE(ns->revision))
0442
0443 goto restart;
0444
0445
0446
0447
0448 if (ret < 0)
0449 continue;
0450 }
0451
0452
0453
0454
0455
0456
0457 if (count == candidate_len &&
0458 ret <= candidate_xattrs) {
0459
0460 if (ret == candidate_xattrs)
0461 conflict = true;
0462 continue;
0463 }
0464
0465
0466
0467
0468 candidate = profile;
0469 candidate_len = max(count, profile->xmatch_len);
0470 candidate_xattrs = ret;
0471 conflict = false;
0472 }
0473 } else if (!strcmp(profile->base.name, name)) {
0474
0475
0476
0477
0478 candidate = profile;
0479 goto out;
0480 }
0481 }
0482
0483 if (!candidate || conflict) {
0484 if (conflict)
0485 *info = "conflicting profile attachments";
0486 rcu_read_unlock();
0487 return NULL;
0488 }
0489
0490 out:
0491 candidate = aa_get_newest_profile(candidate);
0492 rcu_read_unlock();
0493
0494 return &candidate->label;
0495 }
0496
0497 static const char *next_name(int xtype, const char *name)
0498 {
0499 return NULL;
0500 }
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510 struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex,
0511 const char **name)
0512 {
0513 struct aa_label *label = NULL;
0514 u32 xtype = xindex & AA_X_TYPE_MASK;
0515 int index = xindex & AA_X_INDEX_MASK;
0516
0517 AA_BUG(!name);
0518
0519
0520
0521
0522
0523 for (*name = profile->file.trans.table[index]; !label && *name;
0524 *name = next_name(xtype, *name)) {
0525 if (xindex & AA_X_CHILD) {
0526 struct aa_profile *new_profile;
0527
0528 new_profile = aa_find_child(profile, *name);
0529 if (new_profile)
0530 label = &new_profile->label;
0531 continue;
0532 }
0533 label = aa_label_parse(&profile->label, *name, GFP_KERNEL,
0534 true, false);
0535 if (IS_ERR(label))
0536 label = NULL;
0537 }
0538
0539
0540
0541 return label;
0542 }
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556 static struct aa_label *x_to_label(struct aa_profile *profile,
0557 const struct linux_binprm *bprm,
0558 const char *name, u32 xindex,
0559 const char **lookupname,
0560 const char **info)
0561 {
0562 struct aa_label *new = NULL;
0563 struct aa_ns *ns = profile->ns;
0564 u32 xtype = xindex & AA_X_TYPE_MASK;
0565 const char *stack = NULL;
0566
0567 switch (xtype) {
0568 case AA_X_NONE:
0569
0570 *lookupname = NULL;
0571 break;
0572 case AA_X_TABLE:
0573
0574 stack = profile->file.trans.table[xindex & AA_X_INDEX_MASK];
0575 if (*stack != '&') {
0576
0577 new = x_table_lookup(profile, xindex, lookupname);
0578 stack = NULL;
0579 break;
0580 }
0581 fallthrough;
0582 case AA_X_NAME:
0583 if (xindex & AA_X_CHILD)
0584
0585 new = find_attach(bprm, ns, &profile->base.profiles,
0586 name, info);
0587 else
0588
0589 new = find_attach(bprm, ns, &ns->base.profiles,
0590 name, info);
0591 *lookupname = name;
0592 break;
0593 }
0594
0595 if (!new) {
0596 if (xindex & AA_X_INHERIT) {
0597
0598
0599
0600 *info = "ix fallback";
0601
0602 new = aa_get_newest_label(&profile->label);
0603 } else if (xindex & AA_X_UNCONFINED) {
0604 new = aa_get_newest_label(ns_unconfined(profile->ns));
0605 *info = "ux fallback";
0606 }
0607 }
0608
0609 if (new && stack) {
0610
0611 struct aa_label *base = new;
0612
0613 new = aa_label_parse(base, stack, GFP_KERNEL, true, false);
0614 if (IS_ERR(new))
0615 new = NULL;
0616 aa_put_label(base);
0617 }
0618
0619
0620 return new;
0621 }
0622
0623 static struct aa_label *profile_transition(struct aa_profile *profile,
0624 const struct linux_binprm *bprm,
0625 char *buffer, struct path_cond *cond,
0626 bool *secure_exec)
0627 {
0628 struct aa_label *new = NULL;
0629 const char *info = NULL, *name = NULL, *target = NULL;
0630 unsigned int state = profile->file.start;
0631 struct aa_perms perms = {};
0632 bool nonewprivs = false;
0633 int error = 0;
0634
0635 AA_BUG(!profile);
0636 AA_BUG(!bprm);
0637 AA_BUG(!buffer);
0638
0639 error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
0640 &name, &info, profile->disconnected);
0641 if (error) {
0642 if (profile_unconfined(profile) ||
0643 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
0644 AA_DEBUG("name lookup ix on error");
0645 error = 0;
0646 new = aa_get_newest_label(&profile->label);
0647 }
0648 name = bprm->filename;
0649 goto audit;
0650 }
0651
0652 if (profile_unconfined(profile)) {
0653 new = find_attach(bprm, profile->ns,
0654 &profile->ns->base.profiles, name, &info);
0655 if (new) {
0656 AA_DEBUG("unconfined attached to new label");
0657 return new;
0658 }
0659 AA_DEBUG("unconfined exec no attachment");
0660 return aa_get_newest_label(&profile->label);
0661 }
0662
0663
0664 state = aa_str_perms(profile->file.dfa, state, name, cond, &perms);
0665 if (perms.allow & MAY_EXEC) {
0666
0667 new = x_to_label(profile, bprm, name, perms.xindex, &target,
0668 &info);
0669 if (new && new->proxy == profile->label.proxy && info) {
0670
0671 goto audit;
0672 } else if (!new) {
0673 error = -EACCES;
0674 info = "profile transition not found";
0675
0676 perms.allow &= ~MAY_EXEC;
0677 }
0678 } else if (COMPLAIN_MODE(profile)) {
0679
0680 struct aa_profile *new_profile = NULL;
0681
0682 new_profile = aa_new_null_profile(profile, false, name,
0683 GFP_KERNEL);
0684 if (!new_profile) {
0685 error = -ENOMEM;
0686 info = "could not create null profile";
0687 } else {
0688 error = -EACCES;
0689 new = &new_profile->label;
0690 }
0691 perms.xindex |= AA_X_UNSAFE;
0692 } else
0693
0694 error = -EACCES;
0695
0696 if (!new)
0697 goto audit;
0698
0699
0700 if (!(perms.xindex & AA_X_UNSAFE)) {
0701 if (DEBUG_ON) {
0702 dbg_printk("apparmor: scrubbing environment variables"
0703 " for %s profile=", name);
0704 aa_label_printk(new, GFP_KERNEL);
0705 dbg_printk("\n");
0706 }
0707 *secure_exec = true;
0708 }
0709
0710 audit:
0711 aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name, target, new,
0712 cond->uid, info, error);
0713 if (!new || nonewprivs) {
0714 aa_put_label(new);
0715 return ERR_PTR(error);
0716 }
0717
0718 return new;
0719 }
0720
0721 static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
0722 bool stack, const struct linux_binprm *bprm,
0723 char *buffer, struct path_cond *cond,
0724 bool *secure_exec)
0725 {
0726 unsigned int state = profile->file.start;
0727 struct aa_perms perms = {};
0728 const char *xname = NULL, *info = "change_profile onexec";
0729 int error = -EACCES;
0730
0731 AA_BUG(!profile);
0732 AA_BUG(!onexec);
0733 AA_BUG(!bprm);
0734 AA_BUG(!buffer);
0735
0736 if (profile_unconfined(profile)) {
0737
0738
0739
0740
0741
0742
0743 return 0;
0744 }
0745
0746 error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
0747 &xname, &info, profile->disconnected);
0748 if (error) {
0749 if (profile_unconfined(profile) ||
0750 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
0751 AA_DEBUG("name lookup ix on error");
0752 error = 0;
0753 }
0754 xname = bprm->filename;
0755 goto audit;
0756 }
0757
0758
0759 state = aa_str_perms(profile->file.dfa, state, xname, cond, &perms);
0760 if (!(perms.allow & AA_MAY_ONEXEC)) {
0761 info = "no change_onexec valid for executable";
0762 goto audit;
0763 }
0764
0765
0766
0767
0768 state = aa_dfa_null_transition(profile->file.dfa, state);
0769 error = change_profile_perms(profile, onexec, stack, AA_MAY_ONEXEC,
0770 state, &perms);
0771 if (error) {
0772 perms.allow &= ~AA_MAY_ONEXEC;
0773 goto audit;
0774 }
0775
0776 if (!(perms.xindex & AA_X_UNSAFE)) {
0777 if (DEBUG_ON) {
0778 dbg_printk("apparmor: scrubbing environment "
0779 "variables for %s label=", xname);
0780 aa_label_printk(onexec, GFP_KERNEL);
0781 dbg_printk("\n");
0782 }
0783 *secure_exec = true;
0784 }
0785
0786 audit:
0787 return aa_audit_file(profile, &perms, OP_EXEC, AA_MAY_ONEXEC, xname,
0788 NULL, onexec, cond->uid, info, error);
0789 }
0790
0791
0792
0793 static struct aa_label *handle_onexec(struct aa_label *label,
0794 struct aa_label *onexec, bool stack,
0795 const struct linux_binprm *bprm,
0796 char *buffer, struct path_cond *cond,
0797 bool *unsafe)
0798 {
0799 struct aa_profile *profile;
0800 struct aa_label *new;
0801 int error;
0802
0803 AA_BUG(!label);
0804 AA_BUG(!onexec);
0805 AA_BUG(!bprm);
0806 AA_BUG(!buffer);
0807
0808 if (!stack) {
0809 error = fn_for_each_in_ns(label, profile,
0810 profile_onexec(profile, onexec, stack,
0811 bprm, buffer, cond, unsafe));
0812 if (error)
0813 return ERR_PTR(error);
0814 new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
0815 aa_get_newest_label(onexec),
0816 profile_transition(profile, bprm, buffer,
0817 cond, unsafe));
0818
0819 } else {
0820
0821 error = fn_for_each_in_ns(label, profile,
0822 profile_onexec(profile, onexec, stack, bprm,
0823 buffer, cond, unsafe));
0824 if (error)
0825 return ERR_PTR(error);
0826 new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
0827 aa_label_merge(&profile->label, onexec,
0828 GFP_KERNEL),
0829 profile_transition(profile, bprm, buffer,
0830 cond, unsafe));
0831 }
0832
0833 if (new)
0834 return new;
0835
0836
0837 error = fn_for_each_in_ns(label, profile,
0838 aa_audit_file(profile, &nullperms, OP_CHANGE_ONEXEC,
0839 AA_MAY_ONEXEC, bprm->filename, NULL,
0840 onexec, GLOBAL_ROOT_UID,
0841 "failed to build target label", -ENOMEM));
0842 return ERR_PTR(error);
0843 }
0844
0845
0846
0847
0848
0849
0850
0851
0852
0853 int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm)
0854 {
0855 struct aa_task_ctx *ctx;
0856 struct aa_label *label, *new = NULL;
0857 struct aa_profile *profile;
0858 char *buffer = NULL;
0859 const char *info = NULL;
0860 int error = 0;
0861 bool unsafe = false;
0862 kuid_t i_uid = i_uid_into_mnt(file_mnt_user_ns(bprm->file),
0863 file_inode(bprm->file));
0864 struct path_cond cond = {
0865 i_uid,
0866 file_inode(bprm->file)->i_mode
0867 };
0868
0869 ctx = task_ctx(current);
0870 AA_BUG(!cred_label(bprm->cred));
0871 AA_BUG(!ctx);
0872
0873 label = aa_get_newest_label(cred_label(bprm->cred));
0874
0875
0876
0877
0878
0879
0880
0881
0882 if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) && !unconfined(label) &&
0883 !ctx->nnp)
0884 ctx->nnp = aa_get_label(label);
0885
0886
0887 buffer = aa_get_buffer(false);
0888 if (!buffer) {
0889 error = -ENOMEM;
0890 goto done;
0891 }
0892
0893
0894 if (ctx->onexec)
0895 new = handle_onexec(label, ctx->onexec, ctx->token,
0896 bprm, buffer, &cond, &unsafe);
0897 else
0898 new = fn_label_build(label, profile, GFP_KERNEL,
0899 profile_transition(profile, bprm, buffer,
0900 &cond, &unsafe));
0901
0902 AA_BUG(!new);
0903 if (IS_ERR(new)) {
0904 error = PTR_ERR(new);
0905 goto done;
0906 } else if (!new) {
0907 error = -ENOMEM;
0908 goto done;
0909 }
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919 if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) &&
0920 !unconfined(label) &&
0921 !aa_label_is_unconfined_subset(new, ctx->nnp)) {
0922 error = -EPERM;
0923 info = "no new privs";
0924 goto audit;
0925 }
0926
0927 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
0928
0929 ;
0930 }
0931
0932 if (bprm->unsafe & (LSM_UNSAFE_PTRACE)) {
0933
0934 error = may_change_ptraced_domain(new, &info);
0935 if (error)
0936 goto audit;
0937 }
0938
0939 if (unsafe) {
0940 if (DEBUG_ON) {
0941 dbg_printk("scrubbing environment variables for %s "
0942 "label=", bprm->filename);
0943 aa_label_printk(new, GFP_KERNEL);
0944 dbg_printk("\n");
0945 }
0946 bprm->secureexec = 1;
0947 }
0948
0949 if (label->proxy != new->proxy) {
0950
0951 if (DEBUG_ON) {
0952 dbg_printk("apparmor: clearing unsafe personality "
0953 "bits. %s label=", bprm->filename);
0954 aa_label_printk(new, GFP_KERNEL);
0955 dbg_printk("\n");
0956 }
0957 bprm->per_clear |= PER_CLEAR_ON_SETID;
0958 }
0959 aa_put_label(cred_label(bprm->cred));
0960
0961 set_cred_label(bprm->cred, new);
0962
0963 done:
0964 aa_put_label(label);
0965 aa_put_buffer(buffer);
0966
0967 return error;
0968
0969 audit:
0970 error = fn_for_each(label, profile,
0971 aa_audit_file(profile, &nullperms, OP_EXEC, MAY_EXEC,
0972 bprm->filename, NULL, new,
0973 i_uid, info, error));
0974 aa_put_label(new);
0975 goto done;
0976 }
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987 static struct aa_label *build_change_hat(struct aa_profile *profile,
0988 const char *name, bool sibling)
0989 {
0990 struct aa_profile *root, *hat = NULL;
0991 const char *info = NULL;
0992 int error = 0;
0993
0994 if (sibling && PROFILE_IS_HAT(profile)) {
0995 root = aa_get_profile_rcu(&profile->parent);
0996 } else if (!sibling && !PROFILE_IS_HAT(profile)) {
0997 root = aa_get_profile(profile);
0998 } else {
0999 info = "conflicting target types";
1000 error = -EPERM;
1001 goto audit;
1002 }
1003
1004 hat = aa_find_child(root, name);
1005 if (!hat) {
1006 error = -ENOENT;
1007 if (COMPLAIN_MODE(profile)) {
1008 hat = aa_new_null_profile(profile, true, name,
1009 GFP_KERNEL);
1010 if (!hat) {
1011 info = "failed null profile create";
1012 error = -ENOMEM;
1013 }
1014 }
1015 }
1016 aa_put_profile(root);
1017
1018 audit:
1019 aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
1020 name, hat ? hat->base.hname : NULL,
1021 hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info,
1022 error);
1023 if (!hat || (error && error != -ENOENT))
1024 return ERR_PTR(error);
1025
1026
1027
1028 return &hat->label;
1029 }
1030
1031
1032
1033
1034
1035 static struct aa_label *change_hat(struct aa_label *label, const char *hats[],
1036 int count, int flags)
1037 {
1038 struct aa_profile *profile, *root, *hat = NULL;
1039 struct aa_label *new;
1040 struct label_it it;
1041 bool sibling = false;
1042 const char *name, *info = NULL;
1043 int i, error;
1044
1045 AA_BUG(!label);
1046 AA_BUG(!hats);
1047 AA_BUG(count < 1);
1048
1049 if (PROFILE_IS_HAT(labels_profile(label)))
1050 sibling = true;
1051
1052
1053 for (i = 0; i < count && !hat; i++) {
1054 name = hats[i];
1055 label_for_each_in_ns(it, labels_ns(label), label, profile) {
1056 if (sibling && PROFILE_IS_HAT(profile)) {
1057 root = aa_get_profile_rcu(&profile->parent);
1058 } else if (!sibling && !PROFILE_IS_HAT(profile)) {
1059 root = aa_get_profile(profile);
1060 } else {
1061 info = "conflicting targets types";
1062 error = -EPERM;
1063 goto fail;
1064 }
1065 hat = aa_find_child(root, name);
1066 aa_put_profile(root);
1067 if (!hat) {
1068 if (!COMPLAIN_MODE(profile))
1069 goto outer_continue;
1070
1071 } else if (!PROFILE_IS_HAT(hat)) {
1072 info = "target not hat";
1073 error = -EPERM;
1074 aa_put_profile(hat);
1075 goto fail;
1076 }
1077 aa_put_profile(hat);
1078 }
1079
1080 goto build;
1081 outer_continue:
1082 ;
1083 }
1084
1085
1086
1087
1088
1089
1090 name = NULL;
1091 label_for_each_in_ns(it, labels_ns(label), label, profile) {
1092 if (!list_empty(&profile->base.profiles)) {
1093 info = "hat not found";
1094 error = -ENOENT;
1095 goto fail;
1096 }
1097 }
1098 info = "no hats defined";
1099 error = -ECHILD;
1100
1101 fail:
1102 label_for_each_in_ns(it, labels_ns(label), label, profile) {
1103
1104
1105
1106
1107
1108
1109
1110 if (count > 1 || COMPLAIN_MODE(profile)) {
1111 aa_audit_file(profile, &nullperms, OP_CHANGE_HAT,
1112 AA_MAY_CHANGEHAT, name, NULL, NULL,
1113 GLOBAL_ROOT_UID, info, error);
1114 }
1115 }
1116 return ERR_PTR(error);
1117
1118 build:
1119 new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1120 build_change_hat(profile, name, sibling),
1121 aa_get_label(&profile->label));
1122 if (!new) {
1123 info = "label build failed";
1124 error = -ENOMEM;
1125 goto fail;
1126 }
1127
1128 return new;
1129 }
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148 int aa_change_hat(const char *hats[], int count, u64 token, int flags)
1149 {
1150 const struct cred *cred;
1151 struct aa_task_ctx *ctx = task_ctx(current);
1152 struct aa_label *label, *previous, *new = NULL, *target = NULL;
1153 struct aa_profile *profile;
1154 struct aa_perms perms = {};
1155 const char *info = NULL;
1156 int error = 0;
1157
1158
1159 cred = get_current_cred();
1160 label = aa_get_newest_cred_label(cred);
1161 previous = aa_get_newest_label(ctx->previous);
1162
1163
1164
1165
1166
1167
1168
1169
1170 if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp)
1171 ctx->nnp = aa_get_label(label);
1172
1173 if (unconfined(label)) {
1174 info = "unconfined can not change_hat";
1175 error = -EPERM;
1176 goto fail;
1177 }
1178
1179 if (count) {
1180 new = change_hat(label, hats, count, flags);
1181 AA_BUG(!new);
1182 if (IS_ERR(new)) {
1183 error = PTR_ERR(new);
1184 new = NULL;
1185
1186 goto out;
1187 }
1188
1189 error = may_change_ptraced_domain(new, &info);
1190 if (error)
1191 goto fail;
1192
1193
1194
1195
1196
1197 if (task_no_new_privs(current) && !unconfined(label) &&
1198 !aa_label_is_unconfined_subset(new, ctx->nnp)) {
1199
1200 AA_DEBUG("no_new_privs - change_hat denied");
1201 error = -EPERM;
1202 goto out;
1203 }
1204
1205 if (flags & AA_CHANGE_TEST)
1206 goto out;
1207
1208 target = new;
1209 error = aa_set_current_hat(new, token);
1210 if (error == -EACCES)
1211
1212 goto kill;
1213 } else if (previous && !(flags & AA_CHANGE_TEST)) {
1214
1215
1216
1217
1218 if (task_no_new_privs(current) && !unconfined(label) &&
1219 !aa_label_is_unconfined_subset(previous, ctx->nnp)) {
1220
1221 AA_DEBUG("no_new_privs - change_hat denied");
1222 error = -EPERM;
1223 goto out;
1224 }
1225
1226
1227
1228
1229 target = previous;
1230 error = aa_restore_previous_label(token);
1231 if (error) {
1232 if (error == -EACCES)
1233 goto kill;
1234 goto fail;
1235 }
1236 }
1237
1238 out:
1239 aa_put_label(new);
1240 aa_put_label(previous);
1241 aa_put_label(label);
1242 put_cred(cred);
1243
1244 return error;
1245
1246 kill:
1247 info = "failed token match";
1248 perms.kill = AA_MAY_CHANGEHAT;
1249
1250 fail:
1251 fn_for_each_in_ns(label, profile,
1252 aa_audit_file(profile, &perms, OP_CHANGE_HAT,
1253 AA_MAY_CHANGEHAT, NULL, NULL, target,
1254 GLOBAL_ROOT_UID, info, error));
1255
1256 goto out;
1257 }
1258
1259
1260 static int change_profile_perms_wrapper(const char *op, const char *name,
1261 struct aa_profile *profile,
1262 struct aa_label *target, bool stack,
1263 u32 request, struct aa_perms *perms)
1264 {
1265 const char *info = NULL;
1266 int error = 0;
1267
1268 if (!error)
1269 error = change_profile_perms(profile, target, stack, request,
1270 profile->file.start, perms);
1271 if (error)
1272 error = aa_audit_file(profile, perms, op, request, name,
1273 NULL, target, GLOBAL_ROOT_UID, info,
1274 error);
1275
1276 return error;
1277 }
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292 int aa_change_profile(const char *fqname, int flags)
1293 {
1294 struct aa_label *label, *new = NULL, *target = NULL;
1295 struct aa_profile *profile;
1296 struct aa_perms perms = {};
1297 const char *info = NULL;
1298 const char *auditname = fqname;
1299 bool stack = flags & AA_CHANGE_STACK;
1300 struct aa_task_ctx *ctx = task_ctx(current);
1301 int error = 0;
1302 char *op;
1303 u32 request;
1304
1305 label = aa_get_current_label();
1306
1307
1308
1309
1310
1311
1312
1313
1314 if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp)
1315 ctx->nnp = aa_get_label(label);
1316
1317 if (!fqname || !*fqname) {
1318 aa_put_label(label);
1319 AA_DEBUG("no profile name");
1320 return -EINVAL;
1321 }
1322
1323 if (flags & AA_CHANGE_ONEXEC) {
1324 request = AA_MAY_ONEXEC;
1325 if (stack)
1326 op = OP_STACK_ONEXEC;
1327 else
1328 op = OP_CHANGE_ONEXEC;
1329 } else {
1330 request = AA_MAY_CHANGE_PROFILE;
1331 if (stack)
1332 op = OP_STACK;
1333 else
1334 op = OP_CHANGE_PROFILE;
1335 }
1336
1337 if (*fqname == '&') {
1338 stack = true;
1339
1340 fqname++;
1341 }
1342 target = aa_label_parse(label, fqname, GFP_KERNEL, true, false);
1343 if (IS_ERR(target)) {
1344 struct aa_profile *tprofile;
1345
1346 info = "label not found";
1347 error = PTR_ERR(target);
1348 target = NULL;
1349
1350
1351
1352
1353 if ((flags & AA_CHANGE_TEST) ||
1354 !COMPLAIN_MODE(labels_profile(label)))
1355 goto audit;
1356
1357 tprofile = aa_new_null_profile(labels_profile(label), false,
1358 fqname, GFP_KERNEL);
1359 if (!tprofile) {
1360 info = "failed null profile create";
1361 error = -ENOMEM;
1362 goto audit;
1363 }
1364 target = &tprofile->label;
1365 goto check;
1366 }
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376 error = fn_for_each_in_ns(label, profile,
1377 change_profile_perms_wrapper(op, auditname,
1378 profile, target, stack,
1379 request, &perms));
1380 if (error)
1381
1382 goto out;
1383
1384
1385
1386 check:
1387
1388 error = may_change_ptraced_domain(target, &info);
1389 if (error && !fn_for_each_in_ns(label, profile,
1390 COMPLAIN_MODE(profile)))
1391 goto audit;
1392
1393
1394
1395
1396
1397
1398
1399
1400 if (flags & AA_CHANGE_TEST)
1401 goto out;
1402
1403
1404 if (!stack) {
1405 new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1406 aa_get_label(target),
1407 aa_get_label(&profile->label));
1408
1409
1410
1411
1412 if (task_no_new_privs(current) && !unconfined(label) &&
1413 !aa_label_is_unconfined_subset(new, ctx->nnp)) {
1414
1415 AA_DEBUG("no_new_privs - change_hat denied");
1416 error = -EPERM;
1417 goto out;
1418 }
1419 }
1420
1421 if (!(flags & AA_CHANGE_ONEXEC)) {
1422
1423 if (stack)
1424 new = aa_label_merge(label, target, GFP_KERNEL);
1425 if (IS_ERR_OR_NULL(new)) {
1426 info = "failed to build target label";
1427 if (!new)
1428 error = -ENOMEM;
1429 else
1430 error = PTR_ERR(new);
1431 new = NULL;
1432 perms.allow = 0;
1433 goto audit;
1434 }
1435 error = aa_replace_current_label(new);
1436 } else {
1437 if (new) {
1438 aa_put_label(new);
1439 new = NULL;
1440 }
1441
1442
1443 error = aa_set_current_onexec(target, stack);
1444 }
1445
1446 audit:
1447 error = fn_for_each_in_ns(label, profile,
1448 aa_audit_file(profile, &perms, op, request, auditname,
1449 NULL, new ? new : target,
1450 GLOBAL_ROOT_UID, info, error));
1451
1452 out:
1453 aa_put_label(new);
1454 aa_put_label(target);
1455 aa_put_label(label);
1456
1457 return error;
1458 }