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.

apparmor: split xxx_in_ns into its two separate semantic use cases

This patch doesn't change current functionality, it switches the two
uses of the in_ns fns and macros into the two semantically different
cases they are used for.

xxx_in_scope for checking mediation interaction between profiles
xxx_in_view to determine which profiles are visible.The scope will
always be a subset of the view as profiles that can not see each
other can not interact.

The split can not be completely done for label_match because it has to
distinct uses matching permission against label in scope, and checking
if a transition to a profile is allowed. The transition to a profile
can include profiles that are in view but not in scope, so retain this
distinction as a parameter.

While at the moment the two uses are very similar, in the future there
will be additional differences. So make sure the semantics differences
are present in the code.

Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>

+61 -46
+1 -1
security/apparmor/af_unix.c
··· 416 416 unix_sk(sk), 417 417 peer_addr, peer_addrlen, &p, &ad->info); 418 418 419 - return fn_for_each_in_ns(peer_label, peerp, 419 + return fn_for_each_in_scope(peer_label, peerp, 420 420 match_label(profile, rules, state, request, 421 421 peerp, p, ad)); 422 422 }
+1 -1
security/apparmor/apparmorfs.c
··· 801 801 802 802 perms = allperms; 803 803 if (view_only) { 804 - label_for_each_in_ns(i, labels_ns(label), label, profile) { 804 + label_for_each_in_scope(i, labels_ns(label), label, profile) { 805 805 profile_query_cb(profile, &perms, match_str, match_len); 806 806 } 807 807 } else {
+30 -28
security/apparmor/domain.c
··· 115 115 * @label: label to check access permissions for 116 116 * @stack: whether this is a stacking request 117 117 * @state: state to start match in 118 - * @subns: whether to do permission checks on components in a subns 118 + * @inview: whether to match labels in view or only in scope 119 119 * @request: permissions to request 120 120 * @perms: perms struct to set 121 121 * ··· 127 127 */ 128 128 static int label_compound_match(struct aa_profile *profile, 129 129 struct aa_label *label, bool stack, 130 - aa_state_t state, bool subns, u32 request, 130 + aa_state_t state, bool inview, u32 request, 131 131 struct aa_perms *perms) 132 132 { 133 133 struct aa_ruleset *rules = profile->label.rules[0]; ··· 135 135 struct label_it i; 136 136 struct path_cond cond = { }; 137 137 138 - /* find first subcomponent that is visible */ 138 + /* find first subcomponent that is in view and going to be interated with */ 139 139 label_for_each(i, label, tp) { 140 - if (!aa_ns_visible(profile->ns, tp->ns, subns)) 140 + if (!aa_ns_visible(profile->ns, tp->ns, inview)) 141 141 continue; 142 142 state = match_component(profile, tp, stack, state); 143 143 if (!state) ··· 151 151 152 152 next: 153 153 label_for_each_cont(i, label, tp) { 154 - if (!aa_ns_visible(profile->ns, tp->ns, subns)) 154 + if (!aa_ns_visible(profile->ns, tp->ns, inview)) 155 155 continue; 156 156 state = aa_dfa_match(rules->file->dfa, state, "//&"); 157 157 state = match_component(profile, tp, false, state); ··· 177 177 * @label: label to check access permissions for 178 178 * @stack: whether this is a stacking request 179 179 * @start: state to start match in 180 - * @subns: whether to do permission checks on components in a subns 180 + * @inview: whether to match labels in view or only in scope 181 181 * @request: permissions to request 182 182 * @perms: an initialized perms struct to add accumulation to 183 183 * ··· 189 189 */ 190 190 static int label_components_match(struct aa_profile *profile, 191 191 struct aa_label *label, bool stack, 192 - aa_state_t start, bool subns, u32 request, 192 + aa_state_t start, bool inview, u32 request, 193 193 struct aa_perms *perms) 194 194 { 195 195 struct aa_ruleset *rules = profile->label.rules[0]; ··· 201 201 202 202 /* find first subcomponent to test */ 203 203 label_for_each(i, label, tp) { 204 - if (!aa_ns_visible(profile->ns, tp->ns, subns)) 204 + if (!aa_ns_visible(profile->ns, tp->ns, inview)) 205 205 continue; 206 206 state = match_component(profile, tp, stack, start); 207 207 if (!state) ··· 218 218 aa_apply_modes_to_perms(profile, &tmp); 219 219 aa_perms_accum(perms, &tmp); 220 220 label_for_each_cont(i, label, tp) { 221 - if (!aa_ns_visible(profile->ns, tp->ns, subns)) 221 + if (!aa_ns_visible(profile->ns, tp->ns, inview)) 222 222 continue; 223 223 state = match_component(profile, tp, stack, start); 224 224 if (!state) ··· 245 245 * @label: label to match (NOT NULL) 246 246 * @stack: whether this is a stacking request 247 247 * @state: state to start in 248 - * @subns: whether to match subns components 248 + * @inview: whether to match labels in view or only in scope 249 249 * @request: permission request 250 250 * @perms: Returns computed perms (NOT NULL) 251 251 * 252 252 * Returns: the state the match finished in, may be the none matching state 253 253 */ 254 254 static int label_match(struct aa_profile *profile, struct aa_label *label, 255 - bool stack, aa_state_t state, bool subns, u32 request, 255 + bool stack, aa_state_t state, bool inview, u32 request, 256 256 struct aa_perms *perms) 257 257 { 258 258 int error; 259 259 260 260 *perms = nullperms; 261 - error = label_compound_match(profile, label, stack, state, subns, 261 + error = label_compound_match(profile, label, stack, state, inview, 262 262 request, perms); 263 263 if (!error) 264 264 return error; 265 265 266 266 *perms = allperms; 267 - return label_components_match(profile, label, stack, state, subns, 267 + return label_components_match(profile, label, stack, state, inview, 268 268 request, perms); 269 269 } 270 270 ··· 880 880 AA_BUG(!bprm); 881 881 AA_BUG(!buffer); 882 882 883 - /* TODO: determine how much we want to loosen this */ 884 - error = fn_for_each_in_ns(label, profile, 883 + /* TODO: determine how much we want to loosen this 884 + * only check profiles in scope for permission to change at exec 885 + */ 886 + error = fn_for_each_in_scope(label, profile, 885 887 profile_onexec(subj_cred, profile, onexec, stack, 886 888 bprm, buffer, cond, unsafe)); 887 889 if (error) 888 890 return ERR_PTR(error); 889 891 890 - new = fn_label_build_in_ns(label, profile, GFP_KERNEL, 892 + new = fn_label_build_in_scope(label, profile, GFP_KERNEL, 891 893 stack ? aa_label_merge(&profile->label, onexec, 892 894 GFP_KERNEL) 893 895 : aa_get_newest_label(onexec), ··· 899 897 return new; 900 898 901 899 /* TODO: get rid of GLOBAL_ROOT_UID */ 902 - error = fn_for_each_in_ns(label, profile, 900 + error = fn_for_each_in_scope(label, profile, 903 901 aa_audit_file(subj_cred, profile, &nullperms, 904 902 OP_CHANGE_ONEXEC, 905 903 AA_MAY_ONEXEC, bprm->filename, NULL, ··· 1125 1123 /*find first matching hat */ 1126 1124 for (i = 0; i < count && !hat; i++) { 1127 1125 name = hats[i]; 1128 - label_for_each_in_ns(it, labels_ns(label), label, profile) { 1126 + label_for_each_in_scope(it, labels_ns(label), label, profile) { 1129 1127 if (sibling && PROFILE_IS_HAT(profile)) { 1130 1128 root = aa_get_profile_rcu(&profile->parent); 1131 1129 } else if (!sibling && !PROFILE_IS_HAT(profile)) { ··· 1161 1159 * change_hat. 1162 1160 */ 1163 1161 name = NULL; 1164 - label_for_each_in_ns(it, labels_ns(label), label, profile) { 1162 + label_for_each_in_scope(it, labels_ns(label), label, profile) { 1165 1163 if (!list_empty(&profile->base.profiles)) { 1166 1164 info = "hat not found"; 1167 1165 error = -ENOENT; ··· 1172 1170 error = -ECHILD; 1173 1171 1174 1172 fail: 1175 - label_for_each_in_ns(it, labels_ns(label), label, profile) { 1173 + label_for_each_in_scope(it, labels_ns(label), label, profile) { 1176 1174 /* 1177 1175 * no target as it has failed to be found or built 1178 1176 * ··· 1190 1188 return ERR_PTR(error); 1191 1189 1192 1190 build: 1193 - new = fn_label_build_in_ns(label, profile, GFP_KERNEL, 1191 + new = fn_label_build_in_scope(label, profile, GFP_KERNEL, 1194 1192 build_change_hat(subj_cred, profile, name, 1195 1193 sibling), 1196 1194 aa_get_label(&profile->label)); ··· 1253 1251 bool empty = true; 1254 1252 1255 1253 rcu_read_lock(); 1256 - label_for_each_in_ns(i, labels_ns(label), label, profile) { 1254 + label_for_each_in_scope(i, labels_ns(label), label, profile) { 1257 1255 empty &= list_empty(&profile->base.profiles); 1258 1256 } 1259 1257 rcu_read_unlock(); ··· 1340 1338 perms.kill = AA_MAY_CHANGEHAT; 1341 1339 1342 1340 fail: 1343 - fn_for_each_in_ns(label, profile, 1341 + fn_for_each_in_scope(label, profile, 1344 1342 aa_audit_file(subj_cred, profile, &perms, OP_CHANGE_HAT, 1345 1343 AA_MAY_CHANGEHAT, NULL, NULL, target, 1346 1344 GLOBAL_ROOT_UID, info, error)); ··· 1448 1446 */ 1449 1447 stack = true; 1450 1448 perms.audit = request; 1451 - (void) fn_for_each_in_ns(label, profile, 1449 + (void) fn_for_each_in_scope(label, profile, 1452 1450 aa_audit_file(subj_cred, profile, &perms, op, 1453 1451 request, auditname, NULL, target, 1454 1452 GLOBAL_ROOT_UID, stack_msg, 0)); ··· 1494 1492 * 1495 1493 * if (!stack) { 1496 1494 */ 1497 - error = fn_for_each_in_ns(label, profile, 1495 + error = fn_for_each_in_scope(label, profile, 1498 1496 change_profile_perms_wrapper(op, auditname, 1499 1497 subj_cred, 1500 1498 profile, target, stack, ··· 1508 1506 check: 1509 1507 /* check if tracing task is allowed to trace target domain */ 1510 1508 error = may_change_ptraced_domain(subj_cred, target, &info); 1511 - if (error && !fn_for_each_in_ns(label, profile, 1509 + if (error && !fn_for_each_in_scope(label, profile, 1512 1510 COMPLAIN_MODE(profile))) 1513 1511 goto audit; 1514 1512 ··· 1524 1522 1525 1523 /* stacking is always a subset, so only check the nonstack case */ 1526 1524 if (!stack) { 1527 - new = fn_label_build_in_ns(label, profile, GFP_KERNEL, 1525 + new = fn_label_build_in_scope(label, profile, GFP_KERNEL, 1528 1526 aa_get_label(target), 1529 1527 aa_get_label(&profile->label)); 1530 1528 /* ··· 1567 1565 } 1568 1566 1569 1567 audit: 1570 - error = fn_for_each_in_ns(label, profile, 1568 + error = fn_for_each_in_scope(label, profile, 1571 1569 aa_audit_file(subj_cred, 1572 1570 profile, &perms, op, request, auditname, 1573 1571 NULL, new ? new : target,
+16 -3
security/apparmor/include/lib.h
··· 80 80 /* Flag indicating whether initialization completed */ 81 81 extern int apparmor_initialized; 82 82 83 + /* semantic split of scope and view */ 84 + #define aa_in_scope(SUBJ, OBJ) \ 85 + aa_ns_visible(SUBJ, OBJ, false) 86 + 87 + #define aa_in_view(SUBJ, OBJ) \ 88 + aa_ns_visible(SUBJ, OBJ, true) 89 + 90 + #define label_for_each_in_scope(I, NS, L, P) \ 91 + label_for_each_in_ns(I, NS, L, P) 92 + 93 + #define fn_for_each_in_scope(L, P, FN) \ 94 + fn_for_each_in_ns(L, P, FN) 95 + 83 96 /* fn's in lib */ 84 97 const char *skipn_spaces(const char *str, size_t n); 85 98 const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, ··· 329 316 }) 330 317 331 318 332 - #define __fn_build_in_ns(NS, P, NS_FN, OTHER_FN) \ 319 + #define __fn_build_in_scope(NS, P, NS_FN, OTHER_FN) \ 333 320 ({ \ 334 321 struct aa_label *__new; \ 335 322 if ((P)->ns != (NS)) \ ··· 339 326 (__new); \ 340 327 }) 341 328 342 - #define fn_label_build_in_ns(L, P, GFP, NS_FN, OTHER_FN) \ 329 + #define fn_label_build_in_scope(L, P, GFP, NS_FN, OTHER_FN) \ 343 330 ({ \ 344 331 fn_label_build((L), (P), (GFP), \ 345 - __fn_build_in_ns(labels_ns(L), (P), (NS_FN), (OTHER_FN))); \ 332 + __fn_build_in_scope(labels_ns(L), (P), (NS_FN), (OTHER_FN))); \ 346 333 }) 347 334 348 335 #endif /* __AA_LIB_H */
+13 -13
security/apparmor/label.c
··· 1274 1274 * @rules: ruleset to search 1275 1275 * @label: label to check access permissions for 1276 1276 * @state: state to start match in 1277 - * @subns: whether to do permission checks on components in a subns 1277 + * @inview: whether to match labels in view or only in scope 1278 1278 * @request: permissions to request 1279 1279 * @perms: perms struct to set 1280 1280 * ··· 1287 1287 static int label_compound_match(struct aa_profile *profile, 1288 1288 struct aa_ruleset *rules, 1289 1289 struct aa_label *label, 1290 - aa_state_t state, bool subns, u32 request, 1290 + aa_state_t state, bool inview, u32 request, 1291 1291 struct aa_perms *perms) 1292 1292 { 1293 1293 struct aa_profile *tp; ··· 1295 1295 1296 1296 /* find first subcomponent that is visible */ 1297 1297 label_for_each(i, label, tp) { 1298 - if (!aa_ns_visible(profile->ns, tp->ns, subns)) 1298 + if (!aa_ns_visible(profile->ns, tp->ns, inview)) 1299 1299 continue; 1300 1300 state = match_component(profile, rules, tp, state); 1301 1301 if (!state) ··· 1309 1309 1310 1310 next: 1311 1311 label_for_each_cont(i, label, tp) { 1312 - if (!aa_ns_visible(profile->ns, tp->ns, subns)) 1312 + if (!aa_ns_visible(profile->ns, tp->ns, inview)) 1313 1313 continue; 1314 1314 state = aa_dfa_match(rules->policy->dfa, state, "//&"); 1315 1315 state = match_component(profile, rules, tp, state); ··· 1330 1330 * @rules: ruleset to search 1331 1331 * @label: label to check access permissions for 1332 1332 * @start: state to start match in 1333 - * @subns: whether to do permission checks on components in a subns 1333 + * @subns: whether to match labels in view or only in scope 1334 1334 * @request: permissions to request 1335 1335 * @perms: an initialized perms struct to add accumulation to 1336 1336 * ··· 1343 1343 static int label_components_match(struct aa_profile *profile, 1344 1344 struct aa_ruleset *rules, 1345 1345 struct aa_label *label, aa_state_t start, 1346 - bool subns, u32 request, 1346 + bool inview, u32 request, 1347 1347 struct aa_perms *perms) 1348 1348 { 1349 1349 struct aa_profile *tp; ··· 1353 1353 1354 1354 /* find first subcomponent to test */ 1355 1355 label_for_each(i, label, tp) { 1356 - if (!aa_ns_visible(profile->ns, tp->ns, subns)) 1356 + if (!aa_ns_visible(profile->ns, tp->ns, inview)) 1357 1357 continue; 1358 1358 state = match_component(profile, rules, tp, start); 1359 1359 if (!state) ··· 1368 1368 tmp = *aa_lookup_perms(rules->policy, state); 1369 1369 aa_perms_accum(perms, &tmp); 1370 1370 label_for_each_cont(i, label, tp) { 1371 - if (!aa_ns_visible(profile->ns, tp->ns, subns)) 1371 + if (!aa_ns_visible(profile->ns, tp->ns, inview)) 1372 1372 continue; 1373 1373 state = match_component(profile, rules, tp, start); 1374 1374 if (!state) ··· 1393 1393 * @rules: ruleset to search 1394 1394 * @label: label to match (NOT NULL) 1395 1395 * @state: state to start in 1396 - * @subns: whether to match subns components 1396 + * @subns: whether to match labels in view or only in scope 1397 1397 * @request: permission request 1398 1398 * @perms: Returns computed perms (NOT NULL) 1399 1399 * 1400 1400 * Returns: the state the match finished in, may be the none matching state 1401 1401 */ 1402 1402 int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, 1403 - struct aa_label *label, aa_state_t state, bool subns, 1403 + struct aa_label *label, aa_state_t state, bool inview, 1404 1404 u32 request, struct aa_perms *perms) 1405 1405 { 1406 - aa_state_t tmp = label_compound_match(profile, rules, label, state, subns, 1407 - request, perms); 1406 + aa_state_t tmp = label_compound_match(profile, rules, label, state, 1407 + inview, request, perms); 1408 1408 if ((perms->allow & request) == request) 1409 1409 return 0; 1410 1410 1411 1411 /* failed compound_match try component matches */ 1412 1412 *perms = allperms; 1413 - return label_components_match(profile, rules, label, state, subns, 1413 + return label_components_match(profile, rules, label, state, inview, 1414 1414 request, perms); 1415 1415 } 1416 1416