Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'apparmor-pr-2018-01-12' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor

Pull apparmor regression fixes from John Johansen:
"This fixes a couple bugs I have been working with Matthew Garrett on
this week. Specifically a regression in the handling of a conflicting
profile attachment and label match restrictions for ptrace when
profiles are stacked.

Summary:

- fix ptrace label match when matching stacked labels

- fix regression in profile conflict logic"

* tag 'apparmor-pr-2018-01-12' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor:
apparmor: Fix regression in profile conflict logic
apparmor: fix ptrace label match when matching stacked labels

+40 -25
+5 -4
security/apparmor/domain.c
··· 330 330 continue; 331 331 332 332 if (profile->xmatch) { 333 - if (profile->xmatch_len == len) { 334 - conflict = true; 335 - continue; 336 - } else if (profile->xmatch_len > len) { 333 + if (profile->xmatch_len >= len) { 337 334 unsigned int state; 338 335 u32 perm; 339 336 ··· 339 342 perm = dfa_user_allow(profile->xmatch, state); 340 343 /* any accepting state means a valid match. */ 341 344 if (perm & MAY_EXEC) { 345 + if (profile->xmatch_len == len) { 346 + conflict = true; 347 + continue; 348 + } 342 349 candidate = profile; 343 350 len = profile->xmatch_len; 344 351 conflict = false;
+3
security/apparmor/include/perms.h
··· 133 133 #define xcheck_labels_profiles(L1, L2, FN, args...) \ 134 134 xcheck_ns_labels((L1), (L2), xcheck_ns_profile_label, (FN), args) 135 135 136 + #define xcheck_labels(L1, L2, P, FN1, FN2) \ 137 + xcheck(fn_for_each((L1), (P), (FN1)), fn_for_each((L2), (P), (FN2))) 138 + 136 139 137 140 void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); 138 141 void aa_audit_perm_names(struct audit_buffer *ab, const char **names, u32 mask);
+32 -21
security/apparmor/ipc.c
··· 64 64 FLAGS_NONE, GFP_ATOMIC); 65 65 } 66 66 67 + /* assumes check for PROFILE_MEDIATES is already done */ 67 68 /* TODO: conditionals */ 68 69 static int profile_ptrace_perm(struct aa_profile *profile, 69 - struct aa_profile *peer, u32 request, 70 - struct common_audit_data *sa) 70 + struct aa_label *peer, u32 request, 71 + struct common_audit_data *sa) 71 72 { 72 73 struct aa_perms perms = { }; 73 74 74 - /* need because of peer in cross check */ 75 - if (profile_unconfined(profile) || 76 - !PROFILE_MEDIATES(profile, AA_CLASS_PTRACE)) 77 - return 0; 78 - 79 - aad(sa)->peer = &peer->label; 80 - aa_profile_match_label(profile, &peer->label, AA_CLASS_PTRACE, request, 75 + aad(sa)->peer = peer; 76 + aa_profile_match_label(profile, peer, AA_CLASS_PTRACE, request, 81 77 &perms); 82 78 aa_apply_modes_to_perms(profile, &perms); 83 79 return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb); 84 80 } 85 81 86 - static int cross_ptrace_perm(struct aa_profile *tracer, 87 - struct aa_profile *tracee, u32 request, 88 - struct common_audit_data *sa) 82 + static int profile_tracee_perm(struct aa_profile *tracee, 83 + struct aa_label *tracer, u32 request, 84 + struct common_audit_data *sa) 89 85 { 86 + if (profile_unconfined(tracee) || unconfined(tracer) || 87 + !PROFILE_MEDIATES(tracee, AA_CLASS_PTRACE)) 88 + return 0; 89 + 90 + return profile_ptrace_perm(tracee, tracer, request, sa); 91 + } 92 + 93 + static int profile_tracer_perm(struct aa_profile *tracer, 94 + struct aa_label *tracee, u32 request, 95 + struct common_audit_data *sa) 96 + { 97 + if (profile_unconfined(tracer)) 98 + return 0; 99 + 90 100 if (PROFILE_MEDIATES(tracer, AA_CLASS_PTRACE)) 91 - return xcheck(profile_ptrace_perm(tracer, tracee, request, sa), 92 - profile_ptrace_perm(tracee, tracer, 93 - request << PTRACE_PERM_SHIFT, 94 - sa)); 95 - /* policy uses the old style capability check for ptrace */ 96 - if (profile_unconfined(tracer) || tracer == tracee) 101 + return profile_ptrace_perm(tracer, tracee, request, sa); 102 + 103 + /* profile uses the old style capability check for ptrace */ 104 + if (&tracer->label == tracee) 97 105 return 0; 98 106 99 107 aad(sa)->label = &tracer->label; 100 - aad(sa)->peer = &tracee->label; 108 + aad(sa)->peer = tracee; 101 109 aad(sa)->request = 0; 102 110 aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, 1); 103 111 ··· 123 115 int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, 124 116 u32 request) 125 117 { 118 + struct aa_profile *profile; 119 + u32 xrequest = request << PTRACE_PERM_SHIFT; 126 120 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE); 127 121 128 - return xcheck_labels_profiles(tracer, tracee, cross_ptrace_perm, 129 - request, &sa); 122 + return xcheck_labels(tracer, tracee, profile, 123 + profile_tracer_perm(profile, tracee, request, &sa), 124 + profile_tracee_perm(profile, tracer, xrequest, &sa)); 130 125 } 131 126 132 127