1 { 2 "BPF_ATOMIC_FETCH_ADD smoketest - 64bit", 3 .insns = { 4 BPF_MOV64_IMM(BPF_REG_0, 0), 5 /* Write 3 to stack */ 6 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 3), 7 /* Put a 1 in R1, add it to the 3 on the stack, and load the value back into R1 */ 8 BPF_MOV64_IMM(BPF_REG_1, 1), 9 BPF_ATOMIC_OP(BPF_DW, BPF_ADD | BPF_FETCH, BPF_REG_10, BPF_REG_1, -8), 10 /* Check the value we loaded back was 3 */ 11 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2), 12 BPF_MOV64_IMM(BPF_REG_0, 1), 13 BPF_EXIT_INSN(), 14 /* Load value from stack */ 15 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_10, -8), 16 /* Check value loaded from stack was 4 */ 17 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1), 18 BPF_MOV64_IMM(BPF_REG_0, 2), 19 BPF_EXIT_INSN(), 20 }, 21 .result = ACCEPT, 22 }, 23 { 24 "BPF_ATOMIC_FETCH_ADD smoketest - 32bit", 25 .insns = { 26 BPF_MOV64_IMM(BPF_REG_0, 0), 27 /* Write 3 to stack */ 28 BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 3), 29 /* Put a 1 in R1, add it to the 3 on the stack, and load the value back into R1 */ 30 BPF_MOV32_IMM(BPF_REG_1, 1), 31 BPF_ATOMIC_OP(BPF_W, BPF_ADD | BPF_FETCH, BPF_REG_10, BPF_REG_1, -4), 32 /* Check the value we loaded back was 3 */ 33 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 3, 2), 34 BPF_MOV64_IMM(BPF_REG_0, 1), 35 BPF_EXIT_INSN(), 36 /* Load value from stack */ 37 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_10, -4), 38 /* Check value loaded from stack was 4 */ 39 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 4, 1), 40 BPF_MOV64_IMM(BPF_REG_0, 2), 41 BPF_EXIT_INSN(), 42 }, 43 .result = ACCEPT, 44 }, 45 { 46 "Can't use ATM_FETCH_ADD on frame pointer", 47 .insns = { 48 BPF_MOV64_IMM(BPF_REG_0, 0), 49 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 3), 50 BPF_ATOMIC_OP(BPF_DW, BPF_ADD | BPF_FETCH, BPF_REG_10, BPF_REG_10, -8), 51 BPF_EXIT_INSN(), 52 }, 53 .result = REJECT, 54 .errstr_unpriv = "R10 leaks addr into mem", 55 .errstr = "frame pointer is read only", 56 }, 57 { 58 "Can't use ATM_FETCH_ADD on uninit src reg", 59 .insns = { 60 BPF_MOV64_IMM(BPF_REG_0, 0), 61 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 3), 62 BPF_ATOMIC_OP(BPF_DW, BPF_ADD | BPF_FETCH, BPF_REG_10, BPF_REG_2, -8), 63 BPF_EXIT_INSN(), 64 }, 65 .result = REJECT, 66 /* It happens that the address leak check is first, but it would also be 67 * complain about the fact that we're trying to modify R10. 68 */ 69 .errstr = "!read_ok", 70 }, 71 { 72 "Can't use ATM_FETCH_ADD on uninit dst reg", 73 .insns = { 74 BPF_MOV64_IMM(BPF_REG_0, 0), 75 BPF_ATOMIC_OP(BPF_DW, BPF_ADD | BPF_FETCH, BPF_REG_2, BPF_REG_0, -8), 76 BPF_EXIT_INSN(), 77 }, 78 .result = REJECT, 79 /* It happens that the address leak check is first, but it would also be 80 * complain about the fact that we're trying to modify R10. 81 */ 82 .errstr = "!read_ok", 83 }, 84 { 85 "Can't use ATM_FETCH_ADD on kernel memory", 86 .insns = { 87 /* This is an fentry prog, context is array of the args of the 88 * kernel function being called. Load first arg into R2. 89 */ 90 BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1, 0), 91 /* First arg of bpf_fentry_test7 is a pointer to a struct. 92 * Attempt to modify that struct. Verifier shouldn't let us 93 * because it's kernel memory. 94 */ 95 BPF_MOV64_IMM(BPF_REG_3, 1), 96 BPF_ATOMIC_OP(BPF_DW, BPF_ADD | BPF_FETCH, BPF_REG_2, BPF_REG_3, 0), 97 /* Done */ 98 BPF_MOV64_IMM(BPF_REG_0, 0), 99 BPF_EXIT_INSN(), 100 }, 101 .prog_type = BPF_PROG_TYPE_TRACING, 102 .expected_attach_type = BPF_TRACE_FENTRY, 103 .kfunc = "bpf_fentry_test7", 104 .result = REJECT, 105 .errstr = "only read is supported", 106 }, 107