stack_ptr.c (9848B)
1{ 2 "PTR_TO_STACK store/load", 3 .insns = { 4 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 5 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10), 6 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c), 7 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2), 8 BPF_EXIT_INSN(), 9 }, 10 .result = ACCEPT, 11 .retval = 0xfaceb00c, 12}, 13{ 14 "PTR_TO_STACK store/load - bad alignment on off", 15 .insns = { 16 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 17 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 18 BPF_ST_MEM(BPF_DW, BPF_REG_1, 2, 0xfaceb00c), 19 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 2), 20 BPF_EXIT_INSN(), 21 }, 22 .result = REJECT, 23 .errstr = "misaligned stack access off (0x0; 0x0)+-8+2 size 8", 24}, 25{ 26 "PTR_TO_STACK store/load - bad alignment on reg", 27 .insns = { 28 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 29 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -10), 30 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c), 31 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8), 32 BPF_EXIT_INSN(), 33 }, 34 .result = REJECT, 35 .errstr = "misaligned stack access off (0x0; 0x0)+-10+8 size 8", 36}, 37{ 38 "PTR_TO_STACK store/load - out of bounds low", 39 .insns = { 40 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 41 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -80000), 42 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c), 43 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8), 44 BPF_EXIT_INSN(), 45 }, 46 .result = REJECT, 47 .errstr = "invalid write to stack R1 off=-79992 size=8", 48 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 49}, 50{ 51 "PTR_TO_STACK store/load - out of bounds high", 52 .insns = { 53 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 54 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), 55 BPF_ST_MEM(BPF_DW, BPF_REG_1, 8, 0xfaceb00c), 56 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, 8), 57 BPF_EXIT_INSN(), 58 }, 59 .result = REJECT, 60 .errstr = "invalid write to stack R1 off=0 size=8", 61}, 62{ 63 "PTR_TO_STACK check high 1", 64 .insns = { 65 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 66 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -1), 67 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 68 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 69 BPF_EXIT_INSN(), 70 }, 71 .result = ACCEPT, 72 .retval = 42, 73}, 74{ 75 "PTR_TO_STACK check high 2", 76 .insns = { 77 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 78 BPF_ST_MEM(BPF_B, BPF_REG_1, -1, 42), 79 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, -1), 80 BPF_EXIT_INSN(), 81 }, 82 .result = ACCEPT, 83 .retval = 42, 84}, 85{ 86 "PTR_TO_STACK check high 3", 87 .insns = { 88 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 89 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0), 90 BPF_ST_MEM(BPF_B, BPF_REG_1, -1, 42), 91 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, -1), 92 BPF_EXIT_INSN(), 93 }, 94 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 95 .result_unpriv = REJECT, 96 .result = ACCEPT, 97 .retval = 42, 98}, 99{ 100 "PTR_TO_STACK check high 4", 101 .insns = { 102 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 103 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0), 104 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 105 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 106 BPF_EXIT_INSN(), 107 }, 108 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 109 .errstr = "invalid write to stack R1 off=0 size=1", 110 .result = REJECT, 111}, 112{ 113 "PTR_TO_STACK check high 5", 114 .insns = { 115 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 116 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1), 117 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 118 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 119 BPF_EXIT_INSN(), 120 }, 121 .result = REJECT, 122 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 123 .errstr = "invalid write to stack R1", 124}, 125{ 126 "PTR_TO_STACK check high 6", 127 .insns = { 128 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 129 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1), 130 BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MAX, 42), 131 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MAX), 132 BPF_EXIT_INSN(), 133 }, 134 .result = REJECT, 135 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 136 .errstr = "invalid write to stack", 137}, 138{ 139 "PTR_TO_STACK check high 7", 140 .insns = { 141 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 142 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1), 143 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, (1 << 29) - 1), 144 BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MAX, 42), 145 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MAX), 146 BPF_EXIT_INSN(), 147 }, 148 .result = REJECT, 149 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 150 .errstr = "fp pointer offset", 151}, 152{ 153 "PTR_TO_STACK check low 1", 154 .insns = { 155 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 156 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -512), 157 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 158 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 159 BPF_EXIT_INSN(), 160 }, 161 .result = ACCEPT, 162 .retval = 42, 163}, 164{ 165 "PTR_TO_STACK check low 2", 166 .insns = { 167 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 168 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -513), 169 BPF_ST_MEM(BPF_B, BPF_REG_1, 1, 42), 170 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 1), 171 BPF_EXIT_INSN(), 172 }, 173 .result_unpriv = REJECT, 174 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 175 .result = ACCEPT, 176 .retval = 42, 177}, 178{ 179 "PTR_TO_STACK check low 3", 180 .insns = { 181 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 182 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -513), 183 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 184 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 185 BPF_EXIT_INSN(), 186 }, 187 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 188 .errstr = "invalid write to stack R1 off=-513 size=1", 189 .result = REJECT, 190}, 191{ 192 "PTR_TO_STACK check low 4", 193 .insns = { 194 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 195 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, INT_MIN), 196 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 197 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 198 BPF_EXIT_INSN(), 199 }, 200 .result = REJECT, 201 .errstr = "math between fp pointer", 202}, 203{ 204 "PTR_TO_STACK check low 5", 205 .insns = { 206 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 207 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)), 208 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 209 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 210 BPF_EXIT_INSN(), 211 }, 212 .result = REJECT, 213 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 214 .errstr = "invalid write to stack", 215}, 216{ 217 "PTR_TO_STACK check low 6", 218 .insns = { 219 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 220 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)), 221 BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MIN, 42), 222 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MIN), 223 BPF_EXIT_INSN(), 224 }, 225 .result = REJECT, 226 .errstr = "invalid write to stack", 227 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 228}, 229{ 230 "PTR_TO_STACK check low 7", 231 .insns = { 232 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 233 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)), 234 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -((1 << 29) - 1)), 235 BPF_ST_MEM(BPF_B, BPF_REG_1, SHRT_MIN, 42), 236 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, SHRT_MIN), 237 BPF_EXIT_INSN(), 238 }, 239 .result = REJECT, 240 .errstr_unpriv = "R1 stack pointer arithmetic goes out of range", 241 .errstr = "fp pointer offset", 242}, 243{ 244 "PTR_TO_STACK mixed reg/k, 1", 245 .insns = { 246 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 247 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -3), 248 BPF_MOV64_IMM(BPF_REG_2, -3), 249 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 250 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 251 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 252 BPF_EXIT_INSN(), 253 }, 254 .result = ACCEPT, 255 .retval = 42, 256}, 257{ 258 "PTR_TO_STACK mixed reg/k, 2", 259 .insns = { 260 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), 261 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0), 262 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 263 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -3), 264 BPF_MOV64_IMM(BPF_REG_2, -3), 265 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 266 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 267 BPF_MOV64_REG(BPF_REG_5, BPF_REG_10), 268 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_5, -6), 269 BPF_EXIT_INSN(), 270 }, 271 .result = ACCEPT, 272 .retval = 42, 273}, 274{ 275 "PTR_TO_STACK mixed reg/k, 3", 276 .insns = { 277 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 278 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -3), 279 BPF_MOV64_IMM(BPF_REG_2, -3), 280 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 281 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 282 BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), 283 BPF_EXIT_INSN(), 284 }, 285 .result = ACCEPT, 286 .retval = -3, 287}, 288{ 289 "PTR_TO_STACK reg", 290 .insns = { 291 BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), 292 BPF_MOV64_IMM(BPF_REG_2, -3), 293 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2), 294 BPF_ST_MEM(BPF_B, BPF_REG_1, 0, 42), 295 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), 296 BPF_EXIT_INSN(), 297 }, 298 .result = ACCEPT, 299 .retval = 42, 300}, 301{ 302 "stack pointer arithmetic", 303 .insns = { 304 BPF_MOV64_IMM(BPF_REG_1, 4), 305 BPF_JMP_IMM(BPF_JA, 0, 0, 0), 306 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), 307 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10), 308 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -10), 309 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), 310 BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1), 311 BPF_ST_MEM(0, BPF_REG_2, 4, 0), 312 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7), 313 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 8), 314 BPF_ST_MEM(0, BPF_REG_2, 4, 0), 315 BPF_MOV64_IMM(BPF_REG_0, 0), 316 BPF_EXIT_INSN(), 317 }, 318 .result = ACCEPT, 319}, 320{ 321 "store PTR_TO_STACK in R10 to array map using BPF_B", 322 .insns = { 323 /* Load pointer to map. */ 324 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), 325 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), 326 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0), 327 BPF_LD_MAP_FD(BPF_REG_1, 0), 328 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), 329 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2), 330 BPF_MOV64_IMM(BPF_REG_0, 2), 331 BPF_EXIT_INSN(), 332 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), 333 /* Copy R10 to R9. */ 334 BPF_MOV64_REG(BPF_REG_9, BPF_REG_10), 335 /* Pollute other registers with unaligned values. */ 336 BPF_MOV64_IMM(BPF_REG_2, -1), 337 BPF_MOV64_IMM(BPF_REG_3, -1), 338 BPF_MOV64_IMM(BPF_REG_4, -1), 339 BPF_MOV64_IMM(BPF_REG_5, -1), 340 BPF_MOV64_IMM(BPF_REG_6, -1), 341 BPF_MOV64_IMM(BPF_REG_7, -1), 342 BPF_MOV64_IMM(BPF_REG_8, -1), 343 /* Store both R9 and R10 with BPF_B and read back. */ 344 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_10, 0), 345 BPF_LDX_MEM(BPF_B, BPF_REG_2, BPF_REG_1, 0), 346 BPF_STX_MEM(BPF_B, BPF_REG_1, BPF_REG_9, 0), 347 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_1, 0), 348 /* Should read back as same value. */ 349 BPF_JMP_REG(BPF_JEQ, BPF_REG_2, BPF_REG_3, 2), 350 BPF_MOV64_IMM(BPF_REG_0, 1), 351 BPF_EXIT_INSN(), 352 BPF_MOV64_IMM(BPF_REG_0, 42), 353 BPF_EXIT_INSN(), 354 }, 355 .fixup_map_array_48b = { 3 }, 356 .result = ACCEPT, 357 .retval = 42, 358 .prog_type = BPF_PROG_TYPE_SCHED_CLS, 359},