Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions controls/nist_rhcos4.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
- id: AC-1
status: not applicable
notes: |-
Section a: AC-1(a) is an organizational control outside the scope of CoreOS configuration.

Check failure on line 17 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

17:100 [line-length] line too long (100 > 99 characters)

Section b: AC-1(b) is an organizational control outside the scope of CoreOS configuration.

Check failure on line 19 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

19:100 [line-length] line too long (100 > 99 characters)
rules: []
description: "The organization:\n a. Develops, documents, and disseminates to [Assignment: organization-defined\

Check failure on line 21 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

21:100 [line-length] line too long (118 > 99 characters)
\ personnel or roles]:\n 1. An access control policy that addresses purpose, scope, roles,\

Check failure on line 22 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

22:100 [line-length] line too long (103 > 99 characters)
\ responsibilities, management commitment, coordination among organizational entities, and\

Check failure on line 23 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

23:100 [line-length] line too long (101 > 99 characters)
\ compliance; and\n 2. Procedures to facilitate the implementation of the access control\

Check failure on line 24 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

24:100 [line-length] line too long (101 > 99 characters)
\ policy and associated access controls; and\n b. Reviews and updates the current:\n 1. Access\

Check failure on line 25 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

25:100 [line-length] line too long (107 > 99 characters)
\ control policy [Assignment: organization-defined frequency]; and\n 2. Access control procedures\

Check failure on line 26 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

26:100 [line-length] line too long (110 > 99 characters)
\ [Assignment: organization-defined frequency].\n\nSupplemental Guidance: This control addresses\

Check failure on line 27 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

27:100 [line-length] line too long (107 > 99 characters)
\ the establishment of policy and procedures for the effective implementation of selected security\

Check failure on line 28 in controls/nist_rhcos4.yml

View workflow job for this annotation

GitHub Actions / Yaml Lint on Changed yaml files

28:100 [line-length] line too long (109 > 99 characters)
\ controls and control enhancements in the AC family. Policy and procedures reflect applicable\
\ federal laws, Executive Orders, directives, regulations, policies, standards, and guidance.\
\ Security program policies and procedures at the organization level may make the need for\
Expand Down Expand Up @@ -480,8 +480,7 @@
rules:
- var_selinux_policy_name=targeted
- selinux_policytype
# (jhrozek): Disabled because of https://issues.redhat.com/browse/OCPBUGS-6968
#- selinux_confinement_of_daemons
- selinux_confinement_of_daemons
- var_selinux_state=enforcing
- selinux_state
- coreos_enable_selinux_kernel_argument
Expand Down Expand Up @@ -822,8 +821,7 @@

https://issues.redhat.com/browse/CMP-115
rules:
# (jhrozek): Disabled because of https://issues.redhat.com/browse/OCPBUGS-6968
#- selinux_confinement_of_daemons
- selinux_confinement_of_daemons
- no_shelllogin_for_systemaccounts
- sysctl_kernel_perf_event_paranoid
- sysctl_kernel_unprivileged_bpf_disabled
Expand Down Expand Up @@ -4919,8 +4917,7 @@
- audit_rules_privileged_commands_userhelper
- audit_rules_networkconfig_modification
- audit_rules_etc_shadow_openat
# (jhrozek): Disabled because of https://issues.redhat.com/browse/OCPBUGS-6968
#- selinux_confinement_of_daemons
- selinux_confinement_of_daemons
- audit_rules_etc_gshadow_open_by_handle_at
- audit_rules_etc_gshadow_open
- var_auditd_space_left_action=syslog
Expand Down Expand Up @@ -5166,8 +5163,7 @@
- service_bluetooth_disabled
- kernel_module_tipc_disabled
- sysctl_net_ipv6_conf_all_accept_redirects
# (jhrozek): Disabled because of https://issues.redhat.com/browse/OCPBUGS-6968
#- selinux_confinement_of_daemons
- selinux_confinement_of_daemons
- sysctl_net_ipv4_tcp_syncookies
- sysctl_net_ipv4_icmp_ignore_bogus_error_responses
- coreos_vsyscall_kernel_argument
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,64 @@
<def-group>
<definition class="compliance" id="selinux_confinement_of_daemons" version="1">
{{{ oval_metadata("All pids in /proc should be assigned an SELinux security context other than 'unconfined_service_t'.", rule_title=rule_title) }}}
<criteria>
<criterion comment="no unconfined_service_t in /proc" test_ref="test_selinux_confinement_of_daemons" />
<definition class="compliance" id="selinux_confinement_of_daemons" version="2">
{{{ oval_metadata("All pids in /proc should be assigned an SELinux security context other than 'unconfined_service_t' (kubelet excluded).", rule_title=rule_title) }}}
<criteria operator="OR">
<criterion comment="no unconfined_service_t processes exist" test_ref="test_no_unconfined_service_t_processes" />
<criterion comment="only kubelet has unconfined_service_t" test_ref="test_only_kubelet_unconfined" />
</criteria>
</definition>
<linux:selinuxsecuritycontext_test check="none satisfy" check_existence="any_exist" comment="none satisfy unconfined_service_t in /proc" id="test_selinux_confinement_of_daemons" version="2">

<!-- Test 1: Check if NO processes have unconfined_service_t -->
<linux:selinuxsecuritycontext_test check="none satisfy" check_existence="any_exist"
comment="no processes with unconfined_service_t" id="test_no_unconfined_service_t_processes" version="1">
<linux:object object_ref="object_selinux_confinement_of_daemons" />
<linux:state state_ref="state_selinux_confinement_of_daemons" />
<linux:state state_ref="state_unconfined_service_t" />
</linux:selinuxsecuritycontext_test>
<linux:selinuxsecuritycontext_object comment="find unconfined_service_t in /proc" id="object_selinux_confinement_of_daemons" version="1">

<!-- Test 2: Check that all unconfined_service_t processes are kubelet -->
<ind:textfilecontent54_test check="all" check_existence="all_exist"
comment="all unconfined_service_t processes are kubelet" id="test_only_kubelet_unconfined" version="1">
<ind:object object_ref="object_unconfined_service_t_cmdlines" />
<ind:state state_ref="state_cmdline_is_kubelet" />
</ind:textfilecontent54_test>

<!-- Object: Find all processes in /proc -->
<linux:selinuxsecuritycontext_object comment="find all processes in /proc" id="object_selinux_confinement_of_daemons" version="2">
<linux:behaviors max_depth="1" recurse_direction="down" />
<linux:path>/proc</linux:path>
<linux:filename operation="pattern match">^.*$</linux:filename>
<filter action="include">state_selinux_confinement_of_daemons</filter>
<linux:filename operation="pattern match">^[0-9]+$</linux:filename>
</linux:selinuxsecuritycontext_object>
<linux:selinuxsecuritycontext_state comment="state unconfined_service_t" id="state_selinux_confinement_of_daemons" version="1">

<!-- Object: Read cmdline for processes with unconfined_service_t -->
<ind:textfilecontent54_object comment="cmdline of unconfined_service_t processes" id="object_unconfined_service_t_cmdlines" version="1">
<ind:filepath operation="equals" var_ref="var_unconfined_cmdline_paths" var_check="at least one"/>
<ind:pattern operation="pattern match">^(.*)$</ind:pattern>
<ind:instance datatype="int" operation="equals">1</ind:instance>
</ind:textfilecontent54_object>

<!-- Variable: Build /proc/PID/cmdline paths for unconfined processes -->
<local_variable id="var_unconfined_cmdline_paths" datatype="string" comment="cmdline paths for unconfined_service_t PIDs" version="1">
<concat>
<literal_component>/proc/</literal_component>
<object_component object_ref="object_unconfined_selinux_contexts" item_field="pid"/>
<literal_component>/cmdline</literal_component>
</concat>
</local_variable>

<!-- Object: SELinux contexts filtered to unconfined_service_t -->
<linux:selinuxsecuritycontext_object comment="unconfined_service_t contexts" id="object_unconfined_selinux_contexts" version="1">
<linux:behaviors max_depth="1" recurse_direction="down" />
<linux:path>/proc</linux:path>
<linux:filename operation="pattern match">^[0-9]+$</linux:filename>
<filter action="include">state_unconfined_service_t</filter>
</linux:selinuxsecuritycontext_object>

<!-- State: Match unconfined_service_t type -->
<linux:selinuxsecuritycontext_state comment="state unconfined_service_t" id="state_unconfined_service_t" version="1">
<linux:type datatype="string" operation="equals">unconfined_service_t</linux:type>
</linux:selinuxsecuritycontext_state>

<!-- State: Match kubelet in cmdline -->
<ind:textfilecontent54_state comment="kubelet cmdline" id="state_cmdline_is_kubelet" version="1">
<ind:subexpression operation="pattern match">.*kubelet.*</ind:subexpression>
</ind:textfilecontent54_state>
</def-group>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash
#
# This test simulates kubelet running with unconfined_service_t (OCP 4.12 scenario)

# Create a mock kubelet process that will run as unconfined_service_t
cat > /usr/local/bin/mock-kubelet << 'EOF'
#!/bin/bash
while true; do
sleep 3600
done
EOF
chmod +x /usr/local/bin/mock-kubelet

# Create systemd service
cat > /etc/systemd/system/mock-kubelet.service << 'EOF'
[Unit]
Description=Mock Kubelet Service

[Service]
Type=simple
ExecStart=/usr/local/bin/mock-kubelet
Restart=no

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl start mock-kubelet.service

# Wait for service to start
sleep 2

# Exit cleanly - the OVAL check should pass because kubelet is excluded
# Note: In test environments without SELinux enforcing, this tests the OVAL logic
exit 0
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@

# sshd should be running and should have specific rules in SELinux policy
# so it should not be detected as unconfined_service_t.
systemctl status sshd.service
systemctl start sshd.service 2>/dev/null || true

# Exit cleanly - the OVAL check should find no unconfined_service_t processes
exit 0
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# remediation = none

cat > /usr/bin/dummydaemon.sh << EOF
cat > /usr/bin/dummydaemon.sh << 'EOF'
#!/bin/bash

while true; do
Expand All @@ -12,17 +12,24 @@ done
EOF
chmod +x /usr/bin/dummydaemon.sh

cat > /etc/systemd/system/dummydaemon.service << EOF
cat > /etc/systemd/system/dummydaemon.service << 'EOF'
[Unit]
Description=Dummy daemon

[Service]
Type=simple
ExecStart=/usr/bin/dummydaemon.sh
Restart=on-failure
Restart=no

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl start dummydaemon.service
systemctl status dummydaemon.service

# Wait a moment for service to start
sleep 2

# Exit cleanly - the OVAL check should detect an unconfined daemon and fail
exit 0
Loading