whyno-core 0.5.0

Permission check pipeline, fix engine, and state types
Documentation
//! `CAP_DAC_OVERRIDE` modifier applied to a failing DAC result.

use crate::checks::caps::{has_cap, CAP_DAC_OVERRIDE};
use crate::operation::Operation;
use crate::state::{Probe, SystemState};

use super::LayerResult;

/// Applies capability override to a failing DAC result.
///
/// Three-way dispatch on `state.subject.capabilities`:
/// - `Known(bitmask)`: override iff `CAP_DAC_OVERRIDE` is set in bitmask.
/// - `Unknown` with uid 0: backward-compat heuristic — assumes full caps.
/// - `Unknown` with non-root uid: no override applied.
/// - `Inaccessible`: result unchanged (user namespace — cannot determine caps).
#[must_use]
pub fn capability_modify(result: LayerResult, state: &SystemState) -> LayerResult {
    match &result {
        LayerResult::Pass { .. } | LayerResult::Degraded { .. } => return result,
        LayerResult::Fail { .. } => {}
    }
    match &state.subject.capabilities {
        Probe::Known(bitmask) => {
            if has_cap(*bitmask, CAP_DAC_OVERRIDE) {
                apply_root_override(state)
            } else {
                result
            }
        }
        Probe::Unknown => {
            if state.subject.uid == 0 {
                apply_root_override(state)
            } else {
                result
            }
        }
        Probe::Inaccessible => result,
    }
}

/// Applies `CAP_DAC_OVERRIDE` logic to a failing DAC result.
fn apply_root_override(state: &SystemState) -> LayerResult {
    if state.operation == Operation::Execute {
        return apply_root_execute_override(state);
    }
    let sticky_note = state.operation == Operation::Delete && parent_has_sticky(state);
    let detail = if sticky_note {
        "DAC bypassed via CAP_DAC_OVERRIDE (sticky bit on parent also bypassed by root)"
    } else {
        "DAC bypassed via CAP_DAC_OVERRIDE"
    };
    LayerResult::Pass {
        detail: detail.into(),
        warnings: vec![],
    }
}

/// Returns `true` if parent directory has sticky bit (`0o1000`) set.
fn parent_has_sticky(state: &SystemState) -> bool {
    state
        .operation
        .target_component(state.walk.len())
        .and_then(|i| state.walk[i].stat.known())
        .is_some_and(|s| s.mode & 0o1000 != 0)
}

/// Root can execute only if at least one class has execute bit set.
fn apply_root_execute_override(state: &SystemState) -> LayerResult {
    let target_idx = state.operation.target_component(state.walk.len());
    let any_x = target_idx
        .and_then(|i| state.walk[i].stat.known())
        .is_some_and(|s| s.mode & 0o111 != 0);
    if any_x {
        LayerResult::Pass {
            detail: "DAC bypassed via CAP_DAC_OVERRIDE".into(),
            warnings: vec![],
        }
    } else {
        LayerResult::Fail {
            detail: "root cannot execute: no execute bit set on any class \
                     (CAP_DAC_OVERRIDE does not apply)"
                .into(),
            component_index: target_idx,
        }
    }
}