diff --git a/sysfs/vulnerability.go b/sysfs/vulnerability.go index 11d38b2e..f6d950d5 100644 --- a/sysfs/vulnerability.go +++ b/sysfs/vulnerability.go @@ -24,9 +24,9 @@ import ( ) const ( - notAffected = "Not affected" // based on: https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu - vulnerable = "Vulnerable" - mitigation = "Mitigation" + notAffected = "not affected" // based on: https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu + vulnerable = "vulnerable" + mitigation = "mitigation" ) const ( @@ -80,20 +80,28 @@ type Vulnerability struct { func parseVulnerability(name, rawContent string) (*Vulnerability, error) { v := &Vulnerability{CodeName: name} rawContent = strings.TrimSpace(rawContent) - if rawContent == notAffected { + rawContentLower := strings.ToLower(rawContent) + + if strings.HasPrefix(rawContentLower, notAffected) { v.State = VulnerabilityStateNotAffected return v, nil } - if strings.HasPrefix(rawContent, vulnerable) { + if strings.HasPrefix(rawContentLower, vulnerable) { v.State = VulnerabilityStateVulnerable - v.Mitigation = strings.TrimPrefix(strings.TrimPrefix(rawContent, vulnerable), ": ") + m := strings.Fields(rawContent) + if len(m) > 1 { + v.Mitigation = strings.Join(m[1:], " ") + } return v, nil } - if strings.HasPrefix(rawContent, mitigation) { + if strings.HasPrefix(rawContentLower, mitigation) { v.State = VulnerabilityStateMitigation - v.Mitigation = strings.TrimPrefix(strings.TrimPrefix(rawContent, mitigation), ": ") + m := strings.Fields(rawContent) + if len(m) > 1 { + v.Mitigation = strings.Join(m[1:], " ") + } return v, nil } diff --git a/sysfs/vulnerability_test.go b/sysfs/vulnerability_test.go index 5cede084..89f9e611 100644 --- a/sysfs/vulnerability_test.go +++ b/sysfs/vulnerability_test.go @@ -44,6 +44,8 @@ func TestFS_CPUVulnerabilities(t *testing.T) { {"Mitigation special chars", "retbleed", &Vulnerability{CodeName: "retbleed", State: VulnerabilityStateMitigation, Mitigation: "untrained return thunk; SMT enabled with STIBP protection"}, false}, {"Mitigation more special chars", "spectre_v1", &Vulnerability{CodeName: "spectre_v1", State: VulnerabilityStateMitigation, Mitigation: "usercopy/swapgs barriers and __user pointer sanitization"}, false}, {"Mitigation with multiple subsections", "spectre_v2", &Vulnerability{CodeName: "spectre_v2", State: VulnerabilityStateMitigation, Mitigation: "Retpolines, IBPB: conditional, STIBP: always-on, RSB filling, PBRSB-eIBRS: Not affected"}, false}, + {"Vulnerable", "mds", &Vulnerability{CodeName: "mds", State: VulnerabilityStateVulnerable, Mitigation: ""}, false}, + {"Vulnerable with mitigation available", "mmio_stale_data", &Vulnerability{CodeName: "mmio_stale_data", State: VulnerabilityStateVulnerable, Mitigation: "Clear CPU buffers attempted, no microcode"}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/testdata/fixtures.ttar b/testdata/fixtures.ttar index 9de25385..decfe168 100644 --- a/testdata/fixtures.ttar +++ b/testdata/fixtures.ttar @@ -13242,6 +13242,16 @@ Lines: 1 Not affected Mode: 444 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/system/cpu/vulnerabilities/mds +Lines: 1 +Vulnerable +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Path: fixtures/sys/devices/system/cpu/vulnerabilities/mmio_stale_data +Lines: 1 +Vulnerable: Clear CPU buffers attempted, no microcode +Mode: 644 +# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Path: fixtures/sys/devices/system/cpu/vulnerabilities/retbleed Lines: 1 Mitigation: untrained return thunk; SMT enabled with STIBP protection