precise.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. {
  2. "precise: test 1",
  3. .insns = {
  4. BPF_MOV64_IMM(BPF_REG_0, 1),
  5. BPF_LD_MAP_FD(BPF_REG_6, 0),
  6. BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
  7. BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP),
  8. BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  9. BPF_ST_MEM(BPF_DW, BPF_REG_FP, -8, 0),
  10. BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
  11. BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
  12. BPF_EXIT_INSN(),
  13. BPF_MOV64_REG(BPF_REG_9, BPF_REG_0),
  14. BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
  15. BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP),
  16. BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  17. BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
  18. BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
  19. BPF_EXIT_INSN(),
  20. BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
  21. BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8), /* map_value_ptr -= map_value_ptr */
  22. BPF_MOV64_REG(BPF_REG_2, BPF_REG_9),
  23. BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 8, 1),
  24. BPF_EXIT_INSN(),
  25. BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), /* R2=scalar(umin=1, umax=8) */
  26. BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP),
  27. BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
  28. BPF_MOV64_IMM(BPF_REG_3, 0),
  29. BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
  30. BPF_EXIT_INSN(),
  31. },
  32. .prog_type = BPF_PROG_TYPE_TRACEPOINT,
  33. .fixup_map_array_48b = { 1 },
  34. .result = VERBOSE_ACCEPT,
  35. .errstr =
  36. "mark_precise: frame0: last_idx 26 first_idx 20\
  37. mark_precise: frame0: regs=r2 stack= before 25\
  38. mark_precise: frame0: regs=r2 stack= before 24\
  39. mark_precise: frame0: regs=r2 stack= before 23\
  40. mark_precise: frame0: regs=r2 stack= before 22\
  41. mark_precise: frame0: regs=r2 stack= before 20\
  42. mark_precise: frame0: parent state regs=r2 stack=:\
  43. mark_precise: frame0: last_idx 19 first_idx 10\
  44. mark_precise: frame0: regs=r2 stack= before 19\
  45. mark_precise: frame0: regs=r9 stack= before 18\
  46. mark_precise: frame0: regs=r8,r9 stack= before 17\
  47. mark_precise: frame0: regs=r0,r9 stack= before 15\
  48. mark_precise: frame0: regs=r0,r9 stack= before 14\
  49. mark_precise: frame0: regs=r9 stack= before 13\
  50. mark_precise: frame0: regs=r9 stack= before 12\
  51. mark_precise: frame0: regs=r9 stack= before 11\
  52. mark_precise: frame0: regs=r9 stack= before 10\
  53. mark_precise: frame0: parent state regs= stack=:",
  54. },
  55. {
  56. "precise: test 2",
  57. .insns = {
  58. BPF_MOV64_IMM(BPF_REG_0, 1),
  59. BPF_LD_MAP_FD(BPF_REG_6, 0),
  60. BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
  61. BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP),
  62. BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  63. BPF_ST_MEM(BPF_DW, BPF_REG_FP, -8, 0),
  64. BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
  65. BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
  66. BPF_EXIT_INSN(),
  67. BPF_MOV64_REG(BPF_REG_9, BPF_REG_0),
  68. BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
  69. BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP),
  70. BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
  71. BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
  72. BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
  73. BPF_EXIT_INSN(),
  74. BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
  75. BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_8), /* map_value_ptr -= map_value_ptr */
  76. BPF_MOV64_REG(BPF_REG_2, BPF_REG_9),
  77. BPF_JMP_IMM(BPF_JLT, BPF_REG_2, 8, 1),
  78. BPF_EXIT_INSN(),
  79. BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), /* R2=scalar(umin=1, umax=8) */
  80. BPF_MOV64_REG(BPF_REG_1, BPF_REG_FP),
  81. BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8),
  82. BPF_MOV64_IMM(BPF_REG_3, 0),
  83. BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel),
  84. BPF_EXIT_INSN(),
  85. },
  86. .prog_type = BPF_PROG_TYPE_TRACEPOINT,
  87. .fixup_map_array_48b = { 1 },
  88. .result = VERBOSE_ACCEPT,
  89. .flags = BPF_F_TEST_STATE_FREQ,
  90. .errstr =
  91. "26: (85) call bpf_probe_read_kernel#113\
  92. mark_precise: frame0: last_idx 26 first_idx 22\
  93. mark_precise: frame0: regs=r2 stack= before 25\
  94. mark_precise: frame0: regs=r2 stack= before 24\
  95. mark_precise: frame0: regs=r2 stack= before 23\
  96. mark_precise: frame0: regs=r2 stack= before 22\
  97. mark_precise: frame0: parent state regs=r2 stack=:\
  98. mark_precise: frame0: last_idx 20 first_idx 20\
  99. mark_precise: frame0: regs=r2 stack= before 20\
  100. mark_precise: frame0: parent state regs=r2 stack=:\
  101. mark_precise: frame0: last_idx 19 first_idx 17\
  102. mark_precise: frame0: regs=r2 stack= before 19\
  103. mark_precise: frame0: regs=r9 stack= before 18\
  104. mark_precise: frame0: regs=r8,r9 stack= before 17\
  105. mark_precise: frame0: parent state regs= stack=:",
  106. },
  107. {
  108. "precise: cross frame pruning",
  109. .insns = {
  110. BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
  111. BPF_MOV64_IMM(BPF_REG_8, 0),
  112. BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
  113. BPF_MOV64_IMM(BPF_REG_8, 1),
  114. BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
  115. BPF_MOV64_IMM(BPF_REG_9, 0),
  116. BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
  117. BPF_MOV64_IMM(BPF_REG_9, 1),
  118. BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
  119. BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4),
  120. BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 1, 1),
  121. BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_2, 0),
  122. BPF_MOV64_IMM(BPF_REG_0, 0),
  123. BPF_EXIT_INSN(),
  124. BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 0),
  125. BPF_EXIT_INSN(),
  126. },
  127. .prog_type = BPF_PROG_TYPE_XDP,
  128. .flags = BPF_F_TEST_STATE_FREQ,
  129. .errstr = "!read_ok",
  130. .result = REJECT,
  131. },
  132. {
  133. "precise: ST zero to stack insn is supported",
  134. .insns = {
  135. BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
  136. BPF_JMP_IMM(BPF_JNE, BPF_REG_3, 123, 0),
  137. /* not a register spill, so we stop precision propagation for R4 here */
  138. BPF_ST_MEM(BPF_DW, BPF_REG_3, -8, 0),
  139. BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
  140. BPF_MOV64_IMM(BPF_REG_0, -1),
  141. BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 0),
  142. BPF_EXIT_INSN(),
  143. },
  144. .prog_type = BPF_PROG_TYPE_XDP,
  145. .flags = BPF_F_TEST_STATE_FREQ,
  146. .errstr = "mark_precise: frame0: last_idx 5 first_idx 5\
  147. mark_precise: frame0: parent state regs=r4 stack=:\
  148. mark_precise: frame0: last_idx 4 first_idx 2\
  149. mark_precise: frame0: regs=r4 stack= before 4\
  150. mark_precise: frame0: regs=r4 stack= before 3\
  151. mark_precise: frame0: last_idx 5 first_idx 5\
  152. mark_precise: frame0: parent state regs=r0 stack=:\
  153. mark_precise: frame0: last_idx 4 first_idx 2\
  154. mark_precise: frame0: regs=r0 stack= before 4\
  155. 5: R0=-1 R4=0",
  156. .result = VERBOSE_ACCEPT,
  157. .retval = -1,
  158. },
  159. {
  160. "precise: STX insn causing spi > allocated_stack",
  161. .insns = {
  162. BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
  163. /* make later reg spill more interesting by having somewhat known scalar */
  164. BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xff),
  165. BPF_MOV64_REG(BPF_REG_3, BPF_REG_10),
  166. BPF_JMP_IMM(BPF_JNE, BPF_REG_3, 123, 0),
  167. BPF_STX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, -8),
  168. BPF_LDX_MEM(BPF_DW, BPF_REG_4, BPF_REG_10, -8),
  169. BPF_MOV64_IMM(BPF_REG_0, -1),
  170. BPF_JMP_REG(BPF_JGT, BPF_REG_4, BPF_REG_0, 0),
  171. BPF_EXIT_INSN(),
  172. },
  173. .prog_type = BPF_PROG_TYPE_XDP,
  174. .flags = BPF_F_TEST_STATE_FREQ,
  175. .errstr = "mark_precise: frame0: last_idx 7 first_idx 7\
  176. mark_precise: frame0: parent state regs=r4 stack=:\
  177. mark_precise: frame0: last_idx 6 first_idx 4\
  178. mark_precise: frame0: regs=r4 stack= before 6: (b7) r0 = -1\
  179. mark_precise: frame0: regs=r4 stack= before 5: (79) r4 = *(u64 *)(r10 -8)\
  180. mark_precise: frame0: regs= stack=-8 before 4: (7b) *(u64 *)(r3 -8) = r0\
  181. mark_precise: frame0: parent state regs=r0 stack=:\
  182. mark_precise: frame0: last_idx 3 first_idx 3\
  183. mark_precise: frame0: regs=r0 stack= before 3: (55) if r3 != 0x7b goto pc+0\
  184. mark_precise: frame0: regs=r0 stack= before 2: (bf) r3 = r10\
  185. mark_precise: frame0: regs=r0 stack= before 1: (57) r0 &= 255\
  186. mark_precise: frame0: parent state regs=r0 stack=:\
  187. mark_precise: frame0: last_idx 0 first_idx 0\
  188. mark_precise: frame0: regs=r0 stack= before 0: (85) call bpf_get_prandom_u32#7\
  189. mark_precise: frame0: last_idx 7 first_idx 7\
  190. mark_precise: frame0: parent state regs= stack=:",
  191. .result = VERBOSE_ACCEPT,
  192. .retval = -1,
  193. },
  194. {
  195. "precise: mark_chain_precision for ARG_CONST_ALLOC_SIZE_OR_ZERO",
  196. .insns = {
  197. BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, offsetof(struct xdp_md, ingress_ifindex)),
  198. BPF_LD_MAP_FD(BPF_REG_6, 0),
  199. BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
  200. BPF_MOV64_IMM(BPF_REG_2, 1),
  201. BPF_MOV64_IMM(BPF_REG_3, 0),
  202. BPF_JMP_IMM(BPF_JEQ, BPF_REG_4, 0, 1),
  203. BPF_MOV64_IMM(BPF_REG_2, 0x1000),
  204. BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_reserve),
  205. BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
  206. BPF_EXIT_INSN(),
  207. BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
  208. BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 42),
  209. BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_ringbuf_submit),
  210. BPF_MOV64_IMM(BPF_REG_0, 0),
  211. BPF_EXIT_INSN(),
  212. },
  213. .fixup_map_ringbuf = { 1 },
  214. .prog_type = BPF_PROG_TYPE_XDP,
  215. .flags = BPF_F_TEST_STATE_FREQ | F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
  216. .errstr = "invalid access to memory, mem_size=1 off=42 size=8",
  217. .result = REJECT,
  218. },
  219. {
  220. "precise: program doesn't prematurely prune branches",
  221. .insns = {
  222. BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
  223. BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_0),
  224. BPF_ALU64_IMM(BPF_MOV, BPF_REG_7, 0),
  225. BPF_ALU64_IMM(BPF_MOV, BPF_REG_8, 0),
  226. BPF_ALU64_IMM(BPF_MOV, BPF_REG_9, 0x80000000),
  227. BPF_JMP_IMM(BPF_JA, 0, 0, 0),
  228. BPF_JMP_REG(BPF_JLE, BPF_REG_6, BPF_REG_9, 2),
  229. BPF_ALU64_IMM(BPF_MOD, BPF_REG_6, 1),
  230. BPF_ALU64_IMM(BPF_MOV, BPF_REG_9, 0),
  231. BPF_JMP_REG(BPF_JLE, BPF_REG_6, BPF_REG_9, 1),
  232. BPF_ALU64_IMM(BPF_MOV, BPF_REG_6, 0),
  233. BPF_ALU64_IMM(BPF_MOV, BPF_REG_0, 0),
  234. BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4),
  235. BPF_LD_MAP_FD(BPF_REG_4, 0),
  236. BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_4),
  237. BPF_ALU64_REG(BPF_MOV, BPF_REG_2, BPF_REG_10),
  238. BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
  239. BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
  240. BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
  241. BPF_EXIT_INSN(),
  242. BPF_ALU64_IMM(BPF_RSH, BPF_REG_6, 10),
  243. BPF_ALU64_IMM(BPF_MUL, BPF_REG_6, 8192),
  244. BPF_ALU64_REG(BPF_MOV, BPF_REG_1, BPF_REG_0),
  245. BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
  246. BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
  247. BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_3, 0),
  248. BPF_EXIT_INSN(),
  249. },
  250. .fixup_map_array_48b = { 13 },
  251. .prog_type = BPF_PROG_TYPE_XDP,
  252. .result = REJECT,
  253. .errstr = "register with unbounded min value is not allowed",
  254. },