|
29 | 29 | { |
30 | 30 | "helper access to variable memory: stack, bitwise AND, zero included", |
31 | 31 | .insns = { |
32 | | - BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8), |
33 | | - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), |
34 | | - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64), |
35 | | - BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128), |
36 | | - BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128), |
37 | | - BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 64), |
38 | | - BPF_MOV64_IMM(BPF_REG_3, 0), |
39 | | - BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel), |
| 32 | + /* set max stack size */ |
| 33 | + BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0), |
| 34 | + /* set r3 to a random value */ |
| 35 | + BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), |
| 36 | + BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), |
| 37 | + /* use bitwise AND to limit r3 range to [0, 64] */ |
| 38 | + BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 64), |
| 39 | + BPF_LD_MAP_FD(BPF_REG_1, 0), |
| 40 | + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| 41 | + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), |
| 42 | + BPF_MOV64_IMM(BPF_REG_4, 0), |
| 43 | + /* Call bpf_ringbuf_output(), it is one of a few helper functions with |
| 44 | + * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode. |
| 45 | + * For unpriv this should signal an error, because memory at &fp[-64] is |
| 46 | + * not initialized. |
| 47 | + */ |
| 48 | + BPF_EMIT_CALL(BPF_FUNC_ringbuf_output), |
40 | 49 | BPF_EXIT_INSN(), |
41 | 50 | }, |
42 | | - .errstr = "invalid indirect read from stack R1 off -64+0 size 64", |
43 | | - .result = REJECT, |
44 | | - .prog_type = BPF_PROG_TYPE_TRACEPOINT, |
| 51 | + .fixup_map_ringbuf = { 4 }, |
| 52 | + .errstr_unpriv = "invalid indirect read from stack R2 off -64+0 size 64", |
| 53 | + .result_unpriv = REJECT, |
| 54 | + /* in privileged mode reads from uninitialized stack locations are permitted */ |
| 55 | + .result = ACCEPT, |
45 | 56 | }, |
46 | 57 | { |
47 | 58 | "helper access to variable memory: stack, bitwise AND + JMP, wrong max", |
|
183 | 194 | { |
184 | 195 | "helper access to variable memory: stack, JMP, no min check", |
185 | 196 | .insns = { |
186 | | - BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8), |
187 | | - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), |
188 | | - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64), |
189 | | - BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_2, -128), |
190 | | - BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, -128), |
191 | | - BPF_JMP_IMM(BPF_JGT, BPF_REG_2, 64, 3), |
192 | | - BPF_MOV64_IMM(BPF_REG_3, 0), |
193 | | - BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel), |
| 197 | + /* set max stack size */ |
| 198 | + BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0), |
| 199 | + /* set r3 to a random value */ |
| 200 | + BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), |
| 201 | + BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), |
| 202 | + /* use JMP to limit r3 range to [0, 64] */ |
| 203 | + BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 64, 6), |
| 204 | + BPF_LD_MAP_FD(BPF_REG_1, 0), |
| 205 | + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| 206 | + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), |
| 207 | + BPF_MOV64_IMM(BPF_REG_4, 0), |
| 208 | + /* Call bpf_ringbuf_output(), it is one of a few helper functions with |
| 209 | + * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode. |
| 210 | + * For unpriv this should signal an error, because memory at &fp[-64] is |
| 211 | + * not initialized. |
| 212 | + */ |
| 213 | + BPF_EMIT_CALL(BPF_FUNC_ringbuf_output), |
194 | 214 | BPF_MOV64_IMM(BPF_REG_0, 0), |
195 | 215 | BPF_EXIT_INSN(), |
196 | 216 | }, |
197 | | - .errstr = "invalid indirect read from stack R1 off -64+0 size 64", |
198 | | - .result = REJECT, |
199 | | - .prog_type = BPF_PROG_TYPE_TRACEPOINT, |
| 217 | + .fixup_map_ringbuf = { 4 }, |
| 218 | + .errstr_unpriv = "invalid indirect read from stack R2 off -64+0 size 64", |
| 219 | + .result_unpriv = REJECT, |
| 220 | + /* in privileged mode reads from uninitialized stack locations are permitted */ |
| 221 | + .result = ACCEPT, |
200 | 222 | }, |
201 | 223 | { |
202 | 224 | "helper access to variable memory: stack, JMP (signed), no min check", |
|
564 | 586 | { |
565 | 587 | "helper access to variable memory: 8 bytes leak", |
566 | 588 | .insns = { |
567 | | - BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 8), |
568 | | - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), |
569 | | - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -64), |
| 589 | + /* set max stack size */ |
| 590 | + BPF_ST_MEM(BPF_DW, BPF_REG_10, -128, 0), |
| 591 | + /* set r3 to a random value */ |
| 592 | + BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32), |
| 593 | + BPF_MOV64_REG(BPF_REG_3, BPF_REG_0), |
| 594 | + BPF_LD_MAP_FD(BPF_REG_1, 0), |
| 595 | + BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| 596 | + BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -64), |
570 | 597 | BPF_MOV64_IMM(BPF_REG_0, 0), |
571 | 598 | BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -64), |
572 | 599 | BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -56), |
573 | 600 | BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -48), |
574 | 601 | BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -40), |
| 602 | + /* Note: fp[-32] left uninitialized */ |
575 | 603 | BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -24), |
576 | 604 | BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -16), |
577 | 605 | BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_0, -8), |
578 | | - BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_2, -128), |
579 | | - BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_10, -128), |
580 | | - BPF_ALU64_IMM(BPF_AND, BPF_REG_2, 63), |
581 | | - BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, 1), |
582 | | - BPF_MOV64_IMM(BPF_REG_3, 0), |
583 | | - BPF_EMIT_CALL(BPF_FUNC_probe_read_kernel), |
584 | | - BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -16), |
| 606 | + /* Limit r3 range to [1, 64] */ |
| 607 | + BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 63), |
| 608 | + BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 1), |
| 609 | + BPF_MOV64_IMM(BPF_REG_4, 0), |
| 610 | + /* Call bpf_ringbuf_output(), it is one of a few helper functions with |
| 611 | + * ARG_CONST_SIZE_OR_ZERO parameter allowed in unpriv mode. |
| 612 | + * For unpriv this should signal an error, because memory region [1, 64] |
| 613 | + * at &fp[-64] is not fully initialized. |
| 614 | + */ |
| 615 | + BPF_EMIT_CALL(BPF_FUNC_ringbuf_output), |
| 616 | + BPF_MOV64_IMM(BPF_REG_0, 0), |
585 | 617 | BPF_EXIT_INSN(), |
586 | 618 | }, |
587 | | - .errstr = "invalid indirect read from stack R1 off -64+32 size 64", |
588 | | - .result = REJECT, |
589 | | - .prog_type = BPF_PROG_TYPE_TRACEPOINT, |
| 619 | + .fixup_map_ringbuf = { 3 }, |
| 620 | + .errstr_unpriv = "invalid indirect read from stack R2 off -64+32 size 64", |
| 621 | + .result_unpriv = REJECT, |
| 622 | + /* in privileged mode reads from uninitialized stack locations are permitted */ |
| 623 | + .result = ACCEPT, |
590 | 624 | }, |
591 | 625 | { |
592 | 626 | "helper access to variable memory: 8 bytes no leak (init memory)", |
|
0 commit comments