~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/kernel/kprobes-common.c

Version: ~ [ linux-5.4-rc7 ] ~ [ linux-5.3.11 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.84 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.154 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.201 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.201 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.77 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * arch/arm/kernel/kprobes-common.c
  3  *
  4  * Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
  5  *
  6  * Some contents moved here from arch/arm/include/asm/kprobes-arm.c which is
  7  * Copyright (C) 2006, 2007 Motorola Inc.
  8  *
  9  * This program is free software; you can redistribute it and/or modify
 10  * it under the terms of the GNU General Public License version 2 as
 11  * published by the Free Software Foundation.
 12  */
 13 
 14 #include <linux/kernel.h>
 15 #include <linux/kprobes.h>
 16 #include <asm/system_info.h>
 17 #include <asm/opcodes.h>
 18 
 19 #include "kprobes.h"
 20 
 21 
 22 #ifndef find_str_pc_offset
 23 
 24 /*
 25  * For STR and STM instructions, an ARM core may choose to use either
 26  * a +8 or a +12 displacement from the current instruction's address.
 27  * Whichever value is chosen for a given core, it must be the same for
 28  * both instructions and may not change.  This function measures it.
 29  */
 30 
 31 int str_pc_offset;
 32 
 33 void __init find_str_pc_offset(void)
 34 {
 35         int addr, scratch, ret;
 36 
 37         __asm__ (
 38                 "sub    %[ret], pc, #4          \n\t"
 39                 "str    pc, %[addr]             \n\t"
 40                 "ldr    %[scr], %[addr]         \n\t"
 41                 "sub    %[ret], %[scr], %[ret]  \n\t"
 42                 : [ret] "=r" (ret), [scr] "=r" (scratch), [addr] "+m" (addr));
 43 
 44         str_pc_offset = ret;
 45 }
 46 
 47 #endif /* !find_str_pc_offset */
 48 
 49 
 50 #ifndef test_load_write_pc_interworking
 51 
 52 bool load_write_pc_interworks;
 53 
 54 void __init test_load_write_pc_interworking(void)
 55 {
 56         int arch = cpu_architecture();
 57         BUG_ON(arch == CPU_ARCH_UNKNOWN);
 58         load_write_pc_interworks = arch >= CPU_ARCH_ARMv5T;
 59 }
 60 
 61 #endif /* !test_load_write_pc_interworking */
 62 
 63 
 64 #ifndef test_alu_write_pc_interworking
 65 
 66 bool alu_write_pc_interworks;
 67 
 68 void __init test_alu_write_pc_interworking(void)
 69 {
 70         int arch = cpu_architecture();
 71         BUG_ON(arch == CPU_ARCH_UNKNOWN);
 72         alu_write_pc_interworks = arch >= CPU_ARCH_ARMv7;
 73 }
 74 
 75 #endif /* !test_alu_write_pc_interworking */
 76 
 77 
 78 void __init arm_kprobe_decode_init(void)
 79 {
 80         find_str_pc_offset();
 81         test_load_write_pc_interworking();
 82         test_alu_write_pc_interworking();
 83 }
 84 
 85 
 86 static unsigned long __kprobes __check_eq(unsigned long cpsr)
 87 {
 88         return cpsr & PSR_Z_BIT;
 89 }
 90 
 91 static unsigned long __kprobes __check_ne(unsigned long cpsr)
 92 {
 93         return (~cpsr) & PSR_Z_BIT;
 94 }
 95 
 96 static unsigned long __kprobes __check_cs(unsigned long cpsr)
 97 {
 98         return cpsr & PSR_C_BIT;
 99 }
100 
101 static unsigned long __kprobes __check_cc(unsigned long cpsr)
102 {
103         return (~cpsr) & PSR_C_BIT;
104 }
105 
106 static unsigned long __kprobes __check_mi(unsigned long cpsr)
107 {
108         return cpsr & PSR_N_BIT;
109 }
110 
111 static unsigned long __kprobes __check_pl(unsigned long cpsr)
112 {
113         return (~cpsr) & PSR_N_BIT;
114 }
115 
116 static unsigned long __kprobes __check_vs(unsigned long cpsr)
117 {
118         return cpsr & PSR_V_BIT;
119 }
120 
121 static unsigned long __kprobes __check_vc(unsigned long cpsr)
122 {
123         return (~cpsr) & PSR_V_BIT;
124 }
125 
126 static unsigned long __kprobes __check_hi(unsigned long cpsr)
127 {
128         cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
129         return cpsr & PSR_C_BIT;
130 }
131 
132 static unsigned long __kprobes __check_ls(unsigned long cpsr)
133 {
134         cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */
135         return (~cpsr) & PSR_C_BIT;
136 }
137 
138 static unsigned long __kprobes __check_ge(unsigned long cpsr)
139 {
140         cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
141         return (~cpsr) & PSR_N_BIT;
142 }
143 
144 static unsigned long __kprobes __check_lt(unsigned long cpsr)
145 {
146         cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
147         return cpsr & PSR_N_BIT;
148 }
149 
150 static unsigned long __kprobes __check_gt(unsigned long cpsr)
151 {
152         unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
153         temp |= (cpsr << 1);                     /* PSR_N_BIT |= PSR_Z_BIT */
154         return (~temp) & PSR_N_BIT;
155 }
156 
157 static unsigned long __kprobes __check_le(unsigned long cpsr)
158 {
159         unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */
160         temp |= (cpsr << 1);                     /* PSR_N_BIT |= PSR_Z_BIT */
161         return temp & PSR_N_BIT;
162 }
163 
164 static unsigned long __kprobes __check_al(unsigned long cpsr)
165 {
166         return true;
167 }
168 
169 kprobe_check_cc * const kprobe_condition_checks[16] = {
170         &__check_eq, &__check_ne, &__check_cs, &__check_cc,
171         &__check_mi, &__check_pl, &__check_vs, &__check_vc,
172         &__check_hi, &__check_ls, &__check_ge, &__check_lt,
173         &__check_gt, &__check_le, &__check_al, &__check_al
174 };
175 
176 
177 void __kprobes kprobe_simulate_nop(struct kprobe *p, struct pt_regs *regs)
178 {
179 }
180 
181 void __kprobes kprobe_emulate_none(struct kprobe *p, struct pt_regs *regs)
182 {
183         p->ainsn.insn_fn();
184 }
185 
186 static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs)
187 {
188         kprobe_opcode_t insn = p->opcode;
189         int rn = (insn >> 16) & 0xf;
190         int lbit = insn & (1 << 20);
191         int wbit = insn & (1 << 21);
192         int ubit = insn & (1 << 23);
193         int pbit = insn & (1 << 24);
194         long *addr = (long *)regs->uregs[rn];
195         int reg_bit_vector;
196         int reg_count;
197 
198         reg_count = 0;
199         reg_bit_vector = insn & 0xffff;
200         while (reg_bit_vector) {
201                 reg_bit_vector &= (reg_bit_vector - 1);
202                 ++reg_count;
203         }
204 
205         if (!ubit)
206                 addr -= reg_count;
207         addr += (!pbit == !ubit);
208 
209         reg_bit_vector = insn & 0xffff;
210         while (reg_bit_vector) {
211                 int reg = __ffs(reg_bit_vector);
212                 reg_bit_vector &= (reg_bit_vector - 1);
213                 if (lbit)
214                         regs->uregs[reg] = *addr++;
215                 else
216                         *addr++ = regs->uregs[reg];
217         }
218 
219         if (wbit) {
220                 if (!ubit)
221                         addr -= reg_count;
222                 addr -= (!pbit == !ubit);
223                 regs->uregs[rn] = (long)addr;
224         }
225 }
226 
227 static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs)
228 {
229         regs->ARM_pc = (long)p->addr + str_pc_offset;
230         simulate_ldm1stm1(p, regs);
231         regs->ARM_pc = (long)p->addr + 4;
232 }
233 
234 static void __kprobes simulate_ldm1_pc(struct kprobe *p, struct pt_regs *regs)
235 {
236         simulate_ldm1stm1(p, regs);
237         load_write_pc(regs->ARM_pc, regs);
238 }
239 
240 static void __kprobes
241 emulate_generic_r0_12_noflags(struct kprobe *p, struct pt_regs *regs)
242 {
243         register void *rregs asm("r1") = regs;
244         register void *rfn asm("lr") = p->ainsn.insn_fn;
245 
246         __asm__ __volatile__ (
247                 "stmdb  sp!, {%[regs], r11}     \n\t"
248                 "ldmia  %[regs], {r0-r12}       \n\t"
249 #if __LINUX_ARM_ARCH__ >= 6
250                 "blx    %[fn]                   \n\t"
251 #else
252                 "str    %[fn], [sp, #-4]!       \n\t"
253                 "adr    lr, 1f                  \n\t"
254                 "ldr    pc, [sp], #4            \n\t"
255                 "1:                             \n\t"
256 #endif
257                 "ldr    lr, [sp], #4            \n\t" /* lr = regs */
258                 "stmia  lr, {r0-r12}            \n\t"
259                 "ldr    r11, [sp], #4           \n\t"
260                 : [regs] "=r" (rregs), [fn] "=r" (rfn)
261                 : "" (rregs), "1" (rfn)
262                 : "r0", "r2", "r3", "r4", "r5", "r6", "r7",
263                   "r8", "r9", "r10", "r12", "memory", "cc"
264                 );
265 }
266 
267 static void __kprobes
268 emulate_generic_r2_14_noflags(struct kprobe *p, struct pt_regs *regs)
269 {
270         emulate_generic_r0_12_noflags(p, (struct pt_regs *)(regs->uregs+2));
271 }
272 
273 static void __kprobes
274 emulate_ldm_r3_15(struct kprobe *p, struct pt_regs *regs)
275 {
276         emulate_generic_r0_12_noflags(p, (struct pt_regs *)(regs->uregs+3));
277         load_write_pc(regs->ARM_pc, regs);
278 }
279 
280 enum kprobe_insn __kprobes
281 kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_specific_insn *asi)
282 {
283         kprobe_insn_handler_t *handler = 0;
284         unsigned reglist = insn & 0xffff;
285         int is_ldm = insn & 0x100000;
286         int rn = (insn >> 16) & 0xf;
287 
288         if (rn <= 12 && (reglist & 0xe000) == 0) {
289                 /* Instruction only uses registers in the range R0..R12 */
290                 handler = emulate_generic_r0_12_noflags;
291 
292         } else if (rn >= 2 && (reglist & 0x8003) == 0) {
293                 /* Instruction only uses registers in the range R2..R14 */
294                 rn -= 2;
295                 reglist >>= 2;
296                 handler = emulate_generic_r2_14_noflags;
297 
298         } else if (rn >= 3 && (reglist & 0x0007) == 0) {
299                 /* Instruction only uses registers in the range R3..R15 */
300                 if (is_ldm && (reglist & 0x8000)) {
301                         rn -= 3;
302                         reglist >>= 3;
303                         handler = emulate_ldm_r3_15;
304                 }
305         }
306 
307         if (handler) {
308                 /* We can emulate the instruction in (possibly) modified form */
309                 asi->insn[0] = __opcode_to_mem_arm((insn & 0xfff00000) |
310                                                    (rn << 16) | reglist);
311                 asi->insn_handler = handler;
312                 return INSN_GOOD;
313         }
314 
315         /* Fallback to slower simulation... */
316         if (reglist & 0x8000)
317                 handler = is_ldm ? simulate_ldm1_pc : simulate_stm1_pc;
318         else
319                 handler = simulate_ldm1stm1;
320         asi->insn_handler = handler;
321         return INSN_GOOD_NO_SLOT;
322 }
323 
324 
325 /*
326  * Prepare an instruction slot to receive an instruction for emulating.
327  * This is done by placing a subroutine return after the location where the
328  * instruction will be placed. We also modify ARM instructions to be
329  * unconditional as the condition code will already be checked before any
330  * emulation handler is called.
331  */
332 static kprobe_opcode_t __kprobes
333 prepare_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
334                                                                 bool thumb)
335 {
336 #ifdef CONFIG_THUMB2_KERNEL
337         if (thumb) {
338                 u16 *thumb_insn = (u16 *)asi->insn;
339                 /* Thumb bx lr */
340                 thumb_insn[1] = __opcode_to_mem_thumb16(0x4770);
341                 thumb_insn[2] = __opcode_to_mem_thumb16(0x4770);
342                 return insn;
343         }
344         asi->insn[1] = __opcode_to_mem_arm(0xe12fff1e); /* ARM bx lr */
345 #else
346         asi->insn[1] = __opcode_to_mem_arm(0xe1a0f00e); /* mov pc, lr */
347 #endif
348         /* Make an ARM instruction unconditional */
349         if (insn < 0xe0000000)
350                 insn = (insn | 0xe0000000) & ~0x10000000;
351         return insn;
352 }
353 
354 /*
355  * Write a (probably modified) instruction into the slot previously prepared by
356  * prepare_emulated_insn
357  */
358 static void  __kprobes
359 set_emulated_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
360                                                                 bool thumb)
361 {
362 #ifdef CONFIG_THUMB2_KERNEL
363         if (thumb) {
364                 u16 *ip = (u16 *)asi->insn;
365                 if (is_wide_instruction(insn))
366                         *ip++ = __opcode_to_mem_thumb16(insn >> 16);
367                 *ip++ = __opcode_to_mem_thumb16(insn);
368                 return;
369         }
370 #endif
371         asi->insn[0] = __opcode_to_mem_arm(insn);
372 }
373 
374 /*
375  * When we modify the register numbers encoded in an instruction to be emulated,
376  * the new values come from this define. For ARM and 32-bit Thumb instructions
377  * this gives...
378  *
379  *      bit position      16  12   8   4   0
380  *      ---------------+---+---+---+---+---+
381  *      register         r2  r0  r1  --  r3
382  */
383 #define INSN_NEW_BITS           0x00020103
384 
385 /* Each nibble has same value as that at INSN_NEW_BITS bit 16 */
386 #define INSN_SAMEAS16_BITS      0x22222222
387 
388 /*
389  * Validate and modify each of the registers encoded in an instruction.
390  *
391  * Each nibble in regs contains a value from enum decode_reg_type. For each
392  * non-zero value, the corresponding nibble in pinsn is validated and modified
393  * according to the type.
394  */
395 static bool __kprobes decode_regs(kprobe_opcode_t* pinsn, u32 regs)
396 {
397         kprobe_opcode_t insn = *pinsn;
398         kprobe_opcode_t mask = 0xf; /* Start at least significant nibble */
399 
400         for (; regs != 0; regs >>= 4, mask <<= 4) {
401 
402                 kprobe_opcode_t new_bits = INSN_NEW_BITS;
403 
404                 switch (regs & 0xf) {
405 
406                 case REG_TYPE_NONE:
407                         /* Nibble not a register, skip to next */
408                         continue;
409 
410                 case REG_TYPE_ANY:
411                         /* Any register is allowed */
412                         break;
413 
414                 case REG_TYPE_SAMEAS16:
415                         /* Replace register with same as at bit position 16 */
416                         new_bits = INSN_SAMEAS16_BITS;
417                         break;
418 
419                 case REG_TYPE_SP:
420                         /* Only allow SP (R13) */
421                         if ((insn ^ 0xdddddddd) & mask)
422                                 goto reject;
423                         break;
424 
425                 case REG_TYPE_PC:
426                         /* Only allow PC (R15) */
427                         if ((insn ^ 0xffffffff) & mask)
428                                 goto reject;
429                         break;
430 
431                 case REG_TYPE_NOSP:
432                         /* Reject SP (R13) */
433                         if (((insn ^ 0xdddddddd) & mask) == 0)
434                                 goto reject;
435                         break;
436 
437                 case REG_TYPE_NOSPPC:
438                 case REG_TYPE_NOSPPCX:
439                         /* Reject SP and PC (R13 and R15) */
440                         if (((insn ^ 0xdddddddd) & 0xdddddddd & mask) == 0)
441                                 goto reject;
442                         break;
443 
444                 case REG_TYPE_NOPCWB:
445                         if (!is_writeback(insn))
446                                 break; /* No writeback, so any register is OK */
447                         /* fall through... */
448                 case REG_TYPE_NOPC:
449                 case REG_TYPE_NOPCX:
450                         /* Reject PC (R15) */
451                         if (((insn ^ 0xffffffff) & mask) == 0)
452                                 goto reject;
453                         break;
454                 }
455 
456                 /* Replace value of nibble with new register number... */
457                 insn &= ~mask;
458                 insn |= new_bits & mask;
459         }
460 
461         *pinsn = insn;
462         return true;
463 
464 reject:
465         return false;
466 }
467 
468 static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
469         [DECODE_TYPE_TABLE]     = sizeof(struct decode_table),
470         [DECODE_TYPE_CUSTOM]    = sizeof(struct decode_custom),
471         [DECODE_TYPE_SIMULATE]  = sizeof(struct decode_simulate),
472         [DECODE_TYPE_EMULATE]   = sizeof(struct decode_emulate),
473         [DECODE_TYPE_OR]        = sizeof(struct decode_or),
474         [DECODE_TYPE_REJECT]    = sizeof(struct decode_reject)
475 };
476 
477 /*
478  * kprobe_decode_insn operates on data tables in order to decode an ARM
479  * architecture instruction onto which a kprobe has been placed.
480  *
481  * These instruction decoding tables are a concatenation of entries each
482  * of which consist of one of the following structs:
483  *
484  *      decode_table
485  *      decode_custom
486  *      decode_simulate
487  *      decode_emulate
488  *      decode_or
489  *      decode_reject
490  *
491  * Each of these starts with a struct decode_header which has the following
492  * fields:
493  *
494  *      type_regs
495  *      mask
496  *      value
497  *
498  * The least significant DECODE_TYPE_BITS of type_regs contains a value
499  * from enum decode_type, this indicates which of the decode_* structs
500  * the entry contains. The value DECODE_TYPE_END indicates the end of the
501  * table.
502  *
503  * When the table is parsed, each entry is checked in turn to see if it
504  * matches the instruction to be decoded using the test:
505  *
506  *      (insn & mask) == value
507  *
508  * If no match is found before the end of the table is reached then decoding
509  * fails with INSN_REJECTED.
510  *
511  * When a match is found, decode_regs() is called to validate and modify each
512  * of the registers encoded in the instruction; the data it uses to do this
513  * is (type_regs >> DECODE_TYPE_BITS). A validation failure will cause decoding
514  * to fail with INSN_REJECTED.
515  *
516  * Once the instruction has passed the above tests, further processing
517  * depends on the type of the table entry's decode struct.
518  *
519  */
520 int __kprobes
521 kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi,
522                                 const union decode_item *table, bool thumb)
523 {
524         const struct decode_header *h = (struct decode_header *)table;
525         const struct decode_header *next;
526         bool matched = false;
527 
528         insn = prepare_emulated_insn(insn, asi, thumb);
529 
530         for (;; h = next) {
531                 enum decode_type type = h->type_regs.bits & DECODE_TYPE_MASK;
532                 u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
533 
534                 if (type == DECODE_TYPE_END)
535                         return INSN_REJECTED;
536 
537                 next = (struct decode_header *)
538                                 ((uintptr_t)h + decode_struct_sizes[type]);
539 
540                 if (!matched && (insn & h->mask.bits) != h->value.bits)
541                         continue;
542 
543                 if (!decode_regs(&insn, regs))
544                         return INSN_REJECTED;
545 
546                 switch (type) {
547 
548                 case DECODE_TYPE_TABLE: {
549                         struct decode_table *d = (struct decode_table *)h;
550                         next = (struct decode_header *)d->table.table;
551                         break;
552                 }
553 
554                 case DECODE_TYPE_CUSTOM: {
555                         struct decode_custom *d = (struct decode_custom *)h;
556                         return (*d->decoder.decoder)(insn, asi);
557                 }
558 
559                 case DECODE_TYPE_SIMULATE: {
560                         struct decode_simulate *d = (struct decode_simulate *)h;
561                         asi->insn_handler = d->handler.handler;
562                         return INSN_GOOD_NO_SLOT;
563                 }
564 
565                 case DECODE_TYPE_EMULATE: {
566                         struct decode_emulate *d = (struct decode_emulate *)h;
567                         asi->insn_handler = d->handler.handler;
568                         set_emulated_insn(insn, asi, thumb);
569                         return INSN_GOOD;
570                 }
571 
572                 case DECODE_TYPE_OR:
573                         matched = true;
574                         break;
575 
576                 case DECODE_TYPE_REJECT:
577                 default:
578                         return INSN_REJECTED;
579                 }
580                 }
581         }
582 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp