Lines Matching +full:label +full:- +full:revision

1 // SPDX-License-Identifier: GPL-2.0-only
7 * Copyright (C) 2002-2008 Novell/SUSE
8 * Copyright 2009-2010 Canonical Ltd.
32 * may_change_ptraced_domain - check if can change profile on ptraced task
76 /**** TODO: dedup to aa_label_match - needs perm and dfa, merging
79 * and policy->dfa with file->dfa
90 struct aa_ruleset *rules = list_first_entry(&profile->rules,
95 state = aa_dfa_match(rules->file->dfa, state, "&");
96 if (profile->ns == tp->ns)
97 return aa_dfa_match(rules->file->dfa, state, tp->base.hname);
100 ns_name = aa_ns_name(profile->ns, tp->ns, true);
101 state = aa_dfa_match_len(rules->file->dfa, state, ":", 1);
102 state = aa_dfa_match(rules->file->dfa, state, ns_name);
103 state = aa_dfa_match_len(rules->file->dfa, state, ":", 1);
104 return aa_dfa_match(rules->file->dfa, state, tp->base.hname);
108 * label_compound_match - find perms for full compound label
110 * @label: label to check access permissions for
119 * For the label A//&B//&C this does the perm match for A//&B//&C
124 struct aa_label *label, bool stack,
128 struct aa_ruleset *rules = list_first_entry(&profile->rules,
135 label_for_each(i, label, tp) {
136 if (!aa_ns_visible(profile->ns, tp->ns, subns))
149 label_for_each_cont(i, label, tp) {
150 if (!aa_ns_visible(profile->ns, tp->ns, subns))
152 state = aa_dfa_match(rules->file->dfa, state, "//&");
157 *perms = *(aa_lookup_fperms(rules->file, state, &cond));
159 if ((perms->allow & request) != request)
160 return -EACCES;
166 return -EACCES;
170 * label_components_match - find perms for all subcomponents of a label
172 * @label: label to check access permissions for
181 * For the label A//&B//&C this does the perm match for each of A and B and C
186 struct aa_label *label, bool stack,
190 struct aa_ruleset *rules = list_first_entry(&profile->rules,
199 label_for_each(i, label, tp) {
200 if (!aa_ns_visible(profile->ns, tp->ns, subns))
208 /* no subcomponents visible - no change in perms */
212 tmp = *(aa_lookup_fperms(rules->file, state, &cond));
215 label_for_each_cont(i, label, tp) {
216 if (!aa_ns_visible(profile->ns, tp->ns, subns))
221 tmp = *(aa_lookup_fperms(rules->file, state, &cond));
226 if ((perms->allow & request) != request)
227 return -EACCES;
233 return -EACCES;
237 * label_match - do a multi-component label match
239 * @label: label to match (NOT NULL)
248 static int label_match(struct aa_profile *profile, struct aa_label *label,
255 error = label_compound_match(profile, label, stack, state, subns,
261 return label_components_match(profile, label, stack, state, subns,
268 * change_profile_perms - find permissions for change_profile
270 * @target: label to transition to (NOT NULL)
279 * currently only matches full label A//&B//&C or individual components A, B, C
288 perms->allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
289 perms->audit = perms->quiet = perms->kill = 0;
298 * aa_xattrs_match - check whether a file matches the xattrs defined in profile
311 struct aa_attachment *attach = &profile->attach;
312 int size, value_size = 0, ret = attach->xattr_count;
314 if (!bprm || !attach->xattr_count)
319 state = aa_dfa_outofband_transition(attach->xmatch->dfa, state);
320 d = bprm->file->f_path.dentry;
322 for (i = 0; i < attach->xattr_count; i++) {
323 size = vfs_getxattr_alloc(&nop_mnt_idmap, d, attach->xattrs[i],
333 state = aa_dfa_null_transition(attach->xmatch->dfa,
336 state = aa_dfa_match_len(attach->xmatch->dfa, state,
338 index = ACCEPT_TABLE(attach->xmatch->dfa)[state];
339 perm = attach->xmatch->perms[index].allow;
341 ret = -EINVAL;
346 state = aa_dfa_outofband_transition(attach->xmatch->dfa, state);
354 ret = -EINVAL;
358 ret--;
368 * find_attach - do attachment search for unconfined processes
382 * Returns: label or NULL if no match found
398 struct aa_attachment *attach = &profile->attach;
400 if (profile->label.flags & FLAG_NULL &&
401 &profile->label == ns_unconfined(profile->ns))
415 if (attach->xmatch->dfa) {
420 state = aa_dfa_leftmatch(attach->xmatch->dfa,
421 attach->xmatch->start[AA_CLASS_XMATCH],
423 index = ACCEPT_TABLE(attach->xmatch->dfa)[state];
424 perm = attach->xmatch->perms[index].allow;
432 if (bprm && attach->xattr_count) {
433 long rev = READ_ONCE(ns->revision);
443 READ_ONCE(ns->revision))
471 candidate_len = max(count, attach->xmatch_len);
475 } else if (!strcmp(profile->base.name, name)) {
477 * old exact non-re match, without conditionals such
496 return &candidate->label;
505 * x_table_lookup - lookup an x transition name via transition table
508 * @name: returns: name tested to find label (NOT NULL)
510 * Returns: refcounted label, or NULL on failure (MAYBE NULL)
515 struct aa_ruleset *rules = list_first_entry(&profile->rules,
517 struct aa_label *label = NULL;
525 * index into the resultant label
527 for (*name = rules->file->trans.table[index]; !label && *name;
534 label = &new_profile->label;
537 label = aa_label_parse(&profile->label, *name, GFP_KERNEL,
539 if (IS_ERR(label))
540 label = NULL;
545 return label;
549 * x_to_label - get target label for a given xindex
557 * find label for a transition index
559 * Returns: refcounted label or NULL if not found available
567 struct aa_ruleset *rules = list_first_entry(&profile->rules,
570 struct aa_ns *ns = profile->ns;
576 /* fail exec unless ix || ux fallback - handled by caller */
581 stack = rules->file->trans.table[xindex & AA_X_INDEX_MASK];
592 new = find_attach(bprm, ns, &profile->base.profiles,
596 new = find_attach(bprm, ns, &ns->base.profiles,
604 /* (p|c|n)ix - don't change profile but do
609 new = aa_get_newest_label(&profile->label);
611 new = aa_get_newest_label(ns_unconfined(profile->ns));
636 struct aa_ruleset *rules = list_first_entry(&profile->rules,
641 aa_state_t state = rules->file->start[AA_CLASS_FILE];
650 error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
651 &name, &info, profile->disconnected);
654 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
657 new = aa_get_newest_label(&profile->label);
659 name = bprm->filename;
664 new = find_attach(bprm, profile->ns,
665 &profile->ns->base.profiles, name, &info);
667 AA_DEBUG("unconfined attached to new label");
671 return aa_get_newest_label(&profile->label);
675 state = aa_str_perms(rules->file, state, name, cond, &perms);
680 if (new && new->proxy == profile->label.proxy && info) {
681 /* hack ix fallback - improve how this is detected */
691 error = -EACCES;
695 /* no exec permission - learning mode */
699 error = -ENOMEM;
702 error = -EACCES;
703 new = &new_profile->label;
708 error = -EACCES;
727 cond->uid, info, error);
742 struct aa_ruleset *rules = list_first_entry(&profile->rules,
744 aa_state_t state = rules->file->start[AA_CLASS_FILE];
747 int error = -EACCES;
764 error = aa_path_name(&bprm->file->f_path, profile->path_flags, buffer,
765 &xname, &info, profile->disconnected);
768 (profile->label.flags & FLAG_IX_ON_NAME_ERROR)) {
772 xname = bprm->filename;
777 state = aa_str_perms(rules->file, state, xname, cond, &perms);
786 state = aa_dfa_null_transition(rules->file->dfa, state);
796 dbg_printk("apparmor: setting AT_SECURE for %s label=",
807 NULL, onexec, cond->uid, info, error);
813 struct aa_label *label,
823 AA_BUG(!label);
829 error = fn_for_each_in_ns(label, profile,
835 new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
836 stack ? aa_label_merge(&profile->label, onexec,
845 error = fn_for_each_in_ns(label, profile,
848 AA_MAY_ONEXEC, bprm->filename, NULL,
850 "failed to build target label", -ENOMEM));
855 * apparmor_bprm_creds_for_exec - Update the new creds on the bprm struct
865 struct aa_label *label, *new = NULL;
872 vfsuid_t vfsuid = i_uid_into_vfsuid(file_mnt_idmap(bprm->file),
873 file_inode(bprm->file));
876 file_inode(bprm->file)->i_mode
881 AA_BUG(!cred_label(bprm->cred));
884 label = aa_get_newest_label(cred_label(bprm->cred));
887 * Detect no new privs being set, and store the label it
893 if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) && !unconfined(label) &&
894 !ctx->nnp)
895 ctx->nnp = aa_get_label(label);
900 error = -ENOMEM;
905 if (ctx->onexec)
906 new = handle_onexec(subj_cred, label, ctx->onexec, ctx->token,
909 new = fn_label_build(label, profile, GFP_KERNEL,
919 error = -ENOMEM;
931 if ((bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) &&
932 !unconfined(label) &&
933 !aa_label_is_unconfined_subset(new, ctx->nnp)) {
934 error = -EPERM;
939 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
944 if (bprm->unsafe & (LSM_UNSAFE_PTRACE)) {
945 /* TODO: test needs to be profile of label to new */
946 error = may_change_ptraced_domain(bprm->cred, new, &info);
953 dbg_printk("setting AT_SECURE for %s label=",
954 bprm->filename);
958 bprm->secureexec = 1;
961 if (label->proxy != new->proxy) {
964 dbg_printk("apparmor: clearing unsafe personality bits. %s label=",
965 bprm->filename);
969 bprm->per_clear |= PER_CLEAR_ON_SETID;
971 aa_put_label(cred_label(bprm->cred));
973 set_cred_label(bprm->cred, new);
976 aa_put_label(label);
982 error = fn_for_each(label, profile,
985 bprm->filename, NULL, new,
998 * Returns: label for hat transition OR ERR_PTR. Does NOT return NULL
1009 root = aa_get_profile_rcu(&profile->parent);
1014 error = -EPERM;
1020 error = -ENOENT;
1026 error = -ENOMEM;
1035 name, hat ? hat->base.hname : NULL,
1036 hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info,
1038 if (!hat || (error && error != -ENOENT))
1040 /* if hat && error - complain mode, already audited and we adjust for
1041 * complain mode allow by returning hat->label
1043 return &hat->label;
1048 * Returns: label for hat transition or ERR_PTR. Does not return NULL
1051 struct aa_label *label, const char *hats[],
1061 AA_BUG(!label);
1065 if (PROFILE_IS_HAT(labels_profile(label)))
1071 label_for_each_in_ns(it, labels_ns(label), label, profile) {
1073 root = aa_get_profile_rcu(&profile->parent);
1078 error = -EPERM;
1089 error = -EPERM;
1107 label_for_each_in_ns(it, labels_ns(label), label, profile) {
1108 if (!list_empty(&profile->base.profiles)) {
1110 error = -ENOENT;
1115 error = -ECHILD;
1118 label_for_each_in_ns(it, labels_ns(label), label, profile) {
1136 new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1139 aa_get_label(&profile->label));
1141 info = "label build failed";
1142 error = -ENOMEM;
1150 * aa_change_hat - change hat to/from subprofile
1170 struct aa_label *label, *previous, *new = NULL, *target = NULL;
1178 label = aa_get_newest_cred_label(subj_cred);
1179 previous = aa_get_newest_label(ctx->previous);
1182 * Detect no new privs being set, and store the label it
1188 if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp)
1189 ctx->nnp = aa_get_label(label);
1191 if (unconfined(label)) {
1193 error = -EPERM;
1198 new = change_hat(subj_cred, label, hats, count, flags);
1207 /* target cred is the same as current except new label */
1216 if (task_no_new_privs(current) && !unconfined(label) &&
1217 !aa_label_is_unconfined_subset(new, ctx->nnp)) {
1219 AA_DEBUG("no_new_privs - change_hat denied");
1220 error = -EPERM;
1229 if (error == -EACCES)
1237 if (task_no_new_privs(current) && !unconfined(label) &&
1238 !aa_label_is_unconfined_subset(previous, ctx->nnp)) {
1240 AA_DEBUG("no_new_privs - change_hat denied");
1241 error = -EPERM;
1245 /* Return to saved label. Kill task if restore fails
1251 if (error == -EACCES)
1260 aa_put_label(label);
1270 fn_for_each_in_ns(label, profile,
1285 struct aa_ruleset *rules = list_first_entry(&profile->rules,
1292 rules->file->start[AA_CLASS_FILE],
1306 * aa_change_profile - perform a one-way profile transition
1320 struct aa_label *label, *new = NULL, *target = NULL;
1332 label = aa_get_current_label();
1335 * Detect no new privs being set, and store the label it
1341 if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp)
1342 ctx->nnp = aa_get_label(label);
1345 aa_put_label(label);
1347 return -EINVAL;
1367 if (!stack && unconfined(label) &&
1368 label == &labels_ns(label)->unconfined->label &&
1375 * by-passed
1379 (void) fn_for_each_in_ns(label, profile,
1391 target = aa_label_parse(label, fqname, GFP_KERNEL, true, false);
1395 info = "label not found";
1399 * TODO: fixme using labels_profile is not right - do profile
1403 !COMPLAIN_MODE(labels_profile(label)))
1406 tprofile = aa_new_learning_profile(labels_profile(label), false,
1410 error = -ENOMEM;
1413 target = &tprofile->label;
1425 error = fn_for_each_in_ns(label, profile,
1439 if (error && !fn_for_each_in_ns(label, profile,
1446 * error = -EACCES;
1455 new = fn_label_build_in_ns(label, profile, GFP_KERNEL,
1457 aa_get_label(&profile->label));
1462 if (task_no_new_privs(current) && !unconfined(label) &&
1463 !aa_label_is_unconfined_subset(new, ctx->nnp)) {
1465 AA_DEBUG("no_new_privs - change_hat denied");
1466 error = -EPERM;
1474 new = aa_label_merge(label, target, GFP_KERNEL);
1476 info = "failed to build target label";
1478 error = -ENOMEM;
1497 error = fn_for_each_in_ns(label, profile,
1506 aa_put_label(label);