diff options
Diffstat (limited to 'runsc/mitigate/cpu.go')
-rw-r--r-- | runsc/mitigate/cpu.go | 235 |
1 files changed, 0 insertions, 235 deletions
diff --git a/runsc/mitigate/cpu.go b/runsc/mitigate/cpu.go deleted file mode 100644 index 113b98159..000000000 --- a/runsc/mitigate/cpu.go +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright 2021 The gVisor Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package mitigate - -import ( - "fmt" - "regexp" - "strconv" - "strings" -) - -const ( - // constants of coomm - meltdown = "cpu_meltdown" - l1tf = "l1tf" - mds = "mds" - swapgs = "swapgs" - taa = "taa" -) - -const ( - processorKey = "processor" - vendorIDKey = "vendor_id" - cpuFamilyKey = "cpu family" - modelKey = "model" - coreIDKey = "core id" - bugsKey = "bugs" -) - -// getCPUSet returns cpu structs from reading /proc/cpuinfo. -func getCPUSet(data string) ([]*cpu, error) { - // Each processor entry should start with the - // processor key. Find the beginings of each. - r := buildRegex(processorKey, `\d+`) - indices := r.FindAllStringIndex(data, -1) - if len(indices) < 1 { - return nil, fmt.Errorf("no cpus found for: %s", data) - } - - // Add the ending index for last entry. - indices = append(indices, []int{len(data), -1}) - - // Valid cpus are now defined by strings in between - // indexes (e.g. data[index[i], index[i+1]]). - // There should be len(indicies) - 1 CPUs - // since the last index is the end of the string. - var cpus = make([]*cpu, 0, len(indices)-1) - // Find each string that represents a CPU. These begin "processor". - for i := 1; i < len(indices); i++ { - start := indices[i-1][0] - end := indices[i][0] - // Parse the CPU entry, which should be between start/end. - c, err := getCPU(data[start:end]) - if err != nil { - return nil, err - } - cpus = append(cpus, c) - } - return cpus, nil -} - -// type cpu represents pertinent info about a cpu. -type cpu struct { - processorNumber int64 // the processor number of this CPU. - vendorID string // the vendorID of CPU (e.g. AuthenticAMD). - cpuFamily int64 // CPU family number (e.g. 6 for CascadeLake/Skylake). - model int64 // CPU model number (e.g. 85 for CascadeLake/Skylake). - coreID int64 // This CPU's core id to match Hyperthread Pairs - bugs map[string]struct{} // map of vulnerabilities parsed from the 'bugs' field. -} - -// getCPU parses a CPU from a single cpu entry from /proc/cpuinfo. -func getCPU(data string) (*cpu, error) { - processor, err := parseProcessor(data) - if err != nil { - return nil, err - } - - vendorID, err := parseVendorID(data) - if err != nil { - return nil, err - } - - cpuFamily, err := parseCPUFamily(data) - if err != nil { - return nil, err - } - - model, err := parseModel(data) - if err != nil { - return nil, err - } - - coreID, err := parseCoreID(data) - if err != nil { - return nil, err - } - - bugs, err := parseBugs(data) - if err != nil { - return nil, err - } - - return &cpu{ - processorNumber: processor, - vendorID: vendorID, - cpuFamily: cpuFamily, - model: model, - coreID: coreID, - bugs: bugs, - }, nil -} - -// List of pertinent side channel vulnerablilites. -// For mds, see: https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html. -var vulnerabilities = []string{ - meltdown, - l1tf, - mds, - swapgs, - taa, -} - -// isVulnerable checks if a CPU is vulnerable to pertinent bugs. -func (c *cpu) isVulnerable() bool { - for _, bug := range vulnerabilities { - if _, ok := c.bugs[bug]; ok { - return true - } - } - return false -} - -// similarTo checks family/model/bugs fields for equality of two -// processors. -func (c *cpu) similarTo(other *cpu) bool { - if c.vendorID != other.vendorID { - return false - } - - if other.cpuFamily != c.cpuFamily { - return false - } - - if other.model != c.model { - return false - } - - if len(other.bugs) != len(c.bugs) { - return false - } - - for bug := range c.bugs { - if _, ok := other.bugs[bug]; !ok { - return false - } - } - return true -} - -// parseProcessor grabs the processor field from /proc/cpuinfo output. -func parseProcessor(data string) (int64, error) { - return parseIntegerResult(data, processorKey) -} - -// parseVendorID grabs the vendor_id field from /proc/cpuinfo output. -func parseVendorID(data string) (string, error) { - return parseRegex(data, vendorIDKey, `[\w\d]+`) -} - -// parseCPUFamily grabs the cpu family field from /proc/cpuinfo output. -func parseCPUFamily(data string) (int64, error) { - return parseIntegerResult(data, cpuFamilyKey) -} - -// parseModel grabs the model field from /proc/cpuinfo output. -func parseModel(data string) (int64, error) { - return parseIntegerResult(data, modelKey) -} - -// parseCoreID parses the core id field. -func parseCoreID(data string) (int64, error) { - return parseIntegerResult(data, coreIDKey) -} - -// parseBugs grabs the bugs field from /proc/cpuinfo output. -func parseBugs(data string) (map[string]struct{}, error) { - result, err := parseRegex(data, bugsKey, `[\d\w\s]*`) - if err != nil { - return nil, err - } - bugs := strings.Split(result, " ") - ret := make(map[string]struct{}, len(bugs)) - for _, bug := range bugs { - ret[bug] = struct{}{} - } - return ret, nil -} - -// parseIntegerResult parses fields expecting an integer. -func parseIntegerResult(data, key string) (int64, error) { - result, err := parseRegex(data, key, `\d+`) - if err != nil { - return 0, err - } - return strconv.ParseInt(result, 0, 64) -} - -// buildRegex builds a regex for parsing each CPU field. -func buildRegex(key, match string) *regexp.Regexp { - reg := fmt.Sprintf(`(?m)^%s\s*:\s*(.*)$`, key) - return regexp.MustCompile(reg) -} - -// parseRegex parses data with key inserted into a standard regex template. -func parseRegex(data, key, match string) (string, error) { - r := buildRegex(key, match) - matches := r.FindStringSubmatch(data) - if len(matches) < 2 { - return "", fmt.Errorf("failed to match key %s: %s", key, data) - } - return matches[1], nil -} |