Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Test ARG_PTR_TO_LONG arg type

Test that verifier handles new argument types properly, including
uninitialized or partially initialized value, misaligned stack access,
etc.

Example of output:
#456/p ARG_PTR_TO_LONG uninitialized OK
#457/p ARG_PTR_TO_LONG half-uninitialized OK
#458/p ARG_PTR_TO_LONG misaligned OK
#459/p ARG_PTR_TO_LONG size < sizeof(long) OK
#460/p ARG_PTR_TO_LONG initialized OK

Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Andrey Ignatov and committed by
Alexei Starovoitov
c2d5f12e 99f57973

+160
+160
tools/testing/selftests/bpf/verifier/int_ptr.c
··· 1 + { 2 + "ARG_PTR_TO_LONG uninitialized", 3 + .insns = { 4 + /* bpf_strtoul arg1 (buf) */ 5 + BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), 6 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), 7 + BPF_MOV64_IMM(BPF_REG_0, 0x00303036), 8 + BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 9 + 10 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 11 + 12 + /* bpf_strtoul arg2 (buf_len) */ 13 + BPF_MOV64_IMM(BPF_REG_2, 4), 14 + 15 + /* bpf_strtoul arg3 (flags) */ 16 + BPF_MOV64_IMM(BPF_REG_3, 0), 17 + 18 + /* bpf_strtoul arg4 (res) */ 19 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), 20 + BPF_MOV64_REG(BPF_REG_4, BPF_REG_7), 21 + 22 + /* bpf_strtoul() */ 23 + BPF_EMIT_CALL(BPF_FUNC_strtoul), 24 + 25 + BPF_MOV64_IMM(BPF_REG_0, 1), 26 + BPF_EXIT_INSN(), 27 + }, 28 + .result = REJECT, 29 + .prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL, 30 + .errstr = "invalid indirect read from stack off -16+0 size 8", 31 + }, 32 + { 33 + "ARG_PTR_TO_LONG half-uninitialized", 34 + .insns = { 35 + /* bpf_strtoul arg1 (buf) */ 36 + BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), 37 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), 38 + BPF_MOV64_IMM(BPF_REG_0, 0x00303036), 39 + BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 40 + 41 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 42 + 43 + /* bpf_strtoul arg2 (buf_len) */ 44 + BPF_MOV64_IMM(BPF_REG_2, 4), 45 + 46 + /* bpf_strtoul arg3 (flags) */ 47 + BPF_MOV64_IMM(BPF_REG_3, 0), 48 + 49 + /* bpf_strtoul arg4 (res) */ 50 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), 51 + BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0), 52 + BPF_MOV64_REG(BPF_REG_4, BPF_REG_7), 53 + 54 + /* bpf_strtoul() */ 55 + BPF_EMIT_CALL(BPF_FUNC_strtoul), 56 + 57 + BPF_MOV64_IMM(BPF_REG_0, 1), 58 + BPF_EXIT_INSN(), 59 + }, 60 + .result = REJECT, 61 + .prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL, 62 + .errstr = "invalid indirect read from stack off -16+4 size 8", 63 + }, 64 + { 65 + "ARG_PTR_TO_LONG misaligned", 66 + .insns = { 67 + /* bpf_strtoul arg1 (buf) */ 68 + BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), 69 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), 70 + BPF_MOV64_IMM(BPF_REG_0, 0x00303036), 71 + BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 72 + 73 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 74 + 75 + /* bpf_strtoul arg2 (buf_len) */ 76 + BPF_MOV64_IMM(BPF_REG_2, 4), 77 + 78 + /* bpf_strtoul arg3 (flags) */ 79 + BPF_MOV64_IMM(BPF_REG_3, 0), 80 + 81 + /* bpf_strtoul arg4 (res) */ 82 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -12), 83 + BPF_MOV64_IMM(BPF_REG_0, 0), 84 + BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0), 85 + BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 4), 86 + BPF_MOV64_REG(BPF_REG_4, BPF_REG_7), 87 + 88 + /* bpf_strtoul() */ 89 + BPF_EMIT_CALL(BPF_FUNC_strtoul), 90 + 91 + BPF_MOV64_IMM(BPF_REG_0, 1), 92 + BPF_EXIT_INSN(), 93 + }, 94 + .result = REJECT, 95 + .prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL, 96 + .errstr = "misaligned stack access off (0x0; 0x0)+-20+0 size 8", 97 + }, 98 + { 99 + "ARG_PTR_TO_LONG size < sizeof(long)", 100 + .insns = { 101 + /* bpf_strtoul arg1 (buf) */ 102 + BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), 103 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16), 104 + BPF_MOV64_IMM(BPF_REG_0, 0x00303036), 105 + BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 106 + 107 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 108 + 109 + /* bpf_strtoul arg2 (buf_len) */ 110 + BPF_MOV64_IMM(BPF_REG_2, 4), 111 + 112 + /* bpf_strtoul arg3 (flags) */ 113 + BPF_MOV64_IMM(BPF_REG_3, 0), 114 + 115 + /* bpf_strtoul arg4 (res) */ 116 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 12), 117 + BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0), 118 + BPF_MOV64_REG(BPF_REG_4, BPF_REG_7), 119 + 120 + /* bpf_strtoul() */ 121 + BPF_EMIT_CALL(BPF_FUNC_strtoul), 122 + 123 + BPF_MOV64_IMM(BPF_REG_0, 1), 124 + BPF_EXIT_INSN(), 125 + }, 126 + .result = REJECT, 127 + .prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL, 128 + .errstr = "invalid stack type R4 off=-4 access_size=8", 129 + }, 130 + { 131 + "ARG_PTR_TO_LONG initialized", 132 + .insns = { 133 + /* bpf_strtoul arg1 (buf) */ 134 + BPF_MOV64_REG(BPF_REG_7, BPF_REG_10), 135 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), 136 + BPF_MOV64_IMM(BPF_REG_0, 0x00303036), 137 + BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 138 + 139 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_7), 140 + 141 + /* bpf_strtoul arg2 (buf_len) */ 142 + BPF_MOV64_IMM(BPF_REG_2, 4), 143 + 144 + /* bpf_strtoul arg3 (flags) */ 145 + BPF_MOV64_IMM(BPF_REG_3, 0), 146 + 147 + /* bpf_strtoul arg4 (res) */ 148 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8), 149 + BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0), 150 + BPF_MOV64_REG(BPF_REG_4, BPF_REG_7), 151 + 152 + /* bpf_strtoul() */ 153 + BPF_EMIT_CALL(BPF_FUNC_strtoul), 154 + 155 + BPF_MOV64_IMM(BPF_REG_0, 1), 156 + BPF_EXIT_INSN(), 157 + }, 158 + .result = ACCEPT, 159 + .prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL, 160 + },