# Raw module-policy syntax (compiled with `checkmodule -M -m`), NOT the refpolicy # `policy_module()` m4 macro — that macro is only expanded by the refpolicy # Makefile and checkmodule rejects it. See chrony-dhcp-dispatcher.te for the why. module fleet_agent_chronyc 1.0.0; ######################################## # Let the fleet-agent's chrony probe transition to chronyc_t under NoNewPrivileges. # # fleet-agent (telemetry) shells out to `chronyc -n tracking` to report the host's # clock offset / NTP source / stratum. The agent runs as unconfined_service_t, and # the shipped chrony policy has a type_transition so executing chronyc moves the # child into the confined chronyc_t domain. BUT the fleet-agent unit is hardened # with NoNewPrivileges (set explicitly AND forced by DynamicUser + SystemCallFilter # + MemoryDenyWriteExecute), and SELinux forbids an NNP process from transitioning # domains unless process2:nnp_transition is granted for that source->target pair. # The shipped policy has no such grant, so under enforcing the exec is DENIED: # avc: denied { nnp_transition } comm="fleet-agent" # scontext=...:unconfined_service_t tcontext=...:chronyc_t tclass=process2 # chronyc never runs, chronyTracking() returns empty, and every chrony_* health # field stays unset (the UI shows chrony as "—"). uptime/cpu/mem are unaffected — # they read /proc directly and need no domain transition. # # This single allow lets the transition proceed to the MORE-confined chronyc_t # domain (the safe direction NNP's nnp_transition permission exists to gate), with # no loosening of the agent's own sandbox. Minimal + auditable; justified in # docs/stig-deviations.md. BENCH-VERIFY: after this, the manager's Monitor chrony # row populates (offset/source/stratum). If a FOLLOW-ON chronyc_t AVC appears on # the bench (e.g. reaching chronyd's socket under the agent's mount namespace), # extend here. ######################################## require { type unconfined_service_t; type chronyc_t; class process2 nnp_transition; } allow unconfined_service_t chronyc_t:process2 nnp_transition;