3
3
package vmdetect
4
4
5
5
import (
6
- "bufio"
7
6
"bytes"
8
7
"github.com/klauspost/cpuid"
9
8
"io/ioutil"
@@ -12,7 +11,7 @@ import (
12
11
)
13
12
14
13
/*
15
- Checks if the DMI table contains vendor strings of known VMs.
14
+ Checks if the DMI table contains vendor strings of known VMs.
16
15
*/
17
16
func checkDMITable () bool {
18
17
@@ -58,15 +57,14 @@ func checkDMITable() bool {
58
57
return true
59
58
}
60
59
}
61
-
62
60
}
63
61
64
62
return false
65
63
}
66
64
67
65
/*
68
- Checks printk messages to see if Linux detected an hypervisor.
69
- https://github.com/torvalds/linux/blob/31cc088a4f5d83481c6f5041bd6eb06115b974af/arch/x86/kernel/cpu/hypervisor.c#L79
66
+ Checks printk messages to see if Linux detected an hypervisor.
67
+ https://github.com/torvalds/linux/blob/31cc088a4f5d83481c6f5041bd6eb06115b974af/arch/x86/kernel/cpu/hypervisor.c#L79
70
68
*/
71
69
func checkKernelRingBuffer () bool {
72
70
@@ -85,42 +83,68 @@ func checkKernelRingBuffer() bool {
85
83
return false
86
84
}
87
85
88
- reader := bufio .NewReader (file )
86
+ return DoesFileContain (file , "Hypervisor detected" )
87
+ }
89
88
90
- for {
91
- line , _ , err := reader .ReadLine ()
89
+ /*
90
+ Checks if UML is being used
91
+ https://en.wikipedia.org/wiki/User-mode_Linux
92
+ */
93
+ func checkUML () bool {
92
94
93
- if err != nil {
94
- if ! os .IsTimeout (err ) {
95
- PrintError (err )
96
- }
95
+ file , err := os .Open ("/proc/cpuinfo" )
97
96
98
- return false
99
- }
97
+ if err != nil {
98
+ PrintError (err )
99
+ return false
100
+ }
100
101
101
- // Lowercase comparison to prevent false negatives
102
- if bytes .Contains (bytes .ToLower (line ), []byte ("hypervisor detected" )) {
103
- return true
104
- }
102
+ defer file .Close ()
103
+
104
+ return DoesFileContain (file , "User Mode Linux" )
105
+ }
106
+
107
+ /*
108
+ Some GNU/Linux distributions expose /proc/sysinfo containing potential VM info
109
+ https://www.ibm.com/support/knowledgecenter/en/linuxonibm/com.ibm.linux.z.lhdd/lhdd_t_sysinfo.html
110
+ */
111
+ func checkSysInfo () bool {
112
+ file , err := os .Open ("/proc/sysinfo" )
113
+
114
+ if err != nil {
115
+ PrintError (err )
116
+ return false
105
117
}
118
+
119
+ defer file .Close ()
120
+
121
+ return DoesFileContain (file , "VM00" )
106
122
}
107
123
108
124
/*
109
- Public function returning true if a VM is detected.
110
- If so, a non-empty string is also returned to tell how it was detected.
125
+ Public function returning true if a VM is detected.
126
+ If so, a non-empty string is also returned to tell how it was detected.
111
127
*/
112
128
func IsRunningInVirtualMachine () (bool , string ) {
113
129
114
130
if cpuid .CPU .VM () {
115
- return true , "CPU Vendor"
131
+ return true , "CPU Vendor (assembly instructions)"
132
+ }
133
+
134
+ if checkUML () {
135
+ return true , "CPU Vendor (/proc/cpuinfo)"
136
+ }
137
+
138
+ if checkSysInfo () {
139
+ return true , "System Information (/proc/sysinfo)"
116
140
}
117
141
118
142
if checkDMITable () {
119
- return true , "DMI Table"
143
+ return true , "DMI Table (/sys/class/dmi/id/*) "
120
144
}
121
145
122
146
if checkKernelRingBuffer () {
123
- return true , "Kernel Ring Buffer"
147
+ return true , "Kernel Ring Buffer (/dev/kmsg) "
124
148
}
125
149
126
150
return false , "nothing"
0 commit comments