0001 {
0002 "valid map access into an array with a constant",
0003 .insns = {
0004 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0005 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0006 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0007 BPF_LD_MAP_FD(BPF_REG_1, 0),
0008 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0009 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0010 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
0011 BPF_EXIT_INSN(),
0012 },
0013 .fixup_map_hash_48b = { 3 },
0014 .errstr_unpriv = "R0 leaks addr",
0015 .result_unpriv = REJECT,
0016 .result = ACCEPT,
0017 },
0018 {
0019 "valid map access into an array with a register",
0020 .insns = {
0021 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0022 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0023 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0024 BPF_LD_MAP_FD(BPF_REG_1, 0),
0025 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0026 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0027 BPF_MOV64_IMM(BPF_REG_1, 4),
0028 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
0029 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0030 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
0031 BPF_EXIT_INSN(),
0032 },
0033 .fixup_map_hash_48b = { 3 },
0034 .errstr_unpriv = "R0 leaks addr",
0035 .result_unpriv = REJECT,
0036 .result = ACCEPT,
0037 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0038 },
0039 {
0040 "valid map access into an array with a variable",
0041 .insns = {
0042 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0043 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0044 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0045 BPF_LD_MAP_FD(BPF_REG_1, 0),
0046 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0047 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
0048 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
0049 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, MAX_ENTRIES, 3),
0050 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
0051 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0052 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
0053 BPF_EXIT_INSN(),
0054 },
0055 .fixup_map_hash_48b = { 3 },
0056 .errstr_unpriv = "R0 leaks addr",
0057 .result_unpriv = REJECT,
0058 .result = ACCEPT,
0059 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0060 },
0061 {
0062 "valid map access into an array with a signed variable",
0063 .insns = {
0064 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0065 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0066 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0067 BPF_LD_MAP_FD(BPF_REG_1, 0),
0068 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0069 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
0070 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
0071 BPF_JMP32_IMM(BPF_JSGT, BPF_REG_1, 0xffffffff, 1),
0072 BPF_MOV32_IMM(BPF_REG_1, 0),
0073 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
0074 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
0075 BPF_MOV32_IMM(BPF_REG_1, 0),
0076 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
0077 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0078 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
0079 BPF_EXIT_INSN(),
0080 },
0081 .fixup_map_hash_48b = { 3 },
0082 .errstr_unpriv = "R0 leaks addr",
0083 .result_unpriv = REJECT,
0084 .result = ACCEPT,
0085 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0086 },
0087 {
0088 "invalid map access into an array with a constant",
0089 .insns = {
0090 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0091 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0092 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0093 BPF_LD_MAP_FD(BPF_REG_1, 0),
0094 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0095 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0096 BPF_ST_MEM(BPF_DW, BPF_REG_0, (MAX_ENTRIES + 1) << 2,
0097 offsetof(struct test_val, foo)),
0098 BPF_EXIT_INSN(),
0099 },
0100 .fixup_map_hash_48b = { 3 },
0101 .errstr = "invalid access to map value, value_size=48 off=48 size=8",
0102 .result = REJECT,
0103 },
0104 {
0105 "invalid map access into an array with a register",
0106 .insns = {
0107 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0108 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0109 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0110 BPF_LD_MAP_FD(BPF_REG_1, 0),
0111 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0112 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0113 BPF_MOV64_IMM(BPF_REG_1, MAX_ENTRIES + 1),
0114 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
0115 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0116 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
0117 BPF_EXIT_INSN(),
0118 },
0119 .fixup_map_hash_48b = { 3 },
0120 .errstr = "R0 min value is outside of the allowed memory range",
0121 .result = REJECT,
0122 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0123 },
0124 {
0125 "invalid map access into an array with a variable",
0126 .insns = {
0127 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0128 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0129 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0130 BPF_LD_MAP_FD(BPF_REG_1, 0),
0131 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0132 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0133 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
0134 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 2),
0135 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0136 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
0137 BPF_EXIT_INSN(),
0138 },
0139 .fixup_map_hash_48b = { 3 },
0140 .errstr = "R0 unbounded memory access, make sure to bounds check any such access",
0141 .result = REJECT,
0142 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0143 },
0144 {
0145 "invalid map access into an array with no floor check",
0146 .insns = {
0147 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0148 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0149 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0150 BPF_LD_MAP_FD(BPF_REG_1, 0),
0151 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0152 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
0153 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
0154 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
0155 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
0156 BPF_MOV32_IMM(BPF_REG_1, 0),
0157 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
0158 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0159 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
0160 BPF_EXIT_INSN(),
0161 },
0162 .fixup_map_hash_48b = { 3 },
0163 .errstr_unpriv = "R0 leaks addr",
0164 .errstr = "R0 unbounded memory access",
0165 .result_unpriv = REJECT,
0166 .result = REJECT,
0167 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0168 },
0169 {
0170 "invalid map access into an array with a invalid max check",
0171 .insns = {
0172 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0173 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0174 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0175 BPF_LD_MAP_FD(BPF_REG_1, 0),
0176 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0177 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7),
0178 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
0179 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES + 1),
0180 BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_1, 1),
0181 BPF_MOV32_IMM(BPF_REG_1, 0),
0182 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
0183 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0184 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
0185 BPF_EXIT_INSN(),
0186 },
0187 .fixup_map_hash_48b = { 3 },
0188 .errstr_unpriv = "R0 leaks addr",
0189 .errstr = "invalid access to map value, value_size=48 off=44 size=8",
0190 .result_unpriv = REJECT,
0191 .result = REJECT,
0192 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0193 },
0194 {
0195 "invalid map access into an array with a invalid max check",
0196 .insns = {
0197 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0198 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0199 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0200 BPF_LD_MAP_FD(BPF_REG_1, 0),
0201 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0202 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 10),
0203 BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
0204 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0205 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0206 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0207 BPF_LD_MAP_FD(BPF_REG_1, 0),
0208 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0209 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
0210 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
0211 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0,
0212 offsetof(struct test_val, foo)),
0213 BPF_EXIT_INSN(),
0214 },
0215 .fixup_map_hash_48b = { 3, 11 },
0216 .errstr = "R0 pointer += pointer",
0217 .result = REJECT,
0218 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0219 },
0220 {
0221 "valid read map access into a read-only array 1",
0222 .insns = {
0223 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0224 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0225 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0226 BPF_LD_MAP_FD(BPF_REG_1, 0),
0227 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0228 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0229 BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0),
0230 BPF_EXIT_INSN(),
0231 },
0232 .fixup_map_array_ro = { 3 },
0233 .result = ACCEPT,
0234 .retval = 28,
0235 },
0236 {
0237 "valid read map access into a read-only array 2",
0238 .insns = {
0239 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0240 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0241 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0242 BPF_LD_MAP_FD(BPF_REG_1, 0),
0243 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0244 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
0245
0246 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0247 BPF_MOV64_IMM(BPF_REG_2, 4),
0248 BPF_MOV64_IMM(BPF_REG_3, 0),
0249 BPF_MOV64_IMM(BPF_REG_4, 0),
0250 BPF_MOV64_IMM(BPF_REG_5, 0),
0251 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0252 BPF_FUNC_csum_diff),
0253 BPF_ALU64_IMM(BPF_AND, BPF_REG_0, 0xffff),
0254 BPF_EXIT_INSN(),
0255 },
0256 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0257 .fixup_map_array_ro = { 3 },
0258 .result = ACCEPT,
0259 .retval = 65507,
0260 },
0261 {
0262 "invalid write map access into a read-only array 1",
0263 .insns = {
0264 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0265 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0266 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0267 BPF_LD_MAP_FD(BPF_REG_1, 0),
0268 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0269 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0270 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
0271 BPF_EXIT_INSN(),
0272 },
0273 .fixup_map_array_ro = { 3 },
0274 .result = REJECT,
0275 .errstr = "write into map forbidden",
0276 },
0277 {
0278 "invalid write map access into a read-only array 2",
0279 .insns = {
0280 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
0281 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0282 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0283 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0284 BPF_LD_MAP_FD(BPF_REG_1, 0),
0285 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0286 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
0287 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0288 BPF_MOV64_IMM(BPF_REG_2, 0),
0289 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
0290 BPF_MOV64_IMM(BPF_REG_4, 8),
0291 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0292 BPF_FUNC_skb_load_bytes),
0293 BPF_EXIT_INSN(),
0294 },
0295 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0296 .fixup_map_array_ro = { 4 },
0297 .result = REJECT,
0298 .errstr = "write into map forbidden",
0299 },
0300 {
0301 "valid write map access into a write-only array 1",
0302 .insns = {
0303 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0304 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0305 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0306 BPF_LD_MAP_FD(BPF_REG_1, 0),
0307 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0308 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0309 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, 42),
0310 BPF_MOV64_IMM(BPF_REG_0, 1),
0311 BPF_EXIT_INSN(),
0312 },
0313 .fixup_map_array_wo = { 3 },
0314 .result = ACCEPT,
0315 .retval = 1,
0316 },
0317 {
0318 "valid write map access into a write-only array 2",
0319 .insns = {
0320 BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
0321 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0322 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0323 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0324 BPF_LD_MAP_FD(BPF_REG_1, 0),
0325 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0326 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
0327 BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
0328 BPF_MOV64_IMM(BPF_REG_2, 0),
0329 BPF_MOV64_REG(BPF_REG_3, BPF_REG_0),
0330 BPF_MOV64_IMM(BPF_REG_4, 8),
0331 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0332 BPF_FUNC_skb_load_bytes),
0333 BPF_EXIT_INSN(),
0334 },
0335 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0336 .fixup_map_array_wo = { 4 },
0337 .result = ACCEPT,
0338 .retval = 0,
0339 },
0340 {
0341 "invalid read map access into a write-only array 1",
0342 .insns = {
0343 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0344 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0345 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0346 BPF_LD_MAP_FD(BPF_REG_1, 0),
0347 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0348 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
0349 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
0350 BPF_EXIT_INSN(),
0351 },
0352 .fixup_map_array_wo = { 3 },
0353 .result = REJECT,
0354 .errstr = "read from map forbidden",
0355 },
0356 {
0357 "invalid read map access into a write-only array 2",
0358 .insns = {
0359 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0360 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0361 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0362 BPF_LD_MAP_FD(BPF_REG_1, 0),
0363 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0364 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
0365
0366 BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
0367 BPF_MOV64_IMM(BPF_REG_2, 4),
0368 BPF_MOV64_IMM(BPF_REG_3, 0),
0369 BPF_MOV64_IMM(BPF_REG_4, 0),
0370 BPF_MOV64_IMM(BPF_REG_5, 0),
0371 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
0372 BPF_FUNC_csum_diff),
0373 BPF_EXIT_INSN(),
0374 },
0375 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0376 .fixup_map_array_wo = { 3 },
0377 .result = REJECT,
0378 .errstr = "read from map forbidden",
0379 },