Fix aarch64 audit rules for unsupported syscalls#14757
Conversation
37bac4e to
06e5155
Compare
|
This datastream diff is auto generated by the check Click here to see the full diffNew content has different text for rule 'xccdf_org.ssgproject.content_rule_audit_rules_file_deletion_events'.
--- xccdf_org.ssgproject.content_rule_audit_rules_file_deletion_events
+++ xccdf_org.ssgproject.content_rule_audit_rules_file_deletion_events
@@ -16,6 +16,10 @@
system, or having two lines for both b32 and b64 in case your system is 64-bit:
-a always,exit -F arch=ARCH -S rmdir,unlink,unlinkat,rename,renameat2 -S renameat -F auid>=1000 -F auid!=unset -F key=delete
+If the system is aarch64, the 64-bit syscall table does not include
+rmdir, unlink, and rename syscalls. They are replaced by
+unlinkat, renameat, and renameat2, respectively.
+
[warning]:
This rule checks for multiple syscalls related to file deletion;
it was written with DISA STIG in mind. Other policies should use a
OVAL for rule 'xccdf_org.ssgproject.content_rule_audit_rules_file_deletion_events' differs.
--- oval:ssg-audit_rules_file_deletion_events:def:1
+++ oval:ssg-audit_rules_file_deletion_events:def:1
@@ -1,4 +1,11 @@
+criteria OR
criteria AND
+extend_definition oval:ssg-system_info_architecture_aarch_64:def:1
+extend_definition oval:ssg-audit_rules_file_deletion_events_unlinkat:def:1
+extend_definition oval:ssg-audit_rules_file_deletion_events_renameat:def:1
+extend_definition oval:ssg-audit_rules_file_deletion_events_renameat2:def:1
+criteria AND
+extend_definition oval:ssg-system_info_architecture_aarch_64:def:1
extend_definition oval:ssg-audit_rules_file_deletion_events_rmdir:def:1
extend_definition oval:ssg-audit_rules_file_deletion_events_unlink:def:1
extend_definition oval:ssg-audit_rules_file_deletion_events_unlinkat:def:1
bash remediation for rule 'xccdf_org.ssgproject.content_rule_audit_rules_file_deletion_events' differs.
--- xccdf_org.ssgproject.content_rule_audit_rules_file_deletion_events
+++ xccdf_org.ssgproject.content_rule_audit_rules_file_deletion_events
@@ -1,8 +1,22 @@
# Remediation is applicable only in certain platforms
if rpm --quiet -q audit && rpm --quiet -q kernel-core; then
-# Perform the remediation for the syscall rule
-# Retrieve hardware architecture of the underlying system
+# Remediation: write audit rules that log all file deletion events
+# ('rmdir', 'unlink', 'unlinkat', 'rename', 'renameat', 'renameat2'),
+# successful or not. Example output:
+# -a always,exit -F arch=b64 -S unlinkat -F auid>=1000 -F auid!=unset -k delete
+#
+# On aarch64, 'rmdir', 'unlink', and 'rename' do not exist in the b64
+# syscall table and are skipped. The b32 table (for 32-bit programs)
+# still has them.
+#
+# Writes to both '/etc/audit/rules.d/*.rules' (for 'augenrules') and
+# '/etc/audit/audit.rules' (for 'auditctl') so the remediation works
+# regardless of which tool the system uses to load audit rules.
+
+# Audit rules filter by program type: 32-bit programs use a different
+# syscall table than 64-bit programs. On 64-bit systems with a 32-bit
+# compatibility layer, both can run, so rules are written for each.
[ "$(getconf LONG_BIT)" = "32" ] && RULE_ARCHS=("b32") || RULE_ARCHS=("b32" "b64")
for ARCH in "${RULE_ARCHS[@]}"
@@ -10,10 +24,21 @@
ACTION_ARCH_FILTERS="-a always,exit -F arch=$ARCH"
OTHER_FILTERS=""
AUID_FILTERS="-F auid>=1000 -F auid!=unset"
- SYSCALL="rmdir unlink unlinkat rename renameat renameat2"
KEY="delete"
- SYSCALL_GROUPING="rmdir unlink unlinkat rename renameat renameat2"
+
+ # aarch64 b64 syscall table does not have rmdir, unlink, rename;
+ # the b32 table (for 32-bit programs, aarch64 can run 32-bit code) still has them
+ if [ "$(uname -m)" = "aarch64" ] && [ "$ARCH" = "b64" ]; then
+ SYSCALL="unlinkat renameat renameat2"
+ else
+ SYSCALL="rmdir unlink unlinkat rename renameat renameat2"
+ fi
+ # SYSCALL_GROUPING tells the macro which syscalls belong together
+ # so it merges them into existing rules instead of creating duplicates
+ SYSCALL_GROUPING="$SYSCALL"
+
# Perform the remediation for both possible tools: 'auditctl' and 'augenrules'
+
unset syscall_a
unset syscall_grouping
unset syscall_string
New content has different text for rule 'xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification'.
--- xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification
+++ xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification
@@ -24,6 +24,9 @@
-a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=access
-a always,exit -F arch=b64 -S creat,open,openat,open_by_handle_at,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=access
+If the system is aarch64, the 64-bit syscall table does not include
+creat and open syscalls. They are replaced by openat.
+
[warning]:
This rule checks for multiple syscalls related to unsuccessful file modification;
it was written with DISA STIG in mind. Other policies should use a
OVAL for rule 'xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification' differs.
--- oval:ssg-audit_rules_unsuccessful_file_modification:def:1
+++ oval:ssg-audit_rules_unsuccessful_file_modification:def:1
@@ -1,4 +1,12 @@
+criteria OR
criteria AND
+extend_definition oval:ssg-system_info_architecture_aarch_64:def:1
+extend_definition oval:ssg-audit_rules_unsuccessful_file_modification_ftruncate:def:1
+extend_definition oval:ssg-audit_rules_unsuccessful_file_modification_openat:def:1
+extend_definition oval:ssg-audit_rules_unsuccessful_file_modification_open_by_handle_at:def:1
+extend_definition oval:ssg-audit_rules_unsuccessful_file_modification_truncate:def:1
+criteria AND
+extend_definition oval:ssg-system_info_architecture_aarch_64:def:1
extend_definition oval:ssg-audit_rules_unsuccessful_file_modification_creat:def:1
extend_definition oval:ssg-audit_rules_unsuccessful_file_modification_ftruncate:def:1
extend_definition oval:ssg-audit_rules_unsuccessful_file_modification_openat:def:1
bash remediation for rule 'xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification' differs.
--- xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification
+++ xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification
@@ -1,21 +1,50 @@
# Remediation is applicable only in certain platforms
-if rpm --quiet -q audit && rpm --quiet -q kernel-core && { ( ! ( ( grep -sqE "^.*\.aarch64$" /proc/sys/kernel/osrelease || grep -sqE "^aarch64$" /proc/sys/kernel/arch; ) ) ); }; then
-
-# Perform the remediation of the syscall rule
-# Retrieve hardware architecture of the underlying system
+if rpm --quiet -q audit && rpm --quiet -q kernel-core; then
+
+# Remediation: write audit rules that log only failed file 'open', 'create',
+# and 'truncate' attempts -- not successful ones.
+# "Failed" means the syscall returned EACCES (permission denied) or
+# EPERM (operation not permitted).
+#
+# For each architecture (b32, b64) and each syscall, two audit rules are
+# written -- one for EACCES and one for EPERM -- because auditd cannot
+# match multiple exit codes in a single rule. Example output:
+# -a always,exit -F arch=b64 -S openat -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access
+# -a always,exit -F arch=b64 -S openat -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access
+#
+# On aarch64, 'creat' and 'open' do not exist in the b64 syscall table
+# and are skipped. The b32 table (for 32-bit programs) still has them.
+#
+# Writes to both '/etc/audit/rules.d/*.rules' (for 'augenrules') and
+# '/etc/audit/audit.rules' (for 'auditctl') so the remediation works
+# regardless of which tool the system uses to load audit rules.
+
+# Audit rules filter by program type: 32-bit programs use a different
+# syscall table than 64-bit programs. On 64-bit systems with a 32-bit
+# compatibility layer, both can run, so rules are written for each.
[ "$(getconf LONG_BIT)" = "32" ] && RULE_ARCHS=("b32") || RULE_ARCHS=("b32" "b64")
for ARCH in "${RULE_ARCHS[@]}"
do
-
- # First fix the -EACCES requirement
ACTION_ARCH_FILTERS="-a always,exit -F arch=$ARCH"
+ AUID_FILTERS="-F auid>=1000 -F auid!=unset"
+ KEY="access"
+
+ # aarch64 b64 syscall table does not have creat or open;
+ # the b32 table (for 32-bit programs, aarch64 can run 32-bit code) still has them
+ if [ "$(uname -m)" = "aarch64" ] && [ "$ARCH" = "b64" ]; then
+ SYSCALL="openat open_by_handle_at truncate ftruncate"
+ else
+ SYSCALL="creat open openat open_by_handle_at truncate ftruncate"
+ fi
+ # SYSCALL_GROUPING tells the macro which syscalls belong together
+ # so it merges them into existing rules instead of creating duplicates
+ SYSCALL_GROUPING="$SYSCALL"
+
+ # Perform the remediation for both possible tools: 'auditctl' and 'augenrules'
+
+ # First pass: EACCES (permission denied by file mode bits)
OTHER_FILTERS="-F exit=-EACCES"
- AUID_FILTERS="-F auid>=1000 -F auid!=unset"
- SYSCALL="creat open openat open_by_handle_at truncate ftruncate"
- KEY="access"
- SYSCALL_GROUPING="creat open openat open_by_handle_at truncate ftruncate"
- # Perform the remediation for both possible tools: 'auditctl' and 'augenrules'
unset syscall_a
unset syscall_grouping
unset syscall_string
@@ -322,15 +351,8 @@
fi
fi
- # Then fix the -EPERM requirement
- # No need to change content of $GROUP variable - it's the same as for -EACCES case above
- ACTION_ARCH_FILTERS="-a always,exit -F arch=$ARCH"
+ # Second pass: EPERM (operation needs a privilege the process lacks)
OTHER_FILTERS="-F exit=-EPERM"
- AUID_FILTERS="-F auid>=1000 -F auid!=unset"
- SYSCALL="creat open openat open_by_handle_at truncate ftruncate"
- KEY="access"
- SYSCALL_GROUPING="creat open openat open_by_handle_at truncate ftruncate"
- # Perform the remediation for both possible tools: 'auditctl' and 'augenrules'
unset syscall_a
unset syscall_grouping
unset syscall_string
@@ -636,7 +658,6 @@
sed -i -e "\#${rule_to_edit}#s#${rule_syscalls_to_edit}#${new_grouped_syscalls}#" "$file_to_edit"
fi
fi
-
done
else
Platform has been changed for rule 'xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification'
--- xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification
+++ xccdf_org.ssgproject.content_rule_audit_rules_unsuccessful_file_modification
@@ -1 +1 @@
-oval:ssg-proc_sys_kernel_osrelease_arch_aarch64:def:1
+ |
fa595fd to
99aabd2
Compare
dda0ba1 to
0602c82
Compare
Fix audit_rules_file_deletion_events and audit_rules_unsuccessful_file_modification for aarch64. The aarch64 b64 syscall table does not have some legacy syscalls. The b32 table (for 32-bit programs) still has all of them. Both rules wrote audit rules for these nonexistent syscalls. auditctl rejects unknown syscalls with "Syscall name unknown" and stops loading all subsequent rules, causing audit-rules.service to fail. Missing syscalls and their replacements: - rmdir, unlink, rename -> unlinkat, renameat, renameat2 - creat, open -> openat Changes: Bash remediations: - Detect aarch64 at runtime via uname -m - On aarch64 b64: write only supported syscalls - On b32 and non-aarch64: write all syscalls OVAL checks: - Detect aarch64 at scan time - On aarch64: expect only supported syscalls - On other architectures: expect all syscalls rule.yml: - Remove the aarch64 platform exclusion from audit_rules_unsuccessful_file_modification; the rule was excluded because it checked for nonexistent syscalls on aarch64, which is now fixed Resolves: ComplianceAsCode#14196 Resolves: ComplianceAsCode#14372
0602c82 to
b9d9b93
Compare
vojtapolasek
left a comment
There was a problem hiding this comment.
Looks good, nice documentation. Do you think you could add explanation of that difference in syscalls into the rule description in rule.yml? Thanks.
Document which syscalls do not exist in the aarch64 64-bit syscall table and what replaces them in audit_rules_file_deletion_events and audit_rules_unsuccessful_file_modification rule descriptions and bash remediation headers. Missing syscalls and their replacements: - rmdir, unlink, rename -> unlinkat, renameat, renameat2 - creat, open -> openat
|
@vojtapolasek Thanks for the review, I've updated the docs. PTAL |
vojtapolasek
left a comment
There was a problem hiding this comment.
Looks good now. Thank you.
|
/retest |
|
@macko1: The following tests failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
Description:
Fix
audit_rules_file_deletion_eventsandaudit_rules_unsuccessful_file_modificationfor aarch64.
Some syscalls do not exist on aarch64 for 64-bit programs. 32-bit programs (via the
compatibility layer) still have them.
Missing syscalls and their replacements:
rmdir,unlink,rename->unlinkat,renameat,renameat2creat,open->openatBoth rules had two problems on aarch64:
auditctlrejectsunknown syscalls with "Syscall name unknown" and stops loading all subsequent rules,
causing
audit-rules.serviceto fail.ones that don't exist on aarch64. A correctly configured aarch64 system would fail the
scan.
Changes:
Bash remediations (
bash/shared.sh):uname -mOVAL checks (
oval/shared.xml):audit_rules_unsuccessful_file_modification/rule.yml:platform: not aarch64_arch; the rule was completely excluded from aarch64because the OVAL and remediation didn't handle it. Now that they do, the exclusion is no
longer needed.
Rationale:
Per-syscall rules (e.g.
audit_rules_file_deletion_events_rename) already handle aarch64via
platform: not aarch64_arch.audit_rules_file_deletion_eventsandaudit_rules_unsuccessful_file_modificationbundleall syscalls into one rule and had no aarch64 handling:
Some profiles select them directly
Excluding them would mean no audit coverage on aarch64
This PR makes them work by writing only supported syscalls
Fixes audit-rules service fails due to unsupported rule group on aarch64 #14196
Fixes Do not expect auditd rules for obsolete syscalls on arm64/aarch64 architecture #14372
Review hints:
python3 automatus.py rule \ --libvirt qemu:///session rhel9-aarch64 \ --datastream build/ssg-rhel9-ds.xml \ audit_rules_file_deletion_events \ audit_rules_unsuccessful_file_modificationauditdloads the rules without errorsauditctl -lshows only supported syscalls for b64 rulesauditctl -R /etc/audit/rules.d/*.rules auditctl -lNote: I recommend using an
aarch64VM for this, or testing natively onaarch64.