diff --git a/audit/internal/collector/dmesg_events.go b/audit/internal/collector/dmesg_events.go index 6415f7a..fed6dfb 100644 --- a/audit/internal/collector/dmesg_events.go +++ b/audit/internal/collector/dmesg_events.go @@ -108,6 +108,23 @@ func matchesAny(s string, patterns []*regexp.Regexp) bool { return false } +// dmesgSeverityCriticalPatterns use \b word boundaries, unlike a plain +// strings.Contains check, so common words that merely contain a keyword as a +// substring don't false-positive — e.g. "disabled by default" contains +// "fault" (de-fault), and "undead" would contain "dead". +var dmesgSeverityCriticalPatterns = []*regexp.Regexp{ + regexp.MustCompile(`(?i)\bpanic\b`), + regexp.MustCompile(`(?i)\baer\b`), + regexp.MustCompile(`(?i)\buncorrect`), + regexp.MustCompile(`(?i)\bxid\b`), + regexp.MustCompile(`(?i)\bnvrm\b`), + regexp.MustCompile(`(?i)\berror\b`), + regexp.MustCompile(`(?i)\bfault\b`), + regexp.MustCompile(`(?i)\bfail(ed|ure)?\b`), + regexp.MustCompile(`(?i)\bdead\b`), + regexp.MustCompile(`(?i)\bhang\b`), +} + func dmesgSeverity(msg string) string { if sev, ok := XidSeverity(msg); ok { if sev == "critical" { @@ -115,21 +132,8 @@ func dmesgSeverity(msg string) string { } return statusWarning } - lower := strings.ToLower(msg) - switch { - case strings.Contains(lower, "panic") || - strings.Contains(lower, "aer") || - strings.Contains(lower, "uncorrect") || - strings.Contains(lower, "xid") || - strings.Contains(lower, "nvrm"): + if matchesAny(msg, dmesgSeverityCriticalPatterns) { return statusCritical - case strings.Contains(lower, "error") || - strings.Contains(lower, "fault") || - strings.Contains(lower, "fail") || - strings.Contains(lower, "dead") || - strings.Contains(lower, "hang"): - return statusCritical - default: - return statusWarning } + return statusWarning } diff --git a/audit/internal/collector/dmesg_events_test.go b/audit/internal/collector/dmesg_events_test.go index d46de2c..ad04de2 100644 --- a/audit/internal/collector/dmesg_events_test.go +++ b/audit/internal/collector/dmesg_events_test.go @@ -33,6 +33,16 @@ func TestDmesgSeverity_xidCodes(t *testing.T) { msg: "blk_update_request: I/O error, dev sda", want: statusCritical, }, + { + name: "disabled by default is not a fault substring match", + msg: "Yama: disabled by default; enable with sysctl kernel.yama.*", + want: statusWarning, + }, + { + name: "benign NVRM driver load message still escalates via NVRM keyword", + msg: "NVRM: loading NVIDIA UNIX Open Kernel Module for x86_64 580.159.03", + want: statusCritical, + }, } for _, tt := range tests {