domain.c (2d63dd43ae334ec6f5374d37bb06c4cc57621b3c) domain.c (33fc95d8293cfca352ac875668857293e22d7d51)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * AppArmor security module
4 *
5 * This file contains AppArmor policy attachment and domain transitions
6 *
7 * Copyright (C) 2002-2008 Novell/SUSE
8 * Copyright 2009-2010 Canonical Ltd.

--- 81 unchanged lines hidden (view full) ---

90 * aa_compute_perms is replaced with aa_compute_fperms
91 * and policy.dfa with file.dfa
92 ****/
93/* match a profile and its associated ns component if needed
94 * Assumes visibility test has already been done.
95 * If a subns profile is not to be matched should be prescreened with
96 * visibility test.
97 */
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * AppArmor security module
4 *
5 * This file contains AppArmor policy attachment and domain transitions
6 *
7 * Copyright (C) 2002-2008 Novell/SUSE
8 * Copyright 2009-2010 Canonical Ltd.

--- 81 unchanged lines hidden (view full) ---

90 * aa_compute_perms is replaced with aa_compute_fperms
91 * and policy.dfa with file.dfa
92 ****/
93/* match a profile and its associated ns component if needed
94 * Assumes visibility test has already been done.
95 * If a subns profile is not to be matched should be prescreened with
96 * visibility test.
97 */
98static inline unsigned int match_component(struct aa_profile *profile,
99 struct aa_profile *tp,
100 bool stack, unsigned int state)
98static inline aa_state_t match_component(struct aa_profile *profile,
99 struct aa_profile *tp,
100 bool stack, aa_state_t state)
101{
102 const char *ns_name;
103
104 if (stack)
105 state = aa_dfa_match(profile->file.dfa, state, "&");
106 if (profile->ns == tp->ns)
107 return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
108

--- 18 unchanged lines hidden (view full) ---

127 * Returns: 0 on success else ERROR
128 *
129 * For the label A//&B//&C this does the perm match for A//&B//&C
130 * @perms should be preinitialized with allperms OR a previous permission
131 * check to be stacked.
132 */
133static int label_compound_match(struct aa_profile *profile,
134 struct aa_label *label, bool stack,
101{
102 const char *ns_name;
103
104 if (stack)
105 state = aa_dfa_match(profile->file.dfa, state, "&");
106 if (profile->ns == tp->ns)
107 return aa_dfa_match(profile->file.dfa, state, tp->base.hname);
108

--- 18 unchanged lines hidden (view full) ---

127 * Returns: 0 on success else ERROR
128 *
129 * For the label A//&B//&C this does the perm match for A//&B//&C
130 * @perms should be preinitialized with allperms OR a previous permission
131 * check to be stacked.
132 */
133static int label_compound_match(struct aa_profile *profile,
134 struct aa_label *label, bool stack,
135 unsigned int state, bool subns, u32 request,
135 aa_state_t state, bool subns, u32 request,
136 struct aa_perms *perms)
137{
138 struct aa_profile *tp;
139 struct label_it i;
140 struct path_cond cond = { };
141
142 /* find first subcomponent that is visible */
143 label_for_each(i, label, tp) {

--- 43 unchanged lines hidden (view full) ---

187 * Returns: 0 on success else ERROR
188 *
189 * For the label A//&B//&C this does the perm match for each of A and B and C
190 * @perms should be preinitialized with allperms OR a previous permission
191 * check to be stacked.
192 */
193static int label_components_match(struct aa_profile *profile,
194 struct aa_label *label, bool stack,
136 struct aa_perms *perms)
137{
138 struct aa_profile *tp;
139 struct label_it i;
140 struct path_cond cond = { };
141
142 /* find first subcomponent that is visible */
143 label_for_each(i, label, tp) {

--- 43 unchanged lines hidden (view full) ---

187 * Returns: 0 on success else ERROR
188 *
189 * For the label A//&B//&C this does the perm match for each of A and B and C
190 * @perms should be preinitialized with allperms OR a previous permission
191 * check to be stacked.
192 */
193static int label_components_match(struct aa_profile *profile,
194 struct aa_label *label, bool stack,
195 unsigned int start, bool subns, u32 request,
195 aa_state_t start, bool subns, u32 request,
196 struct aa_perms *perms)
197{
198 struct aa_profile *tp;
199 struct label_it i;
200 struct aa_perms tmp;
201 struct path_cond cond = { };
196 struct aa_perms *perms)
197{
198 struct aa_profile *tp;
199 struct label_it i;
200 struct aa_perms tmp;
201 struct path_cond cond = { };
202 unsigned int state = 0;
202 aa_state_t state = 0;
203
204 /* find first subcomponent to test */
205 label_for_each(i, label, tp) {
206 if (!aa_ns_visible(profile->ns, tp->ns, subns))
207 continue;
208 state = match_component(profile, tp, stack, start);
209 if (!state)
210 goto fail;

--- 36 unchanged lines hidden (view full) ---

247 * @state: state to start in
248 * @subns: whether to match subns components
249 * @request: permission request
250 * @perms: Returns computed perms (NOT NULL)
251 *
252 * Returns: the state the match finished in, may be the none matching state
253 */
254static int label_match(struct aa_profile *profile, struct aa_label *label,
203
204 /* find first subcomponent to test */
205 label_for_each(i, label, tp) {
206 if (!aa_ns_visible(profile->ns, tp->ns, subns))
207 continue;
208 state = match_component(profile, tp, stack, start);
209 if (!state)
210 goto fail;

--- 36 unchanged lines hidden (view full) ---

247 * @state: state to start in
248 * @subns: whether to match subns components
249 * @request: permission request
250 * @perms: Returns computed perms (NOT NULL)
251 *
252 * Returns: the state the match finished in, may be the none matching state
253 */
254static int label_match(struct aa_profile *profile, struct aa_label *label,
255 bool stack, unsigned int state, bool subns, u32 request,
255 bool stack, aa_state_t state, bool subns, u32 request,
256 struct aa_perms *perms)
257{
258 int error;
259
260 *perms = nullperms;
261 error = label_compound_match(profile, label, stack, state, subns,
262 request, perms);
263 if (!error)

--- 17 unchanged lines hidden (view full) ---

281 *
282 * Returns: permission set
283 *
284 * currently only matches full label A//&B//&C or individual components A, B, C
285 * not arbitrary combinations. Eg. A//&B, C
286 */
287static int change_profile_perms(struct aa_profile *profile,
288 struct aa_label *target, bool stack,
256 struct aa_perms *perms)
257{
258 int error;
259
260 *perms = nullperms;
261 error = label_compound_match(profile, label, stack, state, subns,
262 request, perms);
263 if (!error)

--- 17 unchanged lines hidden (view full) ---

281 *
282 * Returns: permission set
283 *
284 * currently only matches full label A//&B//&C or individual components A, B, C
285 * not arbitrary combinations. Eg. A//&B, C
286 */
287static int change_profile_perms(struct aa_profile *profile,
288 struct aa_label *target, bool stack,
289 u32 request, unsigned int start,
289 u32 request, aa_state_t start,
290 struct aa_perms *perms)
291{
292 if (profile_unconfined(profile)) {
293 perms->allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
294 perms->audit = perms->quiet = perms->kill = 0;
295 return 0;
296 }
297

--- 5 unchanged lines hidden (view full) ---

303 * aa_xattrs_match - check whether a file matches the xattrs defined in profile
304 * @bprm: binprm struct for the process to validate
305 * @profile: profile to match against (NOT NULL)
306 * @state: state to start match in
307 *
308 * Returns: number of extended attributes that matched, or < 0 on error
309 */
310static int aa_xattrs_match(const struct linux_binprm *bprm,
290 struct aa_perms *perms)
291{
292 if (profile_unconfined(profile)) {
293 perms->allow = AA_MAY_CHANGE_PROFILE | AA_MAY_ONEXEC;
294 perms->audit = perms->quiet = perms->kill = 0;
295 return 0;
296 }
297

--- 5 unchanged lines hidden (view full) ---

303 * aa_xattrs_match - check whether a file matches the xattrs defined in profile
304 * @bprm: binprm struct for the process to validate
305 * @profile: profile to match against (NOT NULL)
306 * @state: state to start match in
307 *
308 * Returns: number of extended attributes that matched, or < 0 on error
309 */
310static int aa_xattrs_match(const struct linux_binprm *bprm,
311 struct aa_profile *profile, unsigned int state)
311 struct aa_profile *profile, aa_state_t state)
312{
313 int i;
314 ssize_t size;
315 struct dentry *d;
316 char *value = NULL;
317 int value_size = 0, ret = profile->xattr_count;
318
319 if (!bprm || !profile->xattr_count)

--- 91 unchanged lines hidden (view full) ---

411 * and a match with more matching extended attributes
412 * will be preferred over one with fewer. If the best
413 * match has both the same level of path specificity
414 * and the same number of matching extended attributes
415 * as another profile, signal a conflict and refuse to
416 * match.
417 */
418 if (profile->xmatch.dfa) {
312{
313 int i;
314 ssize_t size;
315 struct dentry *d;
316 char *value = NULL;
317 int value_size = 0, ret = profile->xattr_count;
318
319 if (!bprm || !profile->xattr_count)

--- 91 unchanged lines hidden (view full) ---

411 * and a match with more matching extended attributes
412 * will be preferred over one with fewer. If the best
413 * match has both the same level of path specificity
414 * and the same number of matching extended attributes
415 * as another profile, signal a conflict and refuse to
416 * match.
417 */
418 if (profile->xmatch.dfa) {
419 unsigned int state, count;
419 unsigned int count;
420 aa_state_t state;
420 u32 index, perm;
421
422 state = aa_dfa_leftmatch(profile->xmatch.dfa,
423 profile->xmatch.start[AA_CLASS_XMATCH],
424 name, &count);
425 index = ACCEPT_TABLE(profile->xmatch.dfa)[state];
426 perm = profile->xmatch.perms[index].allow;
427 /* any accepting state means a valid match. */

--- 198 unchanged lines hidden (view full) ---

626
627static struct aa_label *profile_transition(struct aa_profile *profile,
628 const struct linux_binprm *bprm,
629 char *buffer, struct path_cond *cond,
630 bool *secure_exec)
631{
632 struct aa_label *new = NULL;
633 const char *info = NULL, *name = NULL, *target = NULL;
421 u32 index, perm;
422
423 state = aa_dfa_leftmatch(profile->xmatch.dfa,
424 profile->xmatch.start[AA_CLASS_XMATCH],
425 name, &count);
426 index = ACCEPT_TABLE(profile->xmatch.dfa)[state];
427 perm = profile->xmatch.perms[index].allow;
428 /* any accepting state means a valid match. */

--- 198 unchanged lines hidden (view full) ---

627
628static struct aa_label *profile_transition(struct aa_profile *profile,
629 const struct linux_binprm *bprm,
630 char *buffer, struct path_cond *cond,
631 bool *secure_exec)
632{
633 struct aa_label *new = NULL;
634 const char *info = NULL, *name = NULL, *target = NULL;
634 unsigned int state = profile->file.start[AA_CLASS_FILE];
635 aa_state_t state = profile->file.start[AA_CLASS_FILE];
635 struct aa_perms perms = {};
636 bool nonewprivs = false;
637 int error = 0;
638
639 AA_BUG(!profile);
640 AA_BUG(!bprm);
641 AA_BUG(!buffer);
642

--- 79 unchanged lines hidden (view full) ---

722 return new;
723}
724
725static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
726 bool stack, const struct linux_binprm *bprm,
727 char *buffer, struct path_cond *cond,
728 bool *secure_exec)
729{
636 struct aa_perms perms = {};
637 bool nonewprivs = false;
638 int error = 0;
639
640 AA_BUG(!profile);
641 AA_BUG(!bprm);
642 AA_BUG(!buffer);
643

--- 79 unchanged lines hidden (view full) ---

723 return new;
724}
725
726static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec,
727 bool stack, const struct linux_binprm *bprm,
728 char *buffer, struct path_cond *cond,
729 bool *secure_exec)
730{
730 unsigned int state = profile->file.start[AA_CLASS_FILE];
731 aa_state_t state = profile->file.start[AA_CLASS_FILE];
731 struct aa_perms perms = {};
732 const char *xname = NULL, *info = "change_profile onexec";
733 int error = -EACCES;
734
735 AA_BUG(!profile);
736 AA_BUG(!onexec);
737 AA_BUG(!bprm);
738 AA_BUG(!buffer);

--- 725 unchanged lines hidden ---
732 struct aa_perms perms = {};
733 const char *xname = NULL, *info = "change_profile onexec";
734 int error = -EACCES;
735
736 AA_BUG(!profile);
737 AA_BUG(!onexec);
738 AA_BUG(!bprm);
739 AA_BUG(!buffer);

--- 725 unchanged lines hidden ---