github.com/iDigitalFlame/xmt@v0.5.4/device/cpu_other_nix_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 "github.com/iDigitalFlame/xmt/util/crypt" 29 ) 30 31 func isVirtual() bool { 32 // Check for a container first 33 // OpenVZ 34 if _, err := os.Lstat(crypt.Get(49)); err == nil { // /proc/vz 35 if _, err := os.Lstat(crypt.Get(50)); err != nil { // /proc/bc 36 return true 37 } 38 } 39 // Docker 40 if _, err := os.Lstat(crypt.Get(51)); err == nil { // /.dockerenv 41 return true 42 } 43 if _, err := os.Lstat(crypt.Get(52)); err == nil { // /run/.containerenv 44 return true 45 } 46 // systemd-nspawn 47 if _, err := os.Lstat(crypt.Get(53)); err == nil { // /run/systemd/container 48 return true 49 } 50 // WSL 51 if b, _ := data.ReadFile(crypt.Get(54)); len(b) > 0 { // /proc/sys/kernel/osrelease 52 if x := bytes.IndexByte(b, 'M'); x > -1 && x+8 < len(b) { 53 // Microsoft 54 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') { 55 return true 56 } 57 } 58 if x := bytes.IndexByte(b, 'W'); x > -1 && x+2 < len(b) { 59 // WSL 60 if (b[x+1] == 'S' || b[x+1] == 's') && (b[x+2] == 'L' || b[x+2] == 'l') { 61 return true 62 } 63 } 64 } 65 // PROOT 66 var n string 67 for _, v := range data.ReadSplit(crypt.Get(34), "\n") { // /proc/self/status 68 if len(v) == 0 || (v[0] != 'T' && v[0] != 't') { 69 continue 70 } 71 // TracerPid 72 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') { 73 continue 74 } 75 x := strings.IndexByte(v, ':') 76 if x < 8 { 77 continue 78 } 79 n = strings.TrimSpace(v[x+1:]) 80 break 81 } 82 if len(n) > 0 { 83 p, _ := data.ReadFile( 84 crypt.Get(11) + n + // /proc/ 85 crypt.Get(55), // /comm 86 ) 87 if len(p) > 0 { 88 // proot 89 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') { 90 return true 91 } 92 } 93 } 94 if os.Getpid() == 1 { 95 if k, ok := os.LookupEnv(crypt.Get(56)); ok && len(k) > 0 { // CONTAINER 96 return true 97 } 98 } 99 if b, _ := data.ReadFile(crypt.Get(57)); len(b) > 0 { // /proc/1/environ 100 for s, e, n := 0, 0, 0; e < len(b); e++ { 101 if b[e] != 0 { 102 continue 103 } 104 if e-s > 9 { 105 // CONTAINER= 106 if b[s] == 'C' && b[s+1] == 'O' && b[s+2] == 'N' && b[s+7] == 'N' && b[s+9] == 'R' && b[s+10] == '=' { 107 return true 108 } 109 } 110 s, n = e+1, n+1 111 } 112 } 113 // User Mode Linux 114 for _, v := range data.ReadSplit(crypt.Get(58), "\n") { // /proc/cpuinfo 115 if len(v) == 0 || (v[0] != 'V' && v[0] != 'v') { 116 continue 117 } 118 // vendor_id 119 if (v[1] != 'E' && v[1] != 'e') || (v[3] != 'D' && v[3] != 'd') || v[6] != '_' || (v[7] != 'I' && v[7] != 'i') { 120 continue 121 } 122 x := strings.IndexByte(v, ':') 123 if x < 8 { 124 continue 125 } 126 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') { 127 return true 128 } 129 } 130 // Check DMI 131 return checkVendorFile(crypt.Get(59)) || // /sys/class/dmi/id/sys_vendor 132 checkVendorFile(crypt.Get(60)) || // /sys/class/dmi/id/board_vendor 133 checkVendorFile(crypt.Get(61)) || // /sys/class/dmi/id/bios_vendor 134 checkVendorFile(crypt.Get(62)) // /sys/class/dmi/id/product_version 135 } 136 func checkVendorFile(s string) bool { 137 if b, _ := data.ReadFile(s); len(b) > 0 { 138 return isKnownVendor(bytes.TrimSpace(b)) 139 } 140 return false 141 }