Skip to content

Commit 5056707

Browse files
jopelimaSuperQ
andauthored
Improve sysfs vulnerability parsing (prometheus#568)
The existing sysfs vulnerability parsing routines expected the data provided by the kernel to start with either "Not Affected"/"Vulnerable"/"Mitigation"; however, there are a handful of vulnerabilities that can provide data not matching this expectation: - https://elixir.bootlin.com/linux/v6.1.53/source/arch/x86/kernel/cpu/bugs.c#L2519 - https://elixir.bootlin.com/linux/v6.1.53/source/arch/x86/kernel/cpu/bugs.c#L546 - https://elixir.bootlin.com/linux/v6.1.53/source/arch/x86/kernel/cpu/bugs.c#L2578 Modify the vulnerability parsing to make use of a 4th state ("Unknown"), which is used when the vulnerability information can't be parsed to any of the other vulnerability states, and output the information provided by the kernel, rather than erroring out. Vulnerability parsing tests have been updated to include the aforementioned vulnerability data. Signed-off-by: João Lima <[email protected]> Co-authored-by: Ben Kochie <[email protected]>
1 parent 340d4b8 commit 5056707

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

sysfs/vulnerability.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package sysfs
1818

1919
import (
20-
"fmt"
2120
"os"
2221
"path/filepath"
2322
"strings"
@@ -27,12 +26,14 @@ const (
2726
notAffected = "not affected" // based on: https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu
2827
vulnerable = "vulnerable"
2928
mitigation = "mitigation"
29+
unknown = "unknown"
3030
)
3131

3232
const (
3333
VulnerabilityStateNotAffected = iota
3434
VulnerabilityStateVulnerable
3535
VulnerabilityStateMitigation
36+
VulnerabilityStateUnknown
3637
)
3738

3839
var (
@@ -42,6 +43,7 @@ var (
4243
VulnerabilityStateNotAffected: notAffected,
4344
VulnerabilityStateVulnerable: vulnerable,
4445
VulnerabilityStateMitigation: mitigation,
46+
VulnerabilityStateUnknown: unknown,
4547
}
4648
)
4749

@@ -98,9 +100,17 @@ func parseVulnerability(name, rawContent string) (*Vulnerability, error) {
98100
if len(m) > 1 {
99101
v.Mitigation = strings.Join(m[1:], " ")
100102
}
103+
case strings.HasPrefix(rawContentLower, unknown):
104+
v.State = VulnerabilityStateUnknown
105+
m := strings.Fields(rawContent)
106+
if len(m) > 1 {
107+
v.Mitigation = strings.Join(m[1:], " ")
108+
}
101109
default:
102-
return nil, fmt.Errorf("unknown vulnerability state for %s: %s", name, rawContent)
103-
110+
// Output the raw data obtained from the vulnerability, with state
111+
// unknown, rather than erroring out
112+
v.State = VulnerabilityStateUnknown
113+
v.Mitigation = rawContent
104114
}
105115
return v, nil
106116
}

sysfs/vulnerability_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,15 @@ func TestFS_CPUVulnerabilities(t *testing.T) {
3838
want *Vulnerability
3939
wantErr bool
4040
}{
41-
{"Not affected", "itlb_multihit", &Vulnerability{CodeName: "itlb_multihit", State: VulnerabilityStateNotAffected, Mitigation: ""}, false},
42-
{"Not affected with underscores", "tsx_async_abort", &Vulnerability{CodeName: "tsx_async_abort", State: VulnerabilityStateNotAffected, Mitigation: ""}, false},
41+
{"Not affected", "tsx_async_abort", &Vulnerability{CodeName: "tsx_async_abort", State: VulnerabilityStateNotAffected, Mitigation: ""}, false},
4342
{"Mitigation simple string", "spec_store_bypass", &Vulnerability{CodeName: "spec_store_bypass", State: VulnerabilityStateMitigation, Mitigation: "Speculative Store Bypass disabled via prctl"}, false},
4443
{"Mitigation special chars", "retbleed", &Vulnerability{CodeName: "retbleed", State: VulnerabilityStateMitigation, Mitigation: "untrained return thunk; SMT enabled with STIBP protection"}, false},
4544
{"Mitigation more special chars", "spectre_v1", &Vulnerability{CodeName: "spectre_v1", State: VulnerabilityStateMitigation, Mitigation: "usercopy/swapgs barriers and __user pointer sanitization"}, false},
4645
{"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},
4746
{"Vulnerable", "mds", &Vulnerability{CodeName: "mds", State: VulnerabilityStateVulnerable, Mitigation: ""}, false},
4847
{"Vulnerable with mitigation available", "mmio_stale_data", &Vulnerability{CodeName: "mmio_stale_data", State: VulnerabilityStateVulnerable, Mitigation: "Clear CPU buffers attempted, no microcode"}, false},
48+
{"Unknown", "srbds", &Vulnerability{CodeName: "srbds", State: VulnerabilityStateUnknown, Mitigation: "Dependent on hypervisor status"}, false},
49+
{"Unknown with unparseable mitigation", "itlb_multihit", &Vulnerability{CodeName: "itlb_multihit", State: VulnerabilityStateUnknown, Mitigation: "KVM: Mitigation: VMX unsupported"}, false},
4950
}
5051
for _, tt := range tests {
5152
t.Run(tt.name, func(t *testing.T) {

testdata/fixtures.ttar

+6-1
Original file line numberDiff line numberDiff line change
@@ -13239,7 +13239,7 @@ Mode: 755
1323913239
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1324013240
Path: fixtures/sys/devices/system/cpu/vulnerabilities/itlb_multihit
1324113241
Lines: 1
13242-
Not affected
13242+
KVM: Mitigation: VMX unsupported
1324313243
Mode: 444
1324413244
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1324513245
Path: fixtures/sys/devices/system/cpu/vulnerabilities/mds
@@ -13272,6 +13272,11 @@ Lines: 1
1327213272
Mitigation: Retpolines, IBPB: conditional, STIBP: always-on, RSB filling, PBRSB-eIBRS: Not affected
1327313273
Mode: 444
1327413274
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
13275+
Path: fixtures/sys/devices/system/cpu/vulnerabilities/srbds
13276+
Lines: 1
13277+
Unknown: Dependent on hypervisor status
13278+
Mode: 444
13279+
# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1327513280
Path: fixtures/sys/devices/system/cpu/vulnerabilities/tsx_async_abort
1327613281
Lines: 1
1327713282
Not affected

0 commit comments

Comments
 (0)