Revert "Upgrade NodeJS binary to v16.13.0"
[platform/framework/web/chromium-efl.git] / third_party / nyx-packer / nyx.h
1 /*
2 This file is part of NYX.
3
4 Copyright (c) 2021 Sergej Schumilo
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11 The above copyright notice and this permission notice shall be included in all
12 copies or substantial portions of the Software.
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 SOFTWARE.
20 */
21 #ifndef KAFL_USER_H
22 #define KAFL_USER_H
23
24 #include <stdarg.h>
25 #include <stddef.h>
26 #include <stdio.h>
27 #include <stdarg.h>
28 #include <string.h>
29 #ifndef __MINGW64__
30 #include <sys/mman.h>
31 #endif
32
33 #ifdef __MINGW64__
34 #ifndef uint64_t
35 #define uint64_t UINT64
36 #endif
37 #ifndef int32_t
38 #define int32_t INT32
39 #endif
40 #ifndef uint8_t
41 #define uint8_t UINT8
42 #endif
43 #else 
44 #include <stdint.h>
45 #endif
46
47 #define HYPERCALL_KAFL_RAX_ID                           0x01f
48 #define HYPERCALL_KAFL_ACQUIRE                          0
49 #define HYPERCALL_KAFL_GET_PAYLOAD                      1
50
51 /* deprecated */
52 #define HYPERCALL_KAFL_GET_PROGRAM                      2
53 /* deprecated */
54 #define HYPERCALL_KAFL_GET_ARGV                         3
55
56 #define HYPERCALL_KAFL_RELEASE                          4
57 #define HYPERCALL_KAFL_SUBMIT_CR3                       5
58 #define HYPERCALL_KAFL_SUBMIT_PANIC                     6
59
60 /* deprecated */
61 #define HYPERCALL_KAFL_SUBMIT_KASAN                     7
62
63 #define HYPERCALL_KAFL_PANIC                            8
64
65 /* deprecated */
66 #define HYPERCALL_KAFL_KASAN                            9
67 #define HYPERCALL_KAFL_LOCK                                     10
68
69 /* deprecated */
70 #define HYPERCALL_KAFL_INFO                                     11
71
72 #define HYPERCALL_KAFL_NEXT_PAYLOAD                     12
73 #define HYPERCALL_KAFL_PRINTF                           13
74
75 /* deprecated */
76 #define HYPERCALL_KAFL_PRINTK_ADDR                      14
77 /* deprecated */
78 #define HYPERCALL_KAFL_PRINTK                           15
79
80 /* user space only hypercalls */
81 #define HYPERCALL_KAFL_USER_RANGE_ADVISE        16
82 #define HYPERCALL_KAFL_USER_SUBMIT_MODE         17
83 #define HYPERCALL_KAFL_USER_FAST_ACQUIRE        18
84 /* 19 is already used for exit reason KVM_EXIT_KAFL_TOPA_MAIN_FULL */
85 #define HYPERCALL_KAFL_USER_ABORT                       20
86 #define HYPERCALL_KAFL_RANGE_SUBMIT             29
87 #define HYPERCALL_KAFL_REQ_STREAM_DATA          30
88 #define HYPERCALL_KAFL_PANIC_EXTENDED           32
89
90 #define HYPERCALL_KAFL_CREATE_TMP_SNAPSHOT 33
91 #define HYPERCALL_KAFL_DEBUG_TMP_SNAPSHOT 34 /* hypercall for debugging / development purposes */
92
93 #define HYPERCALL_KAFL_GET_HOST_CONFIG 35
94 #define HYPERCALL_KAFL_SET_AGENT_CONFIG 36
95
96 #define HYPERCALL_KAFL_DUMP_FILE 37
97
98 #define HYPERCALL_KAFL_REQ_STREAM_DATA_BULK 38
99 #define HYPERCALL_KAFL_PERSIST_PAGE_PAST_SNAPSHOT 39
100
101 /* hypertrash only hypercalls */
102 #define HYPERTRASH_HYPERCALL_MASK                       0xAA000000
103
104 #define HYPERCALL_KAFL_NESTED_PREPARE           (0 | HYPERTRASH_HYPERCALL_MASK)
105 #define HYPERCALL_KAFL_NESTED_CONFIG            (1 | HYPERTRASH_HYPERCALL_MASK)
106 #define HYPERCALL_KAFL_NESTED_ACQUIRE           (2 | HYPERTRASH_HYPERCALL_MASK)
107 #define HYPERCALL_KAFL_NESTED_RELEASE           (3 | HYPERTRASH_HYPERCALL_MASK)
108 #define HYPERCALL_KAFL_NESTED_HPRINTF           (4 | HYPERTRASH_HYPERCALL_MASK)gre
109
110 #define HPRINTF_MAX_SIZE                                        0x1000                                  /* up to 4KB hprintf strings */
111
112 /* specific defines to enable support for NYX hypercalls on unmodified KVM builds */
113 /* PIO port number used by VMWare backdoor */
114 #define VMWARE_PORT   0x5658
115 /* slightly changed RAX_ID to avoid vmware backdoor collisions */
116 #define HYPERCALL_KAFL_RAX_ID_VMWARE                            0x8080801f
117
118 typedef struct{
119         int32_t size;
120         uint8_t data[];
121 } kAFL_payload;
122
123 typedef struct{
124         uint64_t ip[4];
125         uint64_t size[4];
126         uint8_t enabled[4];
127 } kAFL_ranges; 
128
129 #define KAFL_MODE_64    0
130 #define KAFL_MODE_32    1
131 #define KAFL_MODE_16    2
132
133 #if defined(__i386__)
134 #define KAFL_HYPERCALL_NO_PT(_ebx, _ecx) ({ \
135         uint32_t _eax = HYPERCALL_KAFL_RAX_ID_VMWARE; \
136         do{ \
137         asm volatile( \
138                 "outl %%eax, %%dx;" \
139         : "+a" (_eax) \
140         : "b" (_ebx), "c" (_ecx), "d" (VMWARE_PORT) \
141         : "cc", "memory" \
142         ); \
143         } while(0); \
144         _eax; \
145 })
146
147 #define KAFL_HYPERCALL_PT(_ebx, _ecx) ({ \
148         uint32_t _eax = HYPERCALL_KAFL_RAX_ID; \
149         do{ \
150         asm volatile( \
151                 "vmcall;" \
152         : "+a" (_eax) \
153         : "b" (_ebx), "c" (_ecx) \
154         : "cc", "memory" \
155         ); \
156         } while(0); \
157         _eax; \
158 })
159
160 #else
161
162 #define KAFL_HYPERCALL_NO_PT(_rbx, _rcx) ({ \
163         uint64_t _rax = HYPERCALL_KAFL_RAX_ID_VMWARE; \
164         do{ \
165         asm volatile( \
166                 "outl %%eax, %%dx;" \
167         : "+a" (_rax) \
168         : "b" (_rbx), "c" (_rcx), "d" (VMWARE_PORT) \
169         : "cc", "memory" \
170         ); \
171         } while(0); \
172         _rax; \
173 })
174
175 #define KAFL_HYPERCALL_PT(_rbx, _rcx) ({ \
176         uint64_t _rax = HYPERCALL_KAFL_RAX_ID; \
177         do{ \
178         asm volatile( \
179                 "vmcall;" \
180         : "+a" (_rax) \
181         : "b" (_rbx), "c" (_rcx) \
182         : "cc", "memory" \
183         ); \
184         } while(0); \
185         _rax; \
186 })
187 #endif
188
189
190 #if defined(__i386__)
191 #ifdef NO_PT_NYX
192
193 #define KAFL_HYPERCALL(__rbx, __rcx) \
194         KAFL_HYPERCALL_NO_PT(_rbx, _rcx); \
195 }while(0)
196
197 static inline uint32_t kAFL_hypercall(uint32_t rbx, uint32_t rcx){
198         return KAFL_HYPERCALL_NO_PT(rbx, rcx);
199 }
200 #else
201 #define KAFL_HYPERCALL(__rbx, __rcx) \
202         KAFL_HYPERCALL_PT(_rbx, _rcx); \
203 }while(0)
204
205 static inline uint32_t kAFL_hypercall(uint32_t rbx, uint32_t rcx){
206 # ifndef __NOKAFL
207         return KAFL_HYPERCALL_PT(rbx, rcx);
208 # endif
209         return 0;
210 }
211 #endif
212 #elif defined(__x86_64__)
213 #ifdef NO_PT_NYX
214
215 #define KAFL_HYPERCALL(__rbx, __rcx) \
216         KAFL_HYPERCALL_NO_PT(_rbx, _rcx); \
217 }while(0)
218
219 static inline uint64_t kAFL_hypercall(uint64_t rbx, uint64_t rcx){
220         return KAFL_HYPERCALL_NO_PT(rbx, rcx);
221 }
222 #else
223 #define KAFL_HYPERCALL(__rbx, __rcx) \
224         KAFL_HYPERCALL_PT(_rbx, _rcx); \
225 }while(0)
226
227 static inline uint64_t kAFL_hypercall(uint64_t rbx, uint64_t rcx){
228 # ifndef __NOKAFL
229         return KAFL_HYPERCALL_PT(rbx, rcx);
230 # endif
231         return 0;
232 }
233 #endif
234 #endif
235
236 //extern uint8_t* hprintf_buffer; 
237
238 static inline uint8_t alloc_hprintf_buffer(uint8_t** hprintf_buffer){
239         if(!*hprintf_buffer){
240 #ifdef __MINGW64__
241                 *hprintf_buffer = (uint8_t*)VirtualAlloc(0, HPRINTF_MAX_SIZE, MEM_COMMIT, PAGE_READWRITE);
242 #else 
243                 *hprintf_buffer = (uint8_t*)mmap((void*)NULL, HPRINTF_MAX_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
244 #endif
245                 if(!*hprintf_buffer){
246                         return 0;
247                 }
248         }
249         return 1; 
250 }
251
252 #ifdef __NOKAFL
253 int (*hprintf)(const char * format, ...) = printf;
254 #else
255 static void hprintf(const char * format, ...)  __attribute__ ((unused));
256
257 static void hprintf(const char * format, ...){
258         static uint8_t* hprintf_buffer = NULL; 
259
260         va_list args;
261         va_start(args, format);
262         if(alloc_hprintf_buffer(&hprintf_buffer)){
263                 vsnprintf((char*)hprintf_buffer, HPRINTF_MAX_SIZE, format, args);
264                 kAFL_hypercall(HYPERCALL_KAFL_PRINTF, (uintptr_t)hprintf_buffer);
265         }
266         //vprintf(format, args);
267         va_end(args);
268 }
269 #endif
270
271 static void habort(char* msg){
272         kAFL_hypercall(HYPERCALL_KAFL_USER_ABORT, (uintptr_t)msg);
273 }
274
275 #define NYX_HOST_MAGIC  0x4878794e
276 #define NYX_AGENT_MAGIC 0x4178794e
277
278 #define NYX_HOST_VERSION 2 
279 #define NYX_AGENT_VERSION 1
280
281 typedef struct host_config_s{
282   uint32_t host_magic;
283   uint32_t host_version;
284   uint32_t bitmap_size;
285   uint32_t ijon_bitmap_size;
286   uint32_t payload_buffer_size;
287   uint32_t worker_id;
288   /* more to come */
289 } __attribute__((packed)) host_config_t;
290
291 typedef struct agent_config_s{
292         uint32_t agent_magic;
293         uint32_t agent_version;
294         uint8_t agent_timeout_detection;
295         uint8_t agent_tracing;
296         uint8_t agent_ijon_tracing;
297         uint8_t agent_non_reload_mode;
298         uint64_t trace_buffer_vaddr;
299         uint64_t ijon_trace_buffer_vaddr;
300         uint32_t coverage_bitmap_size;
301         uint32_t input_buffer_size;             // TODO: remove this later
302
303         uint8_t dump_payloads; /* set by hypervisor */
304   /* more to come */
305 } __attribute__((packed)) agent_config_t;
306
307 typedef struct kafl_dump_file_s{
308   uint64_t file_name_str_ptr;
309   uint64_t data_ptr;
310   uint64_t bytes;
311   uint8_t append;
312 } __attribute__((packed)) kafl_dump_file_t;
313
314
315 enum nyx_cpu_type{
316         unkown = 0, 
317         nyx_cpu_v1,     /* Nyx CPU used by KVM-PT */
318         nyx_cpu_v2  /* Nyx CPU used by vanilla KVM + VMWare backdoor */
319 };
320
321 #define cpuid(in,a,b,c,d)\
322   asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));
323          
324 static int is_nyx_vcpu(void){
325   unsigned long eax,ebx,ecx,edx;
326   char str[8];
327   cpuid(0x80000004,eax,ebx,ecx,edx);    
328
329   for(int j=0;j<4;j++){
330     str[j] = eax >> (8*j);
331     str[j+4] = ebx >> (8*j);
332   }
333
334   return !memcmp(&str, "NYX vCPU", 8);
335 }
336
337 static int get_nyx_cpu_type(void){
338         unsigned long eax,ebx,ecx,edx;
339   char str[9];
340   cpuid(0x80000004,eax,ebx,ecx,edx);    
341
342   for(int j=0;j<4;j++){
343     str[j] = eax >> (8*j);
344     str[j+4] = ebx >> (8*j);
345   }
346
347         if(memcmp(&str, "NYX vCPU", 8) != 0){
348                 return unkown;
349         }
350
351   for(int j=0;j<4;j++){
352     str[j] = ecx >> (8*j);
353     str[j+4] = edx >> (8*j);
354   }
355
356         if(memcmp(&str, " (NO-PT)", 8) != 0){
357                 return nyx_cpu_v1;
358         }
359
360         return nyx_cpu_v2;
361
362         str[8] = 0;
363         printf("ECX: %s\n", str);
364 }
365
366 typedef struct req_data_bulk_s{
367         char file_name[256];
368         uint64_t num_addresses;
369         uint64_t addresses[479];
370 } req_data_bulk_t;
371
372 #endif