← All rules
SOCLE-CLD-FSP-146// File permissionsmediumpersistent config

Verify Permissions On /etc/selinux Directory

Ensures the /etc/selinux directory is not group/other-writable and carries no setuid/setgid/sticky bits, so only root can change the SELinux configuration.

Checked against the content of a persistent configuration file, the source of truth that survives reboots.

A pass proves? running now✓ on disk✓ survives rebootthe qualified verdict →
FedoraRHEL 10 / Rocky 10 / AlmaLinux 10RHEL 8 / Rocky 8 / AlmaLinux 8CIS 4.0.0RHEL 9 / Rocky 9 / AlmaLinux 9CIS 2.0.0
One check, maps to 1 standard

A mapping is a cross-reference to where each standard places this requirement, anchored and cross-validated, not a claim of equivalence. A passing check is evidence toward these references, how to read it.

Why this rule matters

/etc/selinux hosts the SELinux configuration, including config which decides whether SELinux runs enforcing, permissive or disabled at boot. If the directory is writable by group or other, an unprivileged user could drop or replace files there to weaken or disable the system's mandatory access control, defeating the kernel's strongest containment layer. setuid/setgid on a directory affect new files, and a non-standard sticky bit signals tampering. Only root must control this directory.

What Pavois checks

Pavois reads the live mode bits of the /etc/selinux directory on the target (group/other write, setuid/setgid/sticky), the effective permissions the kernel enforces, not a documented baseline. Directory permissions are inode metadata, so there is no include or drop-in to subvert. The only_if guard skips the control on systems without SELinux.

only_if { file('/etc/selinux').exist? }
describe file('/etc/selinux') do
  it { should_not be_setuid }
  it { should_not be_writable.by('group') }
  it { should_not be_setgid }
  it { should_not be_writable.by('other') }
  it { should_not be_sticky }
end

How to verify it is applied

Run stat -c '%A %U %G' /etc/selinux. Expected: mode drwxr-xr-x (0755) owned by root root, with no write bit for group/other and no s/t bits. Quick check: find /etc/selinux -maxdepth 0 -perm /7022 must return nothing. Confirm SELinux is still active with getenforce (Enforcing).

Inspect & investigate

Permission changes are not logged by default. Watch the directory with auditd: auditctl -w /etc/selinux/ -p wa -k selinux, then review with grep 'key="selinux"' /var/log/audit/audit.log. SELinux policy denials and mode changes also surface via ausearch -m AVC / journalctl -t setroubleshoot. Current mode and ownership: stat /etc/selinux.

Remediation

No automated harden plan ships for this rule yet, so it must be applied manually: chown root:root /etc/selinux && chmod 0755 /etc/selinux. This removes any group/other write and any setuid/setgid/sticky bits while keeping the directory traversable by all (needed for SELinux tooling to read config).

Pavois applies this with its own harden engine, the plan below, not a shell script:

mode0755
path/etc/selinux
resourcefile
pavois harden plan local

where the target is local, a user@host SSH alias, or a container , Docs

Impact & precautions

Risk if left mis-set: a writable /etc/selinux lets a non-root user alter config and set SELinux to permissive or disabled at next boot, silently removing mandatory access control. Applying the fix is safe: 0755 root:root is the standard mode. Precaution: keep the directory at least 0755 (traversable/readable), tightening it further can break load_policy, semanage and boot-time policy loading.

Standards mapping

StandardReferenceTypeVersionConfidence
ANSSI BP-028R50direct2.0high

Each reference is a cross-reference anchored in the upstream benchmark and cross-validated against the SCAP Security Guide and ansible-lockdown, not a claim of equivalence. Direct = a prescriptive, line-level requirement; supporting = an abstract control family (NIST) the check provides evidence toward. How to read a mapping.

Sources & references