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

apparmor: convert policy lookup to use accept as an index

Remap polidydb dfa accept table from embedded perms to an index, and
then move the perm lookup to use the accept entry as an index into the
perm table. This is done so that the perm table can be separated from
the dfa, allowing dfa accept to index to share expanded permission
sets.

Signed-off-by: John Johansen <john.johansen@canonical.com>

+33 -24
+1 -1
security/apparmor/apparmorfs.c
··· 634 634 state = aa_dfa_match_len(dfa, profile->policy.start[0], 635 635 match_str, match_len); 636 636 if (state) 637 - tmp = *aa_lookup_perms(profile->policy.perms, state); 637 + tmp = *aa_lookup_perms(&profile->policy, state); 638 638 } 639 639 aa_apply_modes_to_perms(profile, &tmp); 640 640 aa_perms_accum_raw(perms, &tmp);
-8
security/apparmor/include/perms.h
··· 132 132 133 133 extern struct aa_perms default_perms; 134 134 135 - static inline struct aa_perms *aa_lookup_perms(struct aa_perms *perms, 136 - unsigned int state) 137 - { 138 - if (!(perms)) 139 - return &default_perms; 140 - 141 - return &(perms[state]); 142 - } 143 135 144 136 void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs, 145 137 u32 mask);
+12
security/apparmor/include/policy.h
··· 90 90 91 91 } 92 92 93 + static inline struct aa_perms *aa_lookup_perms(struct aa_policydb *policy, 94 + unsigned int state) 95 + { 96 + unsigned int index = ACCEPT_TABLE(policy->dfa)[state]; 97 + 98 + if (!(policy->perms)) 99 + return &default_perms; 100 + 101 + return &(policy->perms[index]); 102 + } 103 + 104 + 93 105 /* struct aa_data - generic data structure 94 106 * key: name for retrieving this data 95 107 * size: size of data in bytes
+3 -3
security/apparmor/label.c
··· 1328 1328 if (!state) 1329 1329 goto fail; 1330 1330 } 1331 - *perms = *aa_lookup_perms(profile->policy.perms, state); 1331 + *perms = *aa_lookup_perms(&profile->policy, state); 1332 1332 aa_apply_modes_to_perms(profile, perms); 1333 1333 if ((perms->allow & request) != request) 1334 1334 return -EACCES; ··· 1379 1379 return 0; 1380 1380 1381 1381 next: 1382 - tmp = *aa_lookup_perms(profile->policy.perms, state); 1382 + tmp = *aa_lookup_perms(&profile->policy, state); 1383 1383 aa_apply_modes_to_perms(profile, &tmp); 1384 1384 aa_perms_accum(perms, &tmp); 1385 1385 label_for_each_cont(i, label, tp) { ··· 1388 1388 state = match_component(profile, tp, start); 1389 1389 if (!state) 1390 1390 goto fail; 1391 - tmp = *aa_lookup_perms(profile->policy.perms, state); 1391 + tmp = *aa_lookup_perms(&profile->policy, state); 1392 1392 aa_apply_modes_to_perms(profile, &tmp); 1393 1393 aa_perms_accum(perms, &tmp); 1394 1394 }
+4 -4
security/apparmor/mount.c
··· 249 249 state = match_mnt_flags(policy->dfa, state, flags); 250 250 if (!state) 251 251 return 4; 252 - *perms = *aa_lookup_perms(policy->perms, state); 252 + *perms = *aa_lookup_perms(policy, state); 253 253 if (perms->allow & AA_MAY_MOUNT) 254 254 return 0; 255 255 ··· 262 262 state = aa_dfa_match(policy->dfa, state, data); 263 263 if (!state) 264 264 return 5; 265 - *perms = *aa_lookup_perms(policy->perms, state); 265 + *perms = *aa_lookup_perms(policy, state); 266 266 if (perms->allow & AA_MAY_MOUNT) 267 267 return 0; 268 268 } ··· 584 584 state = aa_dfa_match(profile->policy.dfa, 585 585 profile->policy.start[AA_CLASS_MOUNT], 586 586 name); 587 - perms = *aa_lookup_perms(profile->policy.perms, state); 587 + perms = *aa_lookup_perms(&profile->policy, state); 588 588 if (AA_MAY_UMOUNT & ~perms.allow) 589 589 error = -EACCES; 590 590 ··· 655 655 new_name); 656 656 state = aa_dfa_null_transition(profile->policy.dfa, state); 657 657 state = aa_dfa_match(profile->policy.dfa, state, old_name); 658 - perms = *aa_lookup_perms(profile->policy.perms, state); 658 + perms = *aa_lookup_perms(&profile->policy, state); 659 659 660 660 if (AA_MAY_PIVOTROOT & perms.allow) 661 661 error = 0;
+1 -1
security/apparmor/net.c
··· 125 125 buffer[1] = cpu_to_be16((u16) type); 126 126 state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer, 127 127 4); 128 - perms = *aa_lookup_perms(profile->policy.perms, state); 128 + perms = *aa_lookup_perms(&profile->policy, state); 129 129 aa_apply_modes_to_perms(profile, &perms); 130 130 131 131 return aa_check_perms(profile, &perms, request, sa, audit_net_cb);
+12 -7
security/apparmor/policy_unpack.c
··· 1055 1055 } 1056 1056 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) 1057 1057 goto fail; 1058 + profile->policy.perms = compute_perms(profile->policy.dfa); 1059 + if (!profile->policy.perms) { 1060 + info = "failed to remap policydb permission table"; 1061 + goto fail; 1062 + } 1063 + /* Do not remap internal dfas */ 1064 + remap_dfa_accept(profile->policy.dfa, 1); 1058 1065 } else 1059 1066 profile->policy.dfa = aa_get_dfa(nulldfa); 1060 - profile->policy.perms = compute_perms(profile->policy.dfa); 1061 - if (!profile->policy.perms) { 1062 - info = "failed to remap policydb permission table"; 1063 - goto fail; 1064 - } 1065 1067 1066 1068 /* get file rules */ 1067 1069 profile->file.dfa = unpack_dfa(e); ··· 1240 1238 */ 1241 1239 static int verify_profile(struct aa_profile *profile) 1242 1240 { 1243 - if (profile->file.dfa && 1241 + if ((profile->file.dfa && 1244 1242 !verify_dfa_xindex(profile->file.dfa, 1245 - profile->file.trans.size)) { 1243 + profile->file.trans.size)) || 1244 + (profile->policy.dfa && 1245 + !verify_dfa_xindex(profile->policy.dfa, 1246 + profile->policy.trans.size))) { 1246 1247 audit_iface(profile, NULL, NULL, 1247 1248 "Unpack: Invalid named transition", NULL, -EPROTO); 1248 1249 return -EPROTO;