github.com/iDigitalFlame/xmt@v0.5.4/device/cpu_other_nix_no_crypt.go (about) 1 //go:build !amd64 && !386 && !windows && !crypt 2 // +build !amd64,!386,!windows,!crypt 3 4 // Copyright (C) 2020 - 2023 iDigitalFlame 5 // 6 // This program is free software: you can redistribute it and/or modify 7 // it under the terms of the GNU General Public License as published by 8 // the Free Software Foundation, either version 3 of the License, or 9 // any later version. 10 // 11 // This program is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 // 16 // You should have received a copy of the GNU General Public License 17 // along with this program. If not, see <https://www.gnu.org/licenses/>. 18 // 19 20 package device 21 22 import ( 23 "bytes" 24 "os" 25 "strings" 26 27 "github.com/iDigitalFlame/xmt/data" 28 ) 29 30 func isVirtual() bool { 31 // Check for a container first 32 // OpenVZ 33 if _, err := os.Lstat("/proc/vz"); err == nil { 34 if _, err := os.Lstat("/proc/bc"); err != nil { 35 return true 36 } 37 } 38 // Docker 39 if _, err := os.Lstat("/.dockerenv"); err == nil { 40 return true 41 } 42 if _, err := os.Lstat("/run/.containerenv"); err == nil { 43 return true 44 } 45 // systemd-nspawn 46 if _, err := os.Lstat("/run/systemd/container"); err == nil { 47 return true 48 } 49 // WSL 50 if b, _ := data.ReadFile("/proc/sys/kernel/osrelease"); len(b) > 0 { 51 if x := bytes.IndexByte(b, 'M'); x > -1 && x+8 < len(b) { 52 // Microsoft 53 if (b[x+1] == 'I' || b[x+1] == 'i') && (b[x+2] == 'C' || b[x+2] == 'c') && (b[x+3] == 'R' || b[x+3] == 'r') && (b[x+4] == 'O' || b[x+4] == 'o') { 54 return true 55 } 56 } 57 if x := bytes.IndexByte(b, 'W'); x > -1 && x+2 < len(b) { 58 // WSL 59 if (b[x+1] == 'S' || b[x+1] == 's') && (b[x+2] == 'L' || b[x+2] == 'l') { 60 return true 61 } 62 } 63 } 64 // PROOT 65 var n string 66 for _, v := range data.ReadSplit("/proc/self/status", "\n") { 67 if len(v) == 0 || (v[0] != 'T' && v[0] != 't') { 68 continue 69 } 70 // TracerPid 71 if (v[1] != 'R' && v[1] != 'r') || (v[3] != 'C' && v[3] != 'c') || (v[6] != 'P' && v[6] != 'p') || (v[8] != 'D' && v[8] != 'd') { 72 continue 73 } 74 x := strings.IndexByte(v, ':') 75 if x < 8 { 76 continue 77 } 78 n = strings.TrimSpace(v[x+1:]) 79 break 80 } 81 if len(n) > 0 { 82 if p, _ := data.ReadFile("/proc/" + n + "/comm"); len(p) > 0 { 83 // proot 84 if (p[0] == 'P' || p[0] == 'p') && (p[1] == 'R' || p[1] == 'r') && (p[2] == 'O' || p[2] == 'o') && (p[4] == 'T' || p[8] == 't') { 85 return true 86 } 87 } 88 } 89 if os.Getpid() == 1 { 90 if k, ok := os.LookupEnv("CONTAINER"); ok && len(k) > 0 { 91 return true 92 } 93 } 94 if b, _ := data.ReadFile("/proc/1/environ"); len(b) > 0 { 95 for s, e, n := 0, 0, 0; e < len(b); e++ { 96 if b[e] != 0 { 97 continue 98 } 99 if e-s > 9 { 100 // CONTAINER= 101 if b[s] == 'C' && b[s+1] == 'O' && b[s+2] == 'N' && b[s+7] == 'N' && b[s+9] == 'R' && b[s+10] == '=' { 102 return true 103 } 104 } 105 s, n = e+1, n+1 106 } 107 } 108 // User Mode Linux 109 for _, v := range data.ReadSplit("/proc/cpuinfo", "\n") { 110 if len(v) == 0 || (v[0] != 'V' && v[0] != 'v') { 111 continue 112 } 113 // vendor_id 114 if (v[1] != 'E' && v[1] != 'e') || (v[3] != 'D' && v[3] != 'd') || v[6] != '_' || (v[7] != 'I' && v[7] != 'i') { 115 continue 116 } 117 x := strings.IndexByte(v, ':') 118 if x < 8 { 119 continue 120 } 121 if n := strings.TrimSpace(v[x+1:]); len(n) >= 15 && (n[0] == 'U' || n[0] == 'u') && (n[5] == 'M' || n[5] == 'm') && (n[8] == 'E' || n[8] == 'e') && (n[10] == 'L' || n[10] == 'l') { 122 return true 123 } 124 } 125 // Check DMI 126 return checkVendorFile("/sys/class/dmi/id/sys_vendor") || 127 checkVendorFile("/sys/class/dmi/id/board_vendor") || 128 checkVendorFile("/sys/class/dmi/id/bios_vendor") || 129 checkVendorFile("/sys/class/dmi/id/product_version") 130 } 131 func checkVendorFile(s string) bool { 132 if b, _ := data.ReadFile(s); len(b) > 0 { 133 return isKnownVendor(bytes.TrimSpace(b)) 134 } 135 return false 136 }