uprobes.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * Copyright (C) 2014-2016 Pratyush Anand <panand@redhat.com>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. */
  8. #include <linux/highmem.h>
  9. #include <linux/ptrace.h>
  10. #include <linux/uprobes.h>
  11. #include <asm/cacheflush.h>
  12. #include "decode-insn.h"
  13. #define UPROBE_INV_FAULT_CODE UINT_MAX
  14. void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr,
  15. void *src, unsigned long len)
  16. {
  17. void *xol_page_kaddr = kmap_atomic(page);
  18. void *dst = xol_page_kaddr + (vaddr & ~PAGE_MASK);
  19. /* Initialize the slot */
  20. memcpy(dst, src, len);
  21. /* flush caches (dcache/icache) */
  22. sync_icache_aliases(dst, len);
  23. kunmap_atomic(xol_page_kaddr);
  24. }
  25. unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
  26. {
  27. return instruction_pointer(regs);
  28. }
  29. int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
  30. unsigned long addr)
  31. {
  32. probe_opcode_t insn;
  33. /* TODO: Currently we do not support AARCH32 instruction probing */
  34. if (test_bit(TIF_32BIT, &mm->context.flags))
  35. return -ENOTSUPP;
  36. else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE))
  37. return -EINVAL;
  38. insn = *(probe_opcode_t *)(&auprobe->insn[0]);
  39. switch (arm_probe_decode_insn(insn, &auprobe->api)) {
  40. case INSN_REJECTED:
  41. return -EINVAL;
  42. case INSN_GOOD_NO_SLOT:
  43. auprobe->simulate = true;
  44. break;
  45. default:
  46. break;
  47. }
  48. return 0;
  49. }
  50. int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
  51. {
  52. struct uprobe_task *utask = current->utask;
  53. /* Initialize with an invalid fault code to detect if ol insn trapped */
  54. current->thread.fault_code = UPROBE_INV_FAULT_CODE;
  55. /* Instruction points to execute ol */
  56. instruction_pointer_set(regs, utask->xol_vaddr);
  57. user_enable_single_step(current);
  58. return 0;
  59. }
  60. int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
  61. {
  62. struct uprobe_task *utask = current->utask;
  63. WARN_ON_ONCE(current->thread.fault_code != UPROBE_INV_FAULT_CODE);
  64. /* Instruction points to execute next to breakpoint address */
  65. instruction_pointer_set(regs, utask->vaddr + 4);
  66. user_disable_single_step(current);
  67. return 0;
  68. }
  69. bool arch_uprobe_xol_was_trapped(struct task_struct *t)
  70. {
  71. /*
  72. * Between arch_uprobe_pre_xol and arch_uprobe_post_xol, if an xol
  73. * insn itself is trapped, then detect the case with the help of
  74. * invalid fault code which is being set in arch_uprobe_pre_xol
  75. */
  76. if (t->thread.fault_code != UPROBE_INV_FAULT_CODE)
  77. return true;
  78. return false;
  79. }
  80. bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
  81. {
  82. probe_opcode_t insn;
  83. unsigned long addr;
  84. if (!auprobe->simulate)
  85. return false;
  86. insn = *(probe_opcode_t *)(&auprobe->insn[0]);
  87. addr = instruction_pointer(regs);
  88. if (auprobe->api.handler)
  89. auprobe->api.handler(insn, addr, regs);
  90. return true;
  91. }
  92. void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
  93. {
  94. struct uprobe_task *utask = current->utask;
  95. /*
  96. * Task has received a fatal signal, so reset back to probbed
  97. * address.
  98. */
  99. instruction_pointer_set(regs, utask->vaddr);
  100. user_disable_single_step(current);
  101. }
  102. bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
  103. struct pt_regs *regs)
  104. {
  105. /*
  106. * If a simple branch instruction (B) was called for retprobed
  107. * assembly label then return true even when regs->sp and ret->stack
  108. * are same. It will ensure that cleanup and reporting of return
  109. * instances corresponding to callee label is done when
  110. * handle_trampoline for called function is executed.
  111. */
  112. if (ctx == RP_CHECK_CHAIN_CALL)
  113. return regs->sp <= ret->stack;
  114. else
  115. return regs->sp < ret->stack;
  116. }
  117. unsigned long
  118. arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr,
  119. struct pt_regs *regs)
  120. {
  121. unsigned long orig_ret_vaddr;
  122. orig_ret_vaddr = procedure_link_pointer(regs);
  123. /* Replace the return addr with trampoline addr */
  124. procedure_link_pointer_set(regs, trampoline_vaddr);
  125. return orig_ret_vaddr;
  126. }
  127. int arch_uprobe_exception_notify(struct notifier_block *self,
  128. unsigned long val, void *data)
  129. {
  130. return NOTIFY_DONE;
  131. }
  132. static int uprobe_breakpoint_handler(struct pt_regs *regs,
  133. unsigned int esr)
  134. {
  135. if (user_mode(regs) && uprobe_pre_sstep_notifier(regs))
  136. return DBG_HOOK_HANDLED;
  137. return DBG_HOOK_ERROR;
  138. }
  139. static int uprobe_single_step_handler(struct pt_regs *regs,
  140. unsigned int esr)
  141. {
  142. struct uprobe_task *utask = current->utask;
  143. if (user_mode(regs)) {
  144. WARN_ON(utask &&
  145. (instruction_pointer(regs) != utask->xol_vaddr + 4));
  146. if (uprobe_post_sstep_notifier(regs))
  147. return DBG_HOOK_HANDLED;
  148. }
  149. return DBG_HOOK_ERROR;
  150. }
  151. /* uprobe breakpoint handler hook */
  152. static struct break_hook uprobes_break_hook = {
  153. .esr_mask = BRK64_ESR_MASK,
  154. .esr_val = BRK64_ESR_UPROBES,
  155. .fn = uprobe_breakpoint_handler,
  156. };
  157. /* uprobe single step handler hook */
  158. static struct step_hook uprobes_step_hook = {
  159. .fn = uprobe_single_step_handler,
  160. };
  161. static int __init arch_init_uprobes(void)
  162. {
  163. register_break_hook(&uprobes_break_hook);
  164. register_step_hook(&uprobes_step_hook);
  165. return 0;
  166. }
  167. device_initcall(arch_init_uprobes);