Skip to content

fedora: add SELinux validation test suite - #4631

Open
balakreddy wants to merge 2 commits into
microsoft:mainfrom
balakreddy:fedora_ci_tests_3
Open

fedora: add SELinux validation test suite#4631
balakreddy wants to merge 2 commits into
microsoft:mainfrom
balakreddy:fedora_ci_tests_3

Conversation

@balakreddy

Copy link
Copy Markdown
Contributor

Description

Add selinux_validation.py with two test cases for Fedora cloud images: verify_setenforce and verify_selinux_info. Covers mode toggling, audit log verification (MAC_STATUS records), sestatus/avcstat field checks, and edge cases (selinuxfs unmounted, enforce file bind-mounted RO).

Sources:
https://src.fedoraproject.org/tests/selinux/blob/main/f/libselinux/setenforce https://src.fedoraproject.org/tests/selinux/blob/main/f/policycoreutils/selinux-info

Related Issue

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Refactoring
  • Documentation update

Checklist

  • Description is filled in above
  • No credentials, secrets, or internal details are included
  • Peer review requested (if not, add required peer reviewers after raising PR)
  • Tests executed and results posted below

Test Validation

Key Test Cases:

verify_selinux_info|verify_setenforce

Impacted LISA Features:

Tested Azure Marketplace Images:

  • WestUS3/Fedora-5e266ba4-2250-406d-adad-5d73860d958f/Fedora-Cloud-44-x64/latest

Test Results

Image VM Size Result
WestUS3/Fedora-5e266ba4-2250-406d-adad-5d73860d958f/Fedora-Cloud-44-x64/latest Standard_D2ads_v5 PASSED

2026-08-04 01:54:22.970[140166918605760][INFO] lisa.RootRunner ________________________________________
2026-08-04 01:54:22.970[140166918605760][INFO] lisa.RootRunner FedoraSELinuxValidation.verify_setenforce: PASSED
2026-08-04 01:54:22.970[140166918605760][INFO] lisa.RootRunner FedoraSELinuxValidation.verify_selinux_info: PASSED
2026-08-04 01:54:22.970[140166918605760][INFO] lisa.RootRunner test result summary
2026-08-04 01:54:22.970[140166918605760][INFO] lisa.RootRunner TOTAL : 2
2026-08-04 01:54:22.970[140166918605760][INFO] lisa.RootRunner QUEUED : 0
2026-08-04 01:54:22.970[140166918605760][INFO] lisa.RootRunner ASSIGNED : 0
2026-08-04 01:54:22.970[140166918605760][INFO] lisa.RootRunner RUNNING : 0
2026-08-04 01:54:22.970[140166918605760][INFO] lisa.RootRunner FAILED : 0
2026-08-04 01:54:22.971[140166918605760][INFO] lisa.RootRunner PASSED : 2
2026-08-04 01:54:22.971[140166918605760][INFO] lisa.RootRunner SKIPPED : 0
2026-08-04 01:54:22.973[140166918605760][INFO] lisa.notifier[Html] report: /lisa/runtime/log/20260804/20260804-014713-049/lisa.html
2026-08-04 01:54:22.982[140166918605760][INFO] lisa. completed in 429.937 sec

Add selinux_validation.py with two test cases for Fedora cloud images:
verify_setenforce and verify_selinux_info. Covers mode toggling, audit
log verification (MAC_STATUS records), sestatus/avcstat field checks,
and edge cases (selinuxfs unmounted, enforce file bind-mounted RO).

Sources:
https://src.fedoraproject.org/tests/selinux/blob/main/f/libselinux/setenforce
https://src.fedoraproject.org/tests/selinux/blob/main/f/policycoreutils/selinux-info

Signed-off-by: Bala Konda Reddy M <bala12352@gmail.com>
Copilot AI review requested due to automatic review settings August 4, 2026 02:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Fedora-focused SELinux validation test suite under lisa/microsoft/testsuites/fedora/, intended to validate SELinux mode switching and basic SELinux tooling behavior on Fedora cloud images.

Changes:

  • Introduces FedoraSELinuxValidation with a verify_setenforce test that toggles SELinux mode and validates corresponding audit events plus edge cases.
  • Adds verify_selinux_info coverage for getenforce, sestatus (including -b/-v), and avcstat output validation.
Suppressed comments (1)

lisa/microsoft/testsuites/fedora/selinux_validation.py:160

  • Magic-number timeout 30 should have an inline comment explaining why this value is appropriate, since it directly impacts test runtime/flakiness.
                check_mac_status_enforcing1,
                timeout_message=(
                    "MAC_STATUS record enforcing=1 old_enforcing=0"
                    " not found in audit log"
                ),
                timeout=30,
            )

Comment on lines +52 to +57
if backup.strip():
node.execute(
f"echo '{backup}' > /tmp/audit_backup && auditctl -R /tmp/audit_backup",
shell=True, sudo=True, no_error_log=True
)
node.execute("rm -f /tmp/audit_backup", sudo=True, no_error_log=True)
Comment on lines +101 to +104
Tests switching between SELinux enforcing and permissive modes,
validates mode changes are reflected in the enforce file and
audit logs, and verifies error handling for edge cases.
""",
Comment on lines +249 to +252
Tests that getenforce accurately reports mode changes, sestatus
displays all required policy fields and contexts, and avcstat
shows live AVC cache statistics.
""",
Comment on lines +124 to +126
# auditd must be active on boot; not started manually
self._wait_for_service_active(node, "auditd", timeout=60)

Comment on lines +197 to +201
node.execute(
f"mount -t selinuxfs none {self._SELINUX_FS_MOUNT}",
sudo=True,
)
node.log.info("Edge case: selinuxfs unmounted passed")
Comment on lines +209 to +215
node.execute("touch /var/tmp/selinux_enforce_bind_test", sudo=True)
node.execute("chattr +i /var/tmp/selinux_enforce_bind_test", sudo=True)
node.execute(
f"mount --bind /var/tmp/selinux_enforce_bind_test"
f" {self._SELINUX_FS_MOUNT}/enforce",
sudo=True,
)
Comment on lines +385 to +390
# Trigger a filesystem access to ensure AVC lookups increment between runs
node.execute("ls /etc/passwd", no_error_log=True)
avcstat2 = node.execute("avcstat")
assert_that(avcstat2.stdout).described_as(
"Two consecutive avcstat outputs must differ (AVC cache is active)"
).is_not_equal_to(avcstat1.stdout)
Apply Black auto-formatting and rename local variable _CON to _con
to fix pep8-naming N806 (uppercase variable in function scope).

Signed-off-by: Bala Konda Reddy M <bala12352@gmail.com>
Copilot AI review requested due to automatic review settings August 4, 2026 02:33
@balakreddy

Copy link
Copy Markdown
Contributor Author

Adding @jeremycline @nmeyerhans

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (8)

lisa/microsoft/testsuites/fedora/selinux_validation.py:60

  • The audit rules restore path embeds the full (potentially multi-line) backup string into a single-quoted shell command (echo '{backup}' ...). If the saved rules contain a single quote, the command breaks (and can also alter what gets restored). Escaping the payload before building the shell command makes the restore deterministic.
    def _restore_audit_rules(self, node: Node, backup: str) -> None:
        """Restore audit rules from backup."""
        node.execute("auditctl -D", sudo=True, no_error_log=True)
        if backup.strip():
            node.execute(
                f"echo '{backup}' > /tmp/audit_backup && auditctl -R /tmp/audit_backup",
                shell=True,
                sudo=True,
                no_error_log=True,
            )
            node.execute("rm -f /tmp/audit_backup", sudo=True, no_error_log=True)

lisa/microsoft/testsuites/fedora/selinux_validation.py:223

  • The "enforce file locked" edge-case relies on touch, chattr +i, and the mount --bind succeeding, but their exit codes aren't checked. If any of these steps fails, subsequent assertions can become misleading (or the edge-case validation can accidentally exercise the normal path).
            node.execute("touch /var/tmp/selinux_enforce_bind_test", sudo=True)
            node.execute("chattr +i /var/tmp/selinux_enforce_bind_test", sudo=True)
            node.execute(
                f"mount --bind /var/tmp/selinux_enforce_bind_test"
                f" {self._SELINUX_FS_MOUNT}/enforce",
                sudo=True,
            )

lisa/microsoft/testsuites/fedora/selinux_validation.py:403

  • Asserting avcstat stdout differs between two consecutive runs can be flaky: the counters may not change deterministically from a single ls /etc/passwd (or the change may be too small/fast to observe). A short bounded retry makes the check more reliable while keeping runtime low.
        # Trigger a filesystem access to ensure AVC lookups increment between runs
        node.execute("ls /etc/passwd", no_error_log=True)
        avcstat2 = node.execute("avcstat")
        assert_that(avcstat2.stdout).described_as(
            "Two consecutive avcstat outputs must differ (AVC cache is active)"
        ).is_not_equal_to(avcstat1.stdout)

lisa/microsoft/testsuites/fedora/selinux_validation.py:126

  • The timeout=60 here is a test-behavior magic number; adding a brief rationale comment makes it easier to maintain and tune without guessing later.
        self._wait_for_service_active(node, "auditd", timeout=60)

lisa/microsoft/testsuites/fedora/selinux_validation.py:162

  • This timeout=30 is a test-behavior magic number; please add a short inline rationale so future maintainers know why 30s is expected/acceptable for audit records to appear.
                timeout=30,

lisa/microsoft/testsuites/fedora/selinux_validation.py:86

  • _assert_cmd_fails_with_error currently treats a non-zero exit code as sufficient even when error_keywords are provided. For the edge-case checks that are supposed to validate a specific failure reason (e.g., "SELinux is disabled"), this can produce false positives where the command fails for an unrelated reason but the test still passes.
        result = node.execute(cmd, shell=True, sudo=True, no_error_log=True)
        combined = (result.stdout + result.stderr).lower()
        has_error = (
            any(kw in combined for kw in error_keywords) or result.exit_code != 0
        )
        assert_that(has_error).described_as(f"{desc} (got: {combined[:200]})").is_true()

lisa/microsoft/testsuites/fedora/selinux_validation.py:369

  • The SELinux context regex is too restrictive: valid contexts can include an MLS/MCS range and categories (e.g. s0-s0:c0.c1023). Limiting the pattern to :s\d+ risks false failures on otherwise-correct Fedora images.
        _con = r"[a-z_]+_u:[a-z_]+_r:[a-z_]+_t:s\d+"

lisa/microsoft/testsuites/fedora/selinux_validation.py:63

  • The default timeout value is a test-behavior control and should be documented inline (per project review guidelines on magic numbers) so future changes keep waits bounded and intentional.

This issue also appears on line 162 of the same file.

    def _wait_for_service_active(
        self, node: Node, service: str, timeout: int = 30
    ) -> None:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants