cfi.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * This is for all the tests relating directly to Control Flow Integrity.
  4. */
  5. #include "lkdtm.h"
  6. #include <asm/page.h>
  7. static int called_count;
  8. /* Function taking one argument, without a return value. */
  9. static noinline void lkdtm_increment_void(int *counter)
  10. {
  11. (*counter)++;
  12. }
  13. /* Function taking one argument, returning int. */
  14. static noinline int lkdtm_increment_int(int *counter)
  15. {
  16. (*counter)++;
  17. return *counter;
  18. }
  19. /* Don't allow the compiler to inline the calls. */
  20. static noinline void lkdtm_indirect_call(void (*func)(int *))
  21. {
  22. func(&called_count);
  23. }
  24. /*
  25. * This tries to call an indirect function with a mismatched prototype.
  26. */
  27. static void lkdtm_CFI_FORWARD_PROTO(void)
  28. {
  29. /*
  30. * Matches lkdtm_increment_void()'s prototype, but not
  31. * lkdtm_increment_int()'s prototype.
  32. */
  33. pr_info("Calling matched prototype ...\n");
  34. lkdtm_indirect_call(lkdtm_increment_void);
  35. pr_info("Calling mismatched prototype ...\n");
  36. lkdtm_indirect_call((void *)lkdtm_increment_int);
  37. pr_err("FAIL: survived mismatched prototype function call!\n");
  38. pr_expected_config(CONFIG_CFI_CLANG);
  39. }
  40. /*
  41. * This can stay local to LKDTM, as there should not be a production reason
  42. * to disable PAC && SCS.
  43. */
  44. #ifdef CONFIG_ARM64_PTR_AUTH_KERNEL
  45. # ifdef CONFIG_ARM64_BTI_KERNEL
  46. # define __no_pac "branch-protection=bti"
  47. # else
  48. # ifdef CONFIG_CC_HAS_BRANCH_PROT_PAC_RET
  49. # define __no_pac "branch-protection=none"
  50. # else
  51. # define __no_pac "sign-return-address=none"
  52. # endif
  53. # endif
  54. # define __no_ret_protection __noscs __attribute__((__target__(__no_pac)))
  55. #else
  56. # define __no_ret_protection __noscs
  57. #endif
  58. #define no_pac_addr(addr) \
  59. ((__force __typeof__(addr))((uintptr_t)(addr) | PAGE_OFFSET))
  60. #ifdef CONFIG_RISCV
  61. /* https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#frame-pointer-convention */
  62. #define FRAME_RA_OFFSET (-1)
  63. #else
  64. #define FRAME_RA_OFFSET 1
  65. #endif
  66. /* The ultimate ROP gadget. */
  67. static noinline __no_ret_protection
  68. void set_return_addr_unchecked(unsigned long *expected, unsigned long *addr)
  69. {
  70. /* Use of volatile is to make sure final write isn't seen as a dead store. */
  71. unsigned long * volatile *ret_addr =
  72. (unsigned long **)__builtin_frame_address(0) + FRAME_RA_OFFSET;
  73. /* Make sure we've found the right place on the stack before writing it. */
  74. if (no_pac_addr(*ret_addr) == expected)
  75. *ret_addr = (addr);
  76. else
  77. /* Check architecture, stack layout, or compiler behavior... */
  78. pr_warn("Eek: return address mismatch! %px != %px\n",
  79. *ret_addr, addr);
  80. }
  81. static noinline
  82. void set_return_addr(unsigned long *expected, unsigned long *addr)
  83. {
  84. /* Use of volatile is to make sure final write isn't seen as a dead store. */
  85. unsigned long * volatile *ret_addr =
  86. (unsigned long **)__builtin_frame_address(0) + FRAME_RA_OFFSET;
  87. /* Make sure we've found the right place on the stack before writing it. */
  88. if (no_pac_addr(*ret_addr) == expected)
  89. *ret_addr = (addr);
  90. else
  91. /* Check architecture, stack layout, or compiler behavior... */
  92. pr_warn("Eek: return address mismatch! %px != %px\n",
  93. *ret_addr, addr);
  94. }
  95. static volatile int force_check;
  96. static void lkdtm_CFI_BACKWARD(void)
  97. {
  98. /* Use calculated gotos to keep labels addressable. */
  99. void *labels[] = { NULL, &&normal, &&redirected, &&check_normal, &&check_redirected };
  100. pr_info("Attempting unchecked stack return address redirection ...\n");
  101. /* Always false */
  102. if (force_check) {
  103. /*
  104. * Prepare to call with NULLs to avoid parameters being treated as
  105. * constants in -02.
  106. */
  107. set_return_addr_unchecked(NULL, NULL);
  108. set_return_addr(NULL, NULL);
  109. if (force_check)
  110. goto *labels[1];
  111. if (force_check)
  112. goto *labels[2];
  113. if (force_check)
  114. goto *labels[3];
  115. if (force_check)
  116. goto *labels[4];
  117. return;
  118. }
  119. /*
  120. * Use fallthrough switch case to keep basic block ordering between
  121. * set_return_addr*() and the label after it.
  122. */
  123. switch (force_check) {
  124. case 0:
  125. set_return_addr_unchecked(&&normal, &&redirected);
  126. fallthrough;
  127. case 1:
  128. normal:
  129. /* Always true */
  130. if (!force_check) {
  131. pr_err("FAIL: stack return address manipulation failed!\n");
  132. /* If we can't redirect "normally", we can't test mitigations. */
  133. return;
  134. }
  135. break;
  136. default:
  137. redirected:
  138. pr_info("ok: redirected stack return address.\n");
  139. break;
  140. }
  141. pr_info("Attempting checked stack return address redirection ...\n");
  142. switch (force_check) {
  143. case 0:
  144. set_return_addr(&&check_normal, &&check_redirected);
  145. fallthrough;
  146. case 1:
  147. check_normal:
  148. /* Always true */
  149. if (!force_check) {
  150. pr_info("ok: control flow unchanged.\n");
  151. return;
  152. }
  153. check_redirected:
  154. pr_err("FAIL: stack return address was redirected!\n");
  155. break;
  156. }
  157. if (IS_ENABLED(CONFIG_ARM64_PTR_AUTH_KERNEL)) {
  158. pr_expected_config(CONFIG_ARM64_PTR_AUTH_KERNEL);
  159. return;
  160. }
  161. if (IS_ENABLED(CONFIG_SHADOW_CALL_STACK)) {
  162. pr_expected_config(CONFIG_SHADOW_CALL_STACK);
  163. return;
  164. }
  165. pr_warn("This is probably expected, since this %s was built *without* %s=y nor %s=y\n",
  166. lkdtm_kernel_info,
  167. "CONFIG_ARM64_PTR_AUTH_KERNEL", "CONFIG_SHADOW_CALL_STACK");
  168. }
  169. static struct crashtype crashtypes[] = {
  170. CRASHTYPE(CFI_FORWARD_PROTO),
  171. CRASHTYPE(CFI_BACKWARD),
  172. };
  173. struct crashtype_category cfi_crashtypes = {
  174. .crashtypes = crashtypes,
  175. .len = ARRAY_SIZE(crashtypes),
  176. };