...

Source file src/github.com/prometheus/procfs/sysfs/vulnerability.go

Documentation: github.com/prometheus/procfs/sysfs

     1  // Copyright 2019 The Prometheus Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  //go:build linux
    15  // +build linux
    16  
    17  package sysfs
    18  
    19  import (
    20  	"os"
    21  	"path/filepath"
    22  	"strings"
    23  )
    24  
    25  const (
    26  	notAffected = "not affected" // based on: https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu
    27  	vulnerable  = "vulnerable"
    28  	mitigation  = "mitigation"
    29  	unknown     = "unknown"
    30  )
    31  
    32  const (
    33  	VulnerabilityStateNotAffected = iota
    34  	VulnerabilityStateVulnerable
    35  	VulnerabilityStateMitigation
    36  	VulnerabilityStateUnknown
    37  )
    38  
    39  var (
    40  	// VulnerabilityHumanEncoding allows mapping the vulnerability state (encoded as an int) onto a human friendly
    41  	// string. It can be used by consumers of this library to expose to the user the state of the vulnerability.
    42  	VulnerabilityHumanEncoding = map[int]string{
    43  		VulnerabilityStateNotAffected: notAffected,
    44  		VulnerabilityStateVulnerable:  vulnerable,
    45  		VulnerabilityStateMitigation:  mitigation,
    46  		VulnerabilityStateUnknown:     unknown,
    47  	}
    48  )
    49  
    50  // CPUVulnerabilities retrieves a map of vulnerability names to their mitigations.
    51  func (fs FS) CPUVulnerabilities() (map[string]*Vulnerability, error) {
    52  	matchingFilepaths, err := filepath.Glob(fs.sys.Path("devices/system/cpu/vulnerabilities/*"))
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	vulnerabilities := make(map[string]*Vulnerability, len(matchingFilepaths))
    58  	for _, path := range matchingFilepaths {
    59  		filename := filepath.Base(path)
    60  
    61  		rawContent, err := os.ReadFile(path)
    62  		if err != nil {
    63  			return nil, err
    64  		}
    65  
    66  		v, err := parseVulnerability(filename, string(rawContent))
    67  		if err != nil {
    68  			return nil, err
    69  		}
    70  
    71  		vulnerabilities[filename] = v
    72  	}
    73  
    74  	return vulnerabilities, nil
    75  }
    76  
    77  // Vulnerability represents a single vulnerability extracted from /sys/devices/system/cpu/vulnerabilities/.
    78  type Vulnerability struct {
    79  	CodeName   string
    80  	State      int
    81  	Mitigation string
    82  }
    83  
    84  func parseVulnerability(name, rawContent string) (*Vulnerability, error) {
    85  	v := &Vulnerability{CodeName: name}
    86  	rawContent = strings.TrimSpace(rawContent)
    87  	rawContentLower := strings.ToLower(rawContent)
    88  	switch {
    89  	case strings.HasPrefix(rawContentLower, notAffected):
    90  		v.State = VulnerabilityStateNotAffected
    91  	case strings.HasPrefix(rawContentLower, vulnerable):
    92  		v.State = VulnerabilityStateVulnerable
    93  		m := strings.Fields(rawContent)
    94  		if len(m) > 1 {
    95  			v.Mitigation = strings.Join(m[1:], " ")
    96  		}
    97  	case strings.HasPrefix(rawContentLower, mitigation):
    98  		v.State = VulnerabilityStateMitigation
    99  		m := strings.Fields(rawContent)
   100  		if len(m) > 1 {
   101  			v.Mitigation = strings.Join(m[1:], " ")
   102  		}
   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  		}
   109  	default:
   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
   114  	}
   115  	return v, nil
   116  }
   117  

View as plain text