aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/uprobes.c
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2015-02-12 14:18:51 -0500
committerIngo Molnar <mingo@kernel.org>2015-02-18 14:55:51 -0500
commit67fc809217dc7fd793211585b2a8d7b61715d06b (patch)
tree707a5ec5175e2e8c83cd04633b2323a7b9ad089d /arch/x86/kernel/uprobes.c
parent097f4e5e839359021c8f0ea273655031e6ed04ff (diff)
uprobes/x86: Fix 1-byte opcode tables
This change fixes 1-byte opcode tables so that only insns for which we have real reasons to disallow probing are marked with unset bits. To that end: Set bits for all prefix bytes. Their setting is ignored anyway - we check the bitmap against OPCODE1(insn), not against first byte. Keeping them set to 0 only confuses code reader with "why we don't support that opcode" question. Thus: enable bytes c4,c5 in 64-bit mode (VEX prefixes). Byte 62 (EVEX prefix) is not yet enabled since insn decoder does not support that yet. For 32-bit mode, enable probing of opcodes 63 (arpl) and d6 (salc). They don't require any special handling. For 64-bit mode, disable 9a and ea - these undefined opcodes were mistakenly left enabled. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Jim Keniston <jkenisto@us.ibm.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Link: http://lkml.kernel.org/r/1423768732-32194-2-git-send-email-dvlasenk@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/kernel/uprobes.c')
-rw-r--r--arch/x86/kernel/uprobes.c66
1 files changed, 18 insertions, 48 deletions
diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 54e36248e9c0..aa1da96d09ff 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -67,18 +67,6 @@
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 * 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: 70 * Opcodes we'll probably never support:
83 * 6c-6f - ins,outs. SEGVs if used in userspace 71 * 6c-6f - ins,outs. SEGVs if used in userspace
84 * e4-e7 - in,out imm. SEGVs if used in userspace 72 * e4-e7 - in,out imm. SEGVs if used in userspace
@@ -105,31 +93,27 @@
105 * Not supported since kernel's handling of userspace single-stepping 93 * Not supported since kernel's handling of userspace single-stepping
106 * (TF flag) is fragile. 94 * (TF flag) is fragile.
107 * cf - iret. Normally not used in userspace. Doesn't SEGV unless arguments are bad 95 * 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
112 */ 96 */
113#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) 97#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
114static volatile u32 good_insns_32[256 / 32] = { 98static volatile u32 good_insns_32[256 / 32] = {
115 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 99 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
116 /* ---------------------------------------------- */ 100 /* ---------------------------------------------- */
117 W(0x00, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) | /* 00 */ 101 W(0x00, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1) | /* 00 */
118 W(0x10, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) , /* 10 */ 102 W(0x10, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) , /* 10 */
119 W(0x20, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1) | /* 20 */ 103 W(0x20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 20 */
120 W(0x30, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1) , /* 30 */ 104 W(0x30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 30 */
121 W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */ 105 W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */
122 W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */ 106 W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
123 W(0x60, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */ 107 W(0x60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */
124 W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */ 108 W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */
125 W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */ 109 W(0x80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
126 W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */ 110 W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */
127 W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */ 111 W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */
128 W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */ 112 W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
129 W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */ 113 W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */
130 W(0xd0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */ 114 W(0xd0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
131 W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */ 115 W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */
132 W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1) /* f0 */ 116 W(0xf0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1) /* f0 */
133 /* ---------------------------------------------- */ 117 /* ---------------------------------------------- */
134 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 118 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
135}; 119};
@@ -139,19 +123,6 @@ static volatile u32 good_insns_32[256 / 32] = {
139 123
140/* Good-instruction tables for 64-bit apps. 124/* Good-instruction tables for 64-bit apps.
141 * 125 *
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: 126 * Genuinely invalid opcodes:
156 * 06,07 - formerly push/pop es 127 * 06,07 - formerly push/pop es
157 * 0e - formerly push cs 128 * 0e - formerly push cs
@@ -159,14 +130,13 @@ static volatile u32 good_insns_32[256 / 32] = {
159 * 1e,1f - formerly push/pop ds 130 * 1e,1f - formerly push/pop ds
160 * 27,2f,37,3f - formerly daa/das/aaa/aas 131 * 27,2f,37,3f - formerly daa/das/aaa/aas
161 * 60,61 - formerly pusha/popa 132 * 60,61 - formerly pusha/popa
162 * 62 - formerly bound. EVEX prefix for AVX512 133 * 62 - formerly bound. EVEX prefix for AVX512 (not yet supported)
163 * 82 - formerly redundant encoding of Group1 134 * 82 - formerly redundant encoding of Group1
164 * 9a - formerly call seg:ofs (marked as "supported"???) 135 * 9a - formerly call seg:ofs
165 * c4,c5 - formerly les/lds. VEX prefixes for AVX
166 * ce - formerly into 136 * ce - formerly into
167 * d4,d5 - formerly aam/aad 137 * d4,d5 - formerly aam/aad
168 * d6 - formerly undocumented salc 138 * d6 - formerly undocumented salc
169 * ea - formerly jmp seg:ofs (marked as "supported"???) 139 * ea - formerly jmp seg:ofs
170 * 140 *
171 * Opcodes we'll probably never support: 141 * Opcodes we'll probably never support:
172 * 6c-6f - ins,outs. SEGVs if used in userspace 142 * 6c-6f - ins,outs. SEGVs if used in userspace
@@ -190,22 +160,22 @@ static volatile u32 good_insns_32[256 / 32] = {
190static volatile u32 good_insns_64[256 / 32] = { 160static volatile u32 good_insns_64[256 / 32] = {
191 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 161 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
192 /* ---------------------------------------------- */ 162 /* ---------------------------------------------- */
193 W(0x00, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 00 */ 163 W(0x00, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1) | /* 00 */
194 W(0x10, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 10 */ 164 W(0x10, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 10 */
195 W(0x20, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) | /* 20 */ 165 W(0x20, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) | /* 20 */
196 W(0x30, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0) , /* 30 */ 166 W(0x30, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0) , /* 30 */
197 W(0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) | /* 40 */ 167 W(0x40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 40 */
198 W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */ 168 W(0x50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 50 */
199 W(0x60, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */ 169 W(0x60, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* 60 */
200 W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */ 170 W(0x70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 70 */
201 W(0x80, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */ 171 W(0x80, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* 80 */
202 W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* 90 */ 172 W(0x90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1) , /* 90 */
203 W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */ 173 W(0xa0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) | /* a0 */
204 W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */ 174 W(0xb0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* b0 */
205 W(0xc0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */ 175 W(0xc0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0) | /* c0 */
206 W(0xd0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */ 176 W(0xd0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1) , /* d0 */
207 W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0) | /* e0 */ 177 W(0xe0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0) | /* e0 */
208 W(0xf0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1) /* f0 */ 178 W(0xf0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1) /* f0 */
209 /* ---------------------------------------------- */ 179 /* ---------------------------------------------- */
210 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ 180 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
211}; 181};