33package vmdetect
44
55import (
6- "bufio"
76 "bytes"
87 "github.com/klauspost/cpuid"
98 "io/ioutil"
@@ -12,7 +11,7 @@ import (
1211)
1312
1413/*
15- Checks if the DMI table contains vendor strings of known VMs.
14+ Checks if the DMI table contains vendor strings of known VMs.
1615*/
1716func checkDMITable () bool {
1817
@@ -58,15 +57,14 @@ func checkDMITable() bool {
5857 return true
5958 }
6059 }
61-
6260 }
6361
6462 return false
6563}
6664
6765/*
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
7068*/
7169func checkKernelRingBuffer () bool {
7270
@@ -85,42 +83,68 @@ func checkKernelRingBuffer() bool {
8583 return false
8684 }
8785
88- reader := bufio .NewReader (file )
86+ return DoesFileContain (file , "Hypervisor detected" )
87+ }
8988
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 {
9294
93- if err != nil {
94- if ! os .IsTimeout (err ) {
95- PrintError (err )
96- }
95+ file , err := os .Open ("/proc/cpuinfo" )
9796
98- return false
99- }
97+ if err != nil {
98+ PrintError (err )
99+ return false
100+ }
100101
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
105117 }
118+
119+ defer file .Close ()
120+
121+ return DoesFileContain (file , "VM00" )
106122}
107123
108124/*
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.
111127*/
112128func IsRunningInVirtualMachine () (bool , string ) {
113129
114130 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)"
116140 }
117141
118142 if checkDMITable () {
119- return true , "DMI Table"
143+ return true , "DMI Table (/sys/class/dmi/id/*) "
120144 }
121145
122146 if checkKernelRingBuffer () {
123- return true , "Kernel Ring Buffer"
147+ return true , "Kernel Ring Buffer (/dev/kmsg) "
124148 }
125149
126150 return false , "nothing"
0 commit comments