| 2481 | } |
| 2482 | |
| 2483 | static int |
| 2484 | lomac_vnode_check_relabel(struct ucred *cred, struct vnode *vp, |
| 2485 | struct label *vplabel, struct label *newlabel) |
| 2486 | { |
| 2487 | struct mac_lomac *old, *new, *subj; |
| 2488 | int error; |
| 2489 | |
| 2490 | old = SLOT(vplabel); |
| 2491 | new = SLOT(newlabel); |
| 2492 | subj = SLOT(cred->cr_label); |
| 2493 | |
| 2494 | /* |
| 2495 | * If there is a LOMAC label update for the vnode, it must be a |
| 2496 | * single label, with an optional explicit auxiliary single. |
| 2497 | */ |
| 2498 | error = lomac_atmostflags(new, |
| 2499 | MAC_LOMAC_FLAG_SINGLE | MAC_LOMAC_FLAG_AUX); |
| 2500 | if (error) |
| 2501 | return (error); |
| 2502 | |
| 2503 | /* |
| 2504 | * To perform a relabel of the vnode (LOMAC label or not), LOMAC must |
| 2505 | * authorize the relabel. |
| 2506 | */ |
| 2507 | if (!lomac_single_in_range(old, subj)) |
| 2508 | return (EPERM); |
| 2509 | |
| 2510 | /* |
| 2511 | * If the LOMAC label is to be changed, authorize as appropriate. |
| 2512 | */ |
| 2513 | if (new->ml_flags & MAC_LOMAC_FLAG_SINGLE) { |
| 2514 | /* |
| 2515 | * To change the LOMAC label on a vnode, the new vnode label |
| 2516 | * must be in the subject range. |
| 2517 | */ |
| 2518 | if (!lomac_single_in_range(new, subj)) |
| 2519 | return (EPERM); |
| 2520 | |
| 2521 | /* |
| 2522 | * To change the LOMAC label on the vnode to be EQUAL, the |
| 2523 | * subject must have appropriate privilege. |
| 2524 | */ |
| 2525 | if (lomac_contains_equal(new)) { |
| 2526 | error = lomac_subject_privileged(subj); |
| 2527 | if (error) |
| 2528 | return (error); |
| 2529 | } |
| 2530 | } |
| 2531 | if (new->ml_flags & MAC_LOMAC_FLAG_AUX) { |
| 2532 | /* |
| 2533 | * Fill in the missing parts from the previous label. |
| 2534 | */ |
| 2535 | if ((new->ml_flags & MAC_LOMAC_FLAG_SINGLE) == 0) |
| 2536 | lomac_copy_single(subj, new); |
| 2537 | |
| 2538 | /* |
| 2539 | * To change the auxiliary LOMAC label on a vnode, the new |
| 2540 | * vnode label must be in the subject range. |
nothing calls this directly
no test coverage detected