Lines Matching +full:current +full:- +full:path

1 // SPDX-License-Identifier: GPL-2.0-only
7 * Copyright (C) 2002-2008 Novell/SUSE
8 * Copyright 2009-2010 Canonical Ltd.
29 #include "include/path.h"
35 "conflicting profile attachments - ix fallback";
37 "conflicting profile attachments - ux fallback";
40 * may_change_ptraced_domain - check if can change profile on ptraced task
45 * Check if current is ptraced and if so if the tracing task is allowed
61 tracer = ptrace_parent(current); in may_change_ptraced_domain()
84 /**** TODO: dedup to aa_label_match - needs perm and dfa, merging
87 * and policy->dfa with file->dfa
98 struct aa_ruleset *rules = profile->label.rules[0]; in match_component()
102 state = aa_dfa_match(rules->file->dfa, state, "&"); in match_component()
103 if (profile->ns == tp->ns) in match_component()
104 return aa_dfa_match(rules->file->dfa, state, tp->base.hname); in match_component()
107 ns_name = aa_ns_name(profile->ns, tp->ns, true); in match_component()
108 state = aa_dfa_match_len(rules->file->dfa, state, ":", 1); in match_component()
109 state = aa_dfa_match(rules->file->dfa, state, ns_name); in match_component()
110 state = aa_dfa_match_len(rules->file->dfa, state, ":", 1); in match_component()
111 return aa_dfa_match(rules->file->dfa, state, tp->base.hname); in match_component()
115 * label_compound_match - find perms for full compound label
135 struct aa_ruleset *rules = profile->label.rules[0]; in label_compound_match()
142 if (!aa_ns_visible(profile->ns, tp->ns, inview)) in label_compound_match()
156 if (!aa_ns_visible(profile->ns, tp->ns, inview)) in label_compound_match()
158 state = aa_dfa_match(rules->file->dfa, state, "//&"); in label_compound_match()
163 *perms = *(aa_lookup_condperms(current_fsuid(), rules->file, state, in label_compound_match()
166 if ((perms->allow & request) != request) in label_compound_match()
167 return -EACCES; in label_compound_match()
173 return -EACCES; in label_compound_match()
177 * label_components_match - find perms for all subcomponents of a label
197 struct aa_ruleset *rules = profile->label.rules[0]; in label_components_match()
206 if (!aa_ns_visible(profile->ns, tp->ns, inview)) in label_components_match()
214 /* no subcomponents visible - no change in perms */ in label_components_match()
218 tmp = *(aa_lookup_condperms(current_fsuid(), rules->file, state, in label_components_match()
223 if (!aa_ns_visible(profile->ns, tp->ns, inview)) in label_components_match()
228 tmp = *(aa_lookup_condperms(current_fsuid(), rules->file, state, in label_components_match()
234 if ((perms->allow & request) != request) in label_components_match()
235 return -EACCES; in label_components_match()
241 return -EACCES; in label_components_match()
245 * label_match - do a multi-component label match
276 * change_profile_perms - find permissions for change_profile
277 * @profile: the current profile (NOT NULL)
296 perms->allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC; in change_profile_perms()
297 perms->audit = perms->quiet = perms->kill = 0; in change_profile_perms()
306 * aa_xattrs_match - check whether a file matches the xattrs defined in profile
307 * @path: path for file being matched (NOT NULL)
313 static int aa_xattrs_match(const struct path *path, in aa_xattrs_match() argument
316 AA_BUG(!path); in aa_xattrs_match()
322 const struct aa_attachment *attach = &profile->attach; in aa_xattrs_match()
323 int size, value_size = 0, ret = attach->xattr_count; in aa_xattrs_match()
325 if (!attach->xattr_count) in aa_xattrs_match()
330 state = aa_dfa_outofband_transition(attach->xmatch->dfa, state); in aa_xattrs_match()
331 d = path->dentry; in aa_xattrs_match()
333 for (i = 0; i < attach->xattr_count; i++) { in aa_xattrs_match()
334 size = vfs_getxattr_alloc(&nop_mnt_idmap, d, attach->xattrs[i], in aa_xattrs_match()
344 state = aa_dfa_null_transition(attach->xmatch->dfa, in aa_xattrs_match()
347 state = aa_dfa_match_len(attach->xmatch->dfa, state, in aa_xattrs_match()
349 perms = aa_lookup_perms(attach->xmatch, state); in aa_xattrs_match()
350 if (!(perms->allow & MAY_EXEC)) { in aa_xattrs_match()
351 ret = -EINVAL; in aa_xattrs_match()
356 state = aa_dfa_outofband_transition(attach->xmatch->dfa, state); in aa_xattrs_match()
364 ret = -EINVAL; in aa_xattrs_match()
368 ret--; in aa_xattrs_match()
378 * find_attach - do attachment search for unconfined processes
379 * @path: path of file in question (NOT NULL)
380 * @ns: the current namespace (NOT NULL)
394 static struct aa_label *find_attach(const struct path *path, in find_attach() argument
402 AA_BUG(!path); in find_attach()
409 struct aa_attachment *attach = &profile->attach; in find_attach()
411 if (profile->label.flags & FLAG_NULL && in find_attach()
412 &profile->label == ns_unconfined(profile->ns)) in find_attach()
416 * match the path and extended attributes (if any) in find_attach()
417 * associated with the file. A more specific path in find_attach()
421 * match has both the same level of path specificity in find_attach()
426 if (attach->xmatch->dfa) { in find_attach()
431 state = aa_dfa_leftmatch(attach->xmatch->dfa, in find_attach()
432 attach->xmatch->start[AA_CLASS_XMATCH], in find_attach()
434 perms = aa_lookup_perms(attach->xmatch, state); in find_attach()
436 if (perms->allow & MAY_EXEC) { in find_attach()
442 if (attach->xattr_count) { in find_attach()
443 long rev = READ_ONCE(ns->revision); in find_attach()
448 ret = aa_xattrs_match(path, profile, in find_attach()
453 READ_ONCE(ns->revision)) in find_attach()
467 * than the current best match in find_attach()
481 candidate_len = max(count, attach->xmatch_len); in find_attach()
485 } else if (!strcmp(profile->base.name, name)) { in find_attach()
487 * old exact non-re match, without conditionals such in find_attach()
506 return &candidate->label; in find_attach()
515 * x_table_lookup - lookup an x transition name via transition table
516 * @profile: current profile (NOT NULL)
526 struct aa_ruleset *rules = profile->label.rules[0]; in x_table_lookup()
538 for (next = rules->file->trans.table[index].strs; next; in x_table_lookup()
548 return &new->label; in x_table_lookup()
551 label = aa_label_parse(&profile->label, lookup, GFP_KERNEL, in x_table_lookup()
562 * x_to_label - get target label for a given xindex
563 * @profile: current profile (NOT NULL)
564 * @path: path of file in question
575 const struct path *path, in x_to_label() argument
582 struct aa_ns *ns = profile->ns; in x_to_label()
589 /* fail exec unless ix || ux fallback - handled by caller */ in x_to_label()
606 new = find_attach(path, ns, &profile->base.profiles, in x_to_label()
610 new = find_attach(path, ns, &ns->base.profiles, in x_to_label()
619 /* (p|c|n)ix - don't change profile but do in x_to_label()
629 new = aa_get_newest_label(&profile->label); in x_to_label()
631 new = aa_get_newest_label(ns_unconfined(profile->ns)); in x_to_label()
647 profile->base.hname, old_info); in x_to_label()
671 struct aa_ruleset *rules = profile->label.rules[0]; in profile_transition()
675 aa_state_t state = rules->file->start[AA_CLASS_FILE]; in profile_transition()
684 error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer, in profile_transition()
685 &name, &info, profile->disconnected); in profile_transition()
688 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) { in profile_transition()
691 new = aa_get_newest_label(&profile->label); in profile_transition()
693 name = bprm->filename; in profile_transition()
698 new = find_attach(&bprm->file->f_path, profile->ns, in profile_transition()
699 &profile->ns->base.profiles, name, &info); in profile_transition()
700 /* info set -> something unusual that we should report in profile_transition()
703 * and only excluded on a case-by-case basis in profile_transition()
713 OP_EXEC, MAY_EXEC, name, target, new, cond->uid, in profile_transition()
721 return aa_get_newest_label(&profile->label); in profile_transition()
725 state = aa_str_perms(rules->file, state, name, cond, &perms); in profile_transition()
728 new = x_to_label(profile, &bprm->file->f_path, name, in profile_transition()
730 if (new && new->proxy == profile->label.proxy && info) { in profile_transition()
738 /* hack ix fallback - improve how this is detected */ in profile_transition()
744 __func__, profile->base.hname, info); in profile_transition()
753 error = -EACCES; in profile_transition()
757 /* no exec permission - learning mode */ in profile_transition()
761 error = -ENOMEM; in profile_transition()
764 error = -EACCES; in profile_transition()
765 new = &new_profile->label; in profile_transition()
770 error = -EACCES; in profile_transition()
789 cond->uid, info, error); in profile_transition()
804 struct aa_ruleset *rules = profile->label.rules[0]; in profile_onexec()
805 aa_state_t state = rules->file->start[AA_CLASS_FILE]; in profile_onexec()
808 int error = -EACCES; in profile_onexec()
825 error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer, in profile_onexec()
826 &xname, &info, profile->disconnected); in profile_onexec()
829 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) { in profile_onexec()
833 xname = bprm->filename; in profile_onexec()
838 state = aa_str_perms(rules->file, state, xname, cond, &perms); in profile_onexec()
847 state = aa_dfa_null_transition(rules->file->dfa, state); in profile_onexec()
868 NULL, onexec, cond->uid, info, error); in profile_onexec()
878 return ERR_PTR(-ENOMEM); in label_merge_wrap()
885 if (profile_unconfined(profile) && profile == profile->ns->unconfined && in is_profile_priv_restricted_to_stack()
909 struct aa_label *target = label_merge_wrap(&profile->label, in priv_restricted_transition()
923 subj_cred->euid, stack_msg, 0); in priv_restricted_transition()
954 stack ? label_merge_wrap(&profile->label, onexec, in handle_onexec()
958 bprm->filename, onexec, in handle_onexec()
970 AA_MAY_ONEXEC, bprm->filename, NULL, in handle_onexec()
978 * apparmor_bprm_creds_for_exec - Update the new creds on the bprm struct
995 vfsuid_t vfsuid = i_uid_into_vfsuid(file_mnt_idmap(bprm->file), in apparmor_bprm_creds_for_exec()
996 file_inode(bprm->file)); in apparmor_bprm_creds_for_exec()
999 file_inode(bprm->file)->i_mode in apparmor_bprm_creds_for_exec()
1003 ctx = task_ctx(current); in apparmor_bprm_creds_for_exec()
1004 AA_BUG(!cred_label(bprm->cred)); in apparmor_bprm_creds_for_exec()
1007 label = aa_get_newest_label(cred_label(bprm->cred)); in apparmor_bprm_creds_for_exec()
1016 if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) && !unconfined(label) && in apparmor_bprm_creds_for_exec()
1017 !ctx->nnp) in apparmor_bprm_creds_for_exec()
1018 ctx->nnp = aa_get_label(label); in apparmor_bprm_creds_for_exec()
1023 error = -ENOMEM; in apparmor_bprm_creds_for_exec()
1028 if (ctx->onexec) in apparmor_bprm_creds_for_exec()
1029 new = handle_onexec(subj_cred, label, ctx->onexec, ctx->token, in apparmor_bprm_creds_for_exec()
1050 if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) && in apparmor_bprm_creds_for_exec()
1052 !aa_label_is_unconfined_subset(new, ctx->nnp)) { in apparmor_bprm_creds_for_exec()
1053 error = -EPERM; in apparmor_bprm_creds_for_exec()
1058 if (bprm->unsafe & LSM_UNSAFE_SHARE) { in apparmor_bprm_creds_for_exec()
1063 if (bprm->unsafe & (LSM_UNSAFE_PTRACE)) { in apparmor_bprm_creds_for_exec()
1065 error = may_change_ptraced_domain(bprm->cred, new, &info); in apparmor_bprm_creds_for_exec()
1073 bprm->filename); in apparmor_bprm_creds_for_exec()
1077 bprm->secureexec = 1; in apparmor_bprm_creds_for_exec()
1080 if (label->proxy != new->proxy) { in apparmor_bprm_creds_for_exec()
1084 bprm->filename); in apparmor_bprm_creds_for_exec()
1088 bprm->per_clear |= PER_CLEAR_ON_SETID; in apparmor_bprm_creds_for_exec()
1090 aa_put_label(cred_label(bprm->cred)); in apparmor_bprm_creds_for_exec()
1092 set_cred_label(bprm->cred, new); in apparmor_bprm_creds_for_exec()
1104 bprm->filename, NULL, new, in apparmor_bprm_creds_for_exec()
1128 root = aa_get_profile_rcu(&profile->parent); in build_change_hat()
1133 error = -EPERM; in build_change_hat()
1139 error = -ENOENT; in build_change_hat()
1145 error = -ENOMEM; in build_change_hat()
1154 name, hat ? hat->base.hname : NULL, in build_change_hat()
1155 hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info, in build_change_hat()
1157 if (!hat || (error && error != -ENOENT)) in build_change_hat()
1159 /* if hat && error - complain mode, already audited and we adjust for in build_change_hat()
1160 * complain mode allow by returning hat->label in build_change_hat()
1162 return &hat->label; in build_change_hat()
1196 mutex_lock_nested(&ns->lock, ns->level); in change_hat()
1208 mutex_unlock(&ns->lock); in change_hat()
1223 root = aa_get_profile(rcu_dereference_protected(profile->parent, in change_hat()
1224 mutex_is_locked(&ns->lock))); in change_hat()
1229 error = -EPERM; in change_hat()
1240 error = -EPERM; in change_hat()
1259 if (!list_empty(&profile->base.profiles)) { in change_hat()
1261 error = -ENOENT; in change_hat()
1266 error = -ECHILD; in change_hat()
1284 mutex_unlock(&ns->lock); in change_hat()
1293 aa_get_label(&profile->label)); in change_hat()
1294 mutex_unlock(&ns->lock); in change_hat()
1303 * aa_change_hat - change hat to/from subprofile
1312 * the @hat_magic in the current task context. If the count == 0 and the
1313 * @token matches that stored in the current task context, return to the
1316 * change_hat only applies to profiles in the current ns, and each profile
1322 struct aa_task_ctx *ctx = task_ctx(current); in aa_change_hat()
1332 previous = aa_get_newest_label(ctx->previous); in aa_change_hat()
1341 if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp) in aa_change_hat()
1342 ctx->nnp = aa_get_label(label); in aa_change_hat()
1344 /* return -EPERM when unconfined doesn't have children to avoid in aa_change_hat()
1353 empty &= list_empty(&profile->base.profiles); in aa_change_hat()
1359 error = -EPERM; in aa_change_hat()
1374 /* target cred is the same as current except new label */ in aa_change_hat()
1383 if (task_no_new_privs(current) && !unconfined(label) && in aa_change_hat()
1384 !aa_label_is_unconfined_subset(new, ctx->nnp)) { in aa_change_hat()
1387 "no_new_privs - change_hat denied"); in aa_change_hat()
1388 error = -EPERM; in aa_change_hat()
1397 if (error == -EACCES) in aa_change_hat()
1405 if (task_no_new_privs(current) && !unconfined(label) && in aa_change_hat()
1406 !aa_label_is_unconfined_subset(previous, ctx->nnp)) { in aa_change_hat()
1409 "no_new_privs - change_hat denied"); in aa_change_hat()
1410 error = -EPERM; in aa_change_hat()
1420 if (error == -EACCES) in aa_change_hat()
1454 struct aa_ruleset *rules = profile->label.rules[0]; in change_profile_perms_wrapper()
1460 rules->file->start[AA_CLASS_FILE], in change_profile_perms_wrapper()
1472 * aa_change_profile - perform a one-way profile transition
1477 * to change back. If @name isn't specified the current profile name is
1492 struct aa_task_ctx *ctx = task_ctx(current); in aa_change_profile()
1507 if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp) in aa_change_profile()
1508 ctx->nnp = aa_get_label(label); in aa_change_profile()
1513 return -EINVAL; in aa_change_profile()
1543 * TODO: fixme using labels_profile is not right - do profile in aa_change_profile()
1554 error = -ENOMEM; in aa_change_profile()
1557 target = &tprofile->label; in aa_change_profile()
1562 * self directed transitions only apply to current policy ns in aa_change_profile()
1590 * error = -EACCES; in aa_change_profile()
1604 aa_get_label(&profile->label)); in aa_change_profile()
1612 if (task_no_new_privs(current) && !unconfined(label) && in aa_change_profile()
1613 !aa_label_is_unconfined_subset(new, ctx->nnp)) { in aa_change_profile()
1616 "no_new_privs - change_hat denied"); in aa_change_profile()
1617 error = -EPERM; in aa_change_profile()
1623 /* only transition profiles in the current ns */ in aa_change_profile()
1634 /* full transition will be built in exec path */ in aa_change_profile()
1643 error = -ENOMEM; in aa_change_profile()