hypervisor kernel integrity enforcement via EPT/NPT write interception for Xen/HVM guests
1#ifndef XEN_TURNSTILE_H
2#define XEN_TURNSTILE_H
3
4#ifdef __XEN__
5#include <xen/types.h>
6#else
7#include <stdint.h>
8#endif
9
10#define TURNSTILE_OP_SET_POLICY 0
11#define TURNSTILE_OP_PROTECT_RANGE 1
12#define TURNSTILE_OP_UNPROTECT_RANGE 2
13#define TURNSTILE_OP_REQUEST_WRITE 3
14#define TURNSTILE_OP_GET_VIOLATIONS 4
15#define TURNSTILE_OP_GET_STATS 5
16#define TURNSTILE_OP_UPLOAD_METADATA 6
17
18#define TURNSTILE_POLICY_DISABLED 0
19#define TURNSTILE_POLICY_AUDIT 1
20#define TURNSTILE_POLICY_ENFORCE 2
21
22#define TURNSTILE_MAX_RANGES 256
23#define TURNSTILE_RING_SIZE 4096
24#define TURNSTILE_MAX_FUNC_ENTRIES 65536
25#define TURNSTILE_MAX_JUMP_ENTRIES 32768
26
27#define TURNSTILE_IMPLICIT_DENIED 0
28#define TURNSTILE_IMPLICIT_FTRACE 1
29#define TURNSTILE_IMPLICIT_STATIC 2
30
31struct turnstile_violation {
32 uint64_t timestamp;
33 uint64_t gpa;
34 uint64_t rip;
35 uint64_t cr3;
36 uint32_t access_flags;
37 uint32_t response;
38 uint8_t insn_bytes[16];
39 uint32_t seq;
40 uint32_t _pad;
41};
42
43struct turnstile_stats {
44 uint64_t violations_total;
45 uint64_t violations_blocked;
46 uint64_t violations_allowed;
47 uint64_t implicit_ftrace;
48 uint64_t implicit_static_key;
49 uint64_t explicit_write_grants;
50 uint64_t ring_overflows;
51};
52
53struct turnstile_op_set_policy {
54 uint32_t policy;
55 uint32_t _pad;
56};
57
58struct turnstile_op_protect_range {
59 uint64_t gpa_start;
60 uint64_t length;
61};
62
63struct turnstile_op_request_write {
64 uint64_t gpa_start;
65 uint64_t length;
66 uint32_t timeout_ms;
67 uint32_t _pad;
68};
69
70struct turnstile_op_get_violations {
71 uint64_t buffer_ptr;
72 uint32_t max_entries;
73 uint32_t entries_returned;
74 uint32_t overflow_count;
75 uint32_t _pad;
76};
77
78struct turnstile_op_upload_metadata {
79 uint64_t buffer_ptr;
80 uint32_t metadata_type;
81 uint32_t count;
82};
83
84#define TURNSTILE_META_FUNC_ENTRIES 0
85#define TURNSTILE_META_JUMP_ENTRIES 1
86
87#ifdef __XEN__
88#include <xen/sched.h>
89#include <xen/spinlock.h>
90#include <xen/time.h>
91#include <asm/p2m.h>
92
93struct turnstile_range {
94 uint64_t gpa_start;
95 uint64_t gpa_end;
96 p2m_type_t original_type;
97 bool active;
98};
99
100struct turnstile_write_grant {
101 uint64_t gpa_start;
102 uint64_t gpa_end;
103 s_time_t expiry;
104 bool active;
105};
106
107struct turnstile_domain_state {
108 rwlock_t lock;
109 uint32_t policy;
110
111 struct turnstile_range ranges[TURNSTILE_MAX_RANGES];
112 unsigned int num_ranges;
113
114 struct turnstile_violation ring[TURNSTILE_RING_SIZE];
115 uint32_t ring_head;
116 uint32_t ring_tail;
117 uint32_t ring_seq;
118 uint32_t overflow_count;
119
120 uint64_t *func_entries;
121 unsigned int num_func_entries;
122
123 uint64_t *jump_entries;
124 unsigned int num_jump_entries;
125
126 struct turnstile_write_grant write_grant;
127 struct turnstile_stats stats;
128};
129
130int turnstile_domain_init(struct domain *d);
131void turnstile_domain_destroy(struct domain *d);
132long do_turnstile_op(unsigned int op, domid_t domid, XEN_GUEST_HANDLE_PARAM(void) arg);
133int turnstile_check_violation(struct domain *d, uint64_t gpa, uint64_t rip,
134 uint64_t cr3, uint32_t access_flags,
135 const uint8_t *insn_bytes);
136#endif
137
138#endif