diff options
-rw-r--r-- | arch/x86/kernel/uprobes.c | 153 |
1 files changed, 134 insertions, 19 deletions
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 8b96a947021f..54e36248e9c0 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c | |||
@@ -66,6 +66,49 @@ | |||
66 | * Good-instruction tables for 32-bit apps. This is non-const and volatile | 66 | * Good-instruction tables for 32-bit apps. This is non-const and volatile |
67 | * to keep gcc from statically optimizing it out, as variable_test_bit makes | 67 | * to keep gcc from statically optimizing it out, as variable_test_bit makes |
68 | * some versions of gcc to think only *(unsigned long*) is used. | 68 | * some versions of gcc to think only *(unsigned long*) is used. |
69 | * | ||
70 | * Prefixes. Most marked as "bad", but it doesn't matter, since insn decoder | ||
71 | * won't report *prefixes* as OPCODE1(insn). | ||
72 | * 0f - 2-byte opcode prefix | ||
73 | * 26,2e,36,3e - es:/cs:/ss:/ds: | ||
74 | * 64 - fs: (marked as "good", why?) | ||
75 | * 65 - gs: (marked as "good", why?) | ||
76 | * 66 - operand-size prefix | ||
77 | * 67 - address-size prefix | ||
78 | * f0 - lock prefix | ||
79 | * f2 - repnz (marked as "good", why?) | ||
80 | * f3 - rep/repz (marked as "good", why?) | ||
81 | * | ||
82 | * Opcodes we'll probably never support: | ||
83 | * 6c-6f - ins,outs. SEGVs if used in userspace | ||
84 | * e4-e7 - in,out imm. SEGVs if used in userspace | ||
85 | * ec-ef - in,out acc. SEGVs if used in userspace | ||
86 | * cc - int3. SIGTRAP if used in userspace | ||
87 | * ce - into. Not used in userspace - no kernel support to make it useful. SEGVs | ||
88 | * (why we support bound (62) then? it's similar, and similarly unused...) | ||
89 | * f1 - int1. SIGTRAP if used in userspace | ||
90 | * f4 - hlt. SEGVs if used in userspace | ||
91 | * fa - cli. SEGVs if used in userspace | ||
92 | * fb - sti. SEGVs if used in userspace | ||
93 | * | ||
94 | * Opcodes which need some work to be supported: | ||
95 | * 07,17,1f - pop es/ss/ds | ||
96 | * Normally not used in userspace, but would execute if used. | ||
97 | * Can cause GP or stack exception if tries to load wrong segment descriptor. | ||
98 | * We hesitate to run them under single step since kernel's handling | ||
99 | * of userspace single-stepping (TF flag) is fragile. | ||
100 | * We can easily refuse to support push es/cs/ss/ds (06/0e/16/1e) | ||
101 | * on the same grounds that they are never used. | ||
102 | * cd - int N. | ||
103 | * Used by userspace for "int 80" syscall entry. (Other "int N" | ||
104 | * cause GP -> SEGV since their IDT gates don't allow calls from CPL 3). | ||
105 | * Not supported since kernel's handling of userspace single-stepping | ||
106 | * (TF flag) is fragile. | ||
107 | * cf - iret. Normally not used in userspace. Doesn't SEGV unless arguments are bad | ||
108 | * | ||
109 | * Opcodes which can be enabled right away: | ||
110 | * 63 - arpl. This insn has no unusual exceptions (it's basically an arith op). | ||
111 | * d6 - salc. Undocumented "sign-extend carry flag to AL" insn | ||
69 | */ | 112 | */ |
70 | #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) | 113 | #if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) |
71 | static volatile u32 good_insns_32[256 / 32] = { | 114 | static volatile u32 good_insns_32[256 / 32] = { |
@@ -94,7 +137,55 @@ static volatile u32 good_insns_32[256 / 32] = { | |||
94 | #define good_insns_32 NULL | 137 | #define good_insns_32 NULL |
95 | #endif | 138 | #endif |
96 | 139 | ||
97 | /* Good-instruction tables for 64-bit apps */ | 140 | /* Good-instruction tables for 64-bit apps. |
141 | * | ||
142 | * Prefixes. Most marked as "bad", but it doesn't matter, since insn decoder | ||
143 | * won't report *prefixes* as OPCODE1(insn). | ||
144 | * 0f - 2-byte opcode prefix | ||
145 | * 26,2e,36,3e - es:/cs:/ss:/ds: | ||
146 | * 40-4f - rex prefixes | ||
147 | * 64 - fs: (marked as "good", why?) | ||
148 | * 65 - gs: (marked as "good", why?) | ||
149 | * 66 - operand-size prefix | ||
150 | * 67 - address-size prefix | ||
151 | * f0 - lock prefix | ||
152 | * f2 - repnz (marked as "good", why?) | ||
153 | * f3 - rep/repz (marked as "good", why?) | ||
154 | * | ||
155 | * Genuinely invalid opcodes: | ||
156 | * 06,07 - formerly push/pop es | ||
157 | * 0e - formerly push cs | ||
158 | * 16,17 - formerly push/pop ss | ||
159 | * 1e,1f - formerly push/pop ds | ||
160 | * 27,2f,37,3f - formerly daa/das/aaa/aas | ||
161 | * 60,61 - formerly pusha/popa | ||
162 | * 62 - formerly bound. EVEX prefix for AVX512 | ||
163 | * 82 - formerly redundant encoding of Group1 | ||
164 | * 9a - formerly call seg:ofs (marked as "supported"???) | ||
165 | * c4,c5 - formerly les/lds. VEX prefixes for AVX | ||
166 | * ce - formerly into | ||
167 | * d4,d5 - formerly aam/aad | ||
168 | * d6 - formerly undocumented salc | ||
169 | * ea - formerly jmp seg:ofs (marked as "supported"???) | ||
170 | * | ||
171 | * Opcodes we'll probably never support: | ||
172 | * 6c-6f - ins,outs. SEGVs if used in userspace | ||
173 | * e4-e7 - in,out imm. SEGVs if used in userspace | ||
174 | * ec-ef - in,out acc. SEGVs if used in userspace | ||
175 | * cc - int3. SIGTRAP if used in userspace | ||
176 | * f1 - int1. SIGTRAP if used in userspace | ||
177 | * f4 - hlt. SEGVs if used in userspace | ||
178 | * fa - cli. SEGVs if used in userspace | ||
179 | * fb - sti. SEGVs if used in userspace | ||
180 | * | ||
181 | * Opcodes which need some work to be supported: | ||
182 | * cd - int N. | ||
183 | * Used by userspace for "int 80" syscall entry. (Other "int N" | ||
184 | * cause GP -> SEGV since their IDT gates don't allow calls from CPL 3). | ||
185 | * Not supported since kernel's handling of userspace single-stepping | ||
186 | * (TF flag) is fragile. | ||
187 | * cf - iret. Normally not used in userspace. Doesn't SEGV unless arguments are bad | ||
188 | */ | ||
98 | #if defined(CONFIG_X86_64) | 189 | #if defined(CONFIG_X86_64) |
99 | static volatile u32 good_insns_64[256 / 32] = { | 190 | static volatile u32 good_insns_64[256 / 32] = { |
100 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | 191 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
@@ -122,7 +213,48 @@ static volatile u32 good_insns_64[256 / 32] = { | |||
122 | #define good_insns_64 NULL | 213 | #define good_insns_64 NULL |
123 | #endif | 214 | #endif |
124 | 215 | ||
125 | /* Using this for both 64-bit and 32-bit apps */ | 216 | /* Using this for both 64-bit and 32-bit apps. |
217 | * Opcodes we don't support: | ||
218 | * 0f 00 - SLDT/STR/LLDT/LTR/VERR/VERW/-/- group. System insns | ||
219 | * 0f 01 - SGDT/SIDT/LGDT/LIDT/SMSW/-/LMSW/INVLPG group. | ||
220 | * Also encodes tons of other system insns if mod=11. | ||
221 | * Some are in fact non-system: xend, xtest, rdtscp, maybe more | ||
222 | * 0f 02 - lar (why? should be safe, it throws no exceptipons) | ||
223 | * 0f 03 - lsl (why? should be safe, it throws no exceptipons) | ||
224 | * 0f 04 - undefined | ||
225 | * 0f 05 - syscall | ||
226 | * 0f 06 - clts (CPL0 insn) | ||
227 | * 0f 07 - sysret | ||
228 | * 0f 08 - invd (CPL0 insn) | ||
229 | * 0f 09 - wbinvd (CPL0 insn) | ||
230 | * 0f 0a - undefined | ||
231 | * 0f 0b - ud2 | ||
232 | * 0f 0c - undefined | ||
233 | * 0f 0d - prefetchFOO (amd prefetch insns) | ||
234 | * 0f 18 - prefetchBAR (intel prefetch insns) | ||
235 | * 0f 24 - mov from test regs (perhaps entire 20-27 area can be disabled (special reg ops)) | ||
236 | * 0f 25 - undefined | ||
237 | * 0f 26 - mov to test regs | ||
238 | * 0f 27 - undefined | ||
239 | * 0f 30 - wrmsr (CPL0 insn) | ||
240 | * 0f 34 - sysenter | ||
241 | * 0f 35 - sysexit | ||
242 | * 0f 36 - undefined | ||
243 | * 0f 37 - getsec | ||
244 | * 0f 38-3f - 3-byte opcodes (why?? all look safe) | ||
245 | * 0f 78 - vmread | ||
246 | * 0f 79 - vmwrite | ||
247 | * 0f 7a - undefined | ||
248 | * 0f 7b - undefined | ||
249 | * 0f 7c - undefined | ||
250 | * 0f 7d - undefined | ||
251 | * 0f a6 - undefined | ||
252 | * 0f a7 - undefined | ||
253 | * 0f b8 - popcnt (why?? it's an ordinary ALU op) | ||
254 | * 0f d0 - undefined | ||
255 | * 0f f0 - lddqu (why?? it's an ordinary vector load op) | ||
256 | * 0f ff - undefined | ||
257 | */ | ||
126 | static volatile u32 good_2byte_insns[256 / 32] = { | 258 | static volatile u32 good_2byte_insns[256 / 32] = { |
127 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | 259 | /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ |
128 | /* ---------------------------------------------- */ | 260 | /* ---------------------------------------------- */ |
@@ -148,23 +280,6 @@ static volatile u32 good_2byte_insns[256 / 32] = { | |||
148 | #undef W | 280 | #undef W |
149 | 281 | ||
150 | /* | 282 | /* |
151 | * opcodes we'll probably never support: | ||
152 | * | ||
153 | * 6c-6d, e4-e5, ec-ed - in | ||
154 | * 6e-6f, e6-e7, ee-ef - out | ||
155 | * cc, cd - int3, int | ||
156 | * cf - iret | ||
157 | * d6 - illegal instruction | ||
158 | * f1 - int1/icebp | ||
159 | * f4 - hlt | ||
160 | * fa, fb - cli, sti | ||
161 | * 0f - lar, lsl, syscall, clts, sysret, sysenter, sysexit, invd, wbinvd, ud2 | ||
162 | * | ||
163 | * invalid opcodes in 64-bit mode: | ||
164 | * | ||
165 | * 06, 0e, 16, 1e, 27, 2f, 37, 3f, 60-62, 82, c4-c5, d4-d5 | ||
166 | * 63 - we support this opcode in x86_64 but not in i386. | ||
167 | * | ||
168 | * opcodes we may need to refine support for: | 283 | * opcodes we may need to refine support for: |
169 | * | 284 | * |
170 | * 0f - 2-byte instructions: For many of these instructions, the validity | 285 | * 0f - 2-byte instructions: For many of these instructions, the validity |