0001 {
0002 "subtraction bounds (map value) variant 1",
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, 9),
0010 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
0011 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 7),
0012 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
0013 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 5),
0014 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
0015 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 56),
0016 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0017 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
0018 BPF_EXIT_INSN(),
0019 BPF_MOV64_IMM(BPF_REG_0, 0),
0020 BPF_EXIT_INSN(),
0021 },
0022 .fixup_map_hash_8b = { 3 },
0023 .errstr = "R0 max value is outside of the allowed memory range",
0024 .result = REJECT,
0025 },
0026 {
0027 "subtraction bounds (map value) variant 2",
0028 .insns = {
0029 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0030 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0031 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0032 BPF_LD_MAP_FD(BPF_REG_1, 0),
0033 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0034 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
0035 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
0036 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0xff, 6),
0037 BPF_LDX_MEM(BPF_B, BPF_REG_3, BPF_REG_0, 1),
0038 BPF_JMP_IMM(BPF_JGT, BPF_REG_3, 0xff, 4),
0039 BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_3),
0040 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0041 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
0042 BPF_EXIT_INSN(),
0043 BPF_MOV64_IMM(BPF_REG_0, 0),
0044 BPF_EXIT_INSN(),
0045 },
0046 .fixup_map_hash_8b = { 3 },
0047 .errstr = "R0 min value is negative, either use unsigned index or do a if (index >=0) check.",
0048 .errstr_unpriv = "R1 has unknown scalar with mixed signed bounds",
0049 .result = REJECT,
0050 },
0051 {
0052 "check subtraction on pointers for unpriv",
0053 .insns = {
0054 BPF_MOV64_IMM(BPF_REG_0, 0),
0055 BPF_LD_MAP_FD(BPF_REG_ARG1, 0),
0056 BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
0057 BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -8),
0058 BPF_ST_MEM(BPF_DW, BPF_REG_ARG2, 0, 9),
0059 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0060 BPF_MOV64_REG(BPF_REG_9, BPF_REG_FP),
0061 BPF_ALU64_REG(BPF_SUB, BPF_REG_9, BPF_REG_0),
0062 BPF_LD_MAP_FD(BPF_REG_ARG1, 0),
0063 BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP),
0064 BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -8),
0065 BPF_ST_MEM(BPF_DW, BPF_REG_ARG2, 0, 0),
0066 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0067 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0068 BPF_EXIT_INSN(),
0069 BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_9, 0),
0070 BPF_MOV64_IMM(BPF_REG_0, 0),
0071 BPF_EXIT_INSN(),
0072 },
0073 .fixup_map_hash_8b = { 1, 9 },
0074 .result = ACCEPT,
0075 .result_unpriv = REJECT,
0076 .errstr_unpriv = "R9 pointer -= pointer prohibited",
0077 },
0078 {
0079 "bounds check based on zero-extended MOV",
0080 .insns = {
0081 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0082 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0083 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0084 BPF_LD_MAP_FD(BPF_REG_1, 0),
0085 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0086 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0087
0088 BPF_MOV32_IMM(BPF_REG_2, 0xffffffff),
0089
0090 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
0091
0092 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
0093
0094 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
0095
0096 BPF_MOV64_IMM(BPF_REG_0, 0),
0097 BPF_EXIT_INSN(),
0098 },
0099 .fixup_map_hash_8b = { 3 },
0100 .result = ACCEPT
0101 },
0102 {
0103 "bounds check based on sign-extended MOV. test1",
0104 .insns = {
0105 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0106 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0107 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0108 BPF_LD_MAP_FD(BPF_REG_1, 0),
0109 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0110 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0111
0112 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
0113
0114 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 32),
0115
0116 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
0117
0118 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
0119
0120 BPF_MOV64_IMM(BPF_REG_0, 0),
0121 BPF_EXIT_INSN(),
0122 },
0123 .fixup_map_hash_8b = { 3 },
0124 .errstr = "map_value pointer and 4294967295",
0125 .result = REJECT
0126 },
0127 {
0128 "bounds check based on sign-extended MOV. test2",
0129 .insns = {
0130 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0131 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0132 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0133 BPF_LD_MAP_FD(BPF_REG_1, 0),
0134 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0135 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0136
0137 BPF_MOV64_IMM(BPF_REG_2, 0xffffffff),
0138
0139 BPF_ALU64_IMM(BPF_RSH, BPF_REG_2, 36),
0140
0141 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_2),
0142
0143 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
0144
0145 BPF_MOV64_IMM(BPF_REG_0, 0),
0146 BPF_EXIT_INSN(),
0147 },
0148 .fixup_map_hash_8b = { 3 },
0149 .errstr = "R0 min value is outside of the allowed memory range",
0150 .result = REJECT
0151 },
0152 {
0153 "bounds check based on reg_off + var_off + insn_off. test1",
0154 .insns = {
0155 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
0156 offsetof(struct __sk_buff, mark)),
0157 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0158 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0159 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0160 BPF_LD_MAP_FD(BPF_REG_1, 0),
0161 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0162 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0163 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
0164 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 29) - 1),
0165 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
0166 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
0167 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
0168 BPF_MOV64_IMM(BPF_REG_0, 0),
0169 BPF_EXIT_INSN(),
0170 },
0171 .fixup_map_hash_8b = { 4 },
0172 .errstr = "value_size=8 off=1073741825",
0173 .result = REJECT,
0174 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0175 },
0176 {
0177 "bounds check based on reg_off + var_off + insn_off. test2",
0178 .insns = {
0179 BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1,
0180 offsetof(struct __sk_buff, mark)),
0181 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0182 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0183 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0184 BPF_LD_MAP_FD(BPF_REG_1, 0),
0185 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0186 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0187 BPF_ALU64_IMM(BPF_AND, BPF_REG_6, 1),
0188 BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, (1 << 30) - 1),
0189 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_6),
0190 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, (1 << 29) - 1),
0191 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 3),
0192 BPF_MOV64_IMM(BPF_REG_0, 0),
0193 BPF_EXIT_INSN(),
0194 },
0195 .fixup_map_hash_8b = { 4 },
0196 .errstr = "value 1073741823",
0197 .result = REJECT,
0198 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0199 },
0200 {
0201 "bounds check after truncation of non-boundary-crossing range",
0202 .insns = {
0203 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0204 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0205 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0206 BPF_LD_MAP_FD(BPF_REG_1, 0),
0207 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0208 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9),
0209
0210 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
0211 BPF_MOV64_IMM(BPF_REG_2, 1),
0212
0213 BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 36),
0214
0215 BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_2),
0216
0217 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
0218
0219 BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 0x7fffffff),
0220
0221 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
0222
0223 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0224
0225 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
0226
0227 BPF_MOV64_IMM(BPF_REG_0, 0),
0228 BPF_EXIT_INSN(),
0229 },
0230 .fixup_map_hash_8b = { 3 },
0231 .result = ACCEPT
0232 },
0233 {
0234 "bounds check after truncation of boundary-crossing range (1)",
0235 .insns = {
0236 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0237 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0238 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0239 BPF_LD_MAP_FD(BPF_REG_1, 0),
0240 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0241 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
0242
0243 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
0244 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
0245
0246 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
0247
0248
0249
0250 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 0),
0251 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
0252
0253
0254
0255 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
0256
0257 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0258
0259 BPF_MOV64_IMM(BPF_REG_0, 0),
0260 BPF_EXIT_INSN(),
0261 },
0262 .fixup_map_hash_8b = { 3 },
0263
0264 .errstr = "value -4294967168 makes map_value pointer be out of bounds",
0265 .result = REJECT,
0266 },
0267 {
0268 "bounds check after truncation of boundary-crossing range (2)",
0269 .insns = {
0270 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0271 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0272 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0273 BPF_LD_MAP_FD(BPF_REG_1, 0),
0274 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0275 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
0276
0277 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
0278 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
0279
0280 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0xffffff80 >> 1),
0281
0282
0283
0284
0285
0286 BPF_MOV32_REG(BPF_REG_1, BPF_REG_1),
0287 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
0288
0289
0290
0291 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 0xffffff80 >> 1),
0292
0293 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0294
0295 BPF_MOV64_IMM(BPF_REG_0, 0),
0296 BPF_EXIT_INSN(),
0297 },
0298 .fixup_map_hash_8b = { 3 },
0299 .errstr = "value -4294967168 makes map_value pointer be out of bounds",
0300 .result = REJECT,
0301 },
0302 {
0303 "bounds check after wrapping 32-bit addition",
0304 .insns = {
0305 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0306 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0307 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0308 BPF_LD_MAP_FD(BPF_REG_1, 0),
0309 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0310 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
0311
0312 BPF_MOV64_IMM(BPF_REG_1, 0x7fffffff),
0313
0314 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 0x7fffffff),
0315
0316 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 2),
0317
0318 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0319
0320 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
0321
0322 BPF_MOV64_IMM(BPF_REG_0, 0),
0323 BPF_EXIT_INSN(),
0324 },
0325 .fixup_map_hash_8b = { 3 },
0326 .result = ACCEPT
0327 },
0328 {
0329 "bounds check after shift with oversized count operand",
0330 .insns = {
0331 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0332 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0333 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0334 BPF_LD_MAP_FD(BPF_REG_1, 0),
0335 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0336 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
0337 BPF_MOV64_IMM(BPF_REG_2, 32),
0338 BPF_MOV64_IMM(BPF_REG_1, 1),
0339
0340 BPF_ALU32_REG(BPF_LSH, BPF_REG_1, BPF_REG_2),
0341
0342 BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xffff),
0343
0344 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0345
0346 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
0347
0348 BPF_MOV64_IMM(BPF_REG_0, 0),
0349 BPF_EXIT_INSN(),
0350 },
0351 .fixup_map_hash_8b = { 3 },
0352 .errstr = "R0 max value is outside of the allowed memory range",
0353 .result = REJECT
0354 },
0355 {
0356 "bounds check after right shift of maybe-negative number",
0357 .insns = {
0358 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0359 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0360 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0361 BPF_LD_MAP_FD(BPF_REG_1, 0),
0362 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0363 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
0364
0365 BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0),
0366
0367 BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
0368
0369 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
0370
0371 BPF_ALU64_IMM(BPF_RSH, BPF_REG_1, 8),
0372
0373 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0374
0375 BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0),
0376
0377 BPF_MOV64_IMM(BPF_REG_0, 0),
0378 BPF_EXIT_INSN(),
0379 },
0380 .fixup_map_hash_8b = { 3 },
0381 .errstr = "R0 unbounded memory access",
0382 .result = REJECT
0383 },
0384 {
0385 "bounds check after 32-bit right shift with 64-bit input",
0386 .insns = {
0387 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0388 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0389 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0390 BPF_LD_MAP_FD(BPF_REG_1, 0),
0391 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0392 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6),
0393
0394 BPF_MOV64_IMM(BPF_REG_1, 2),
0395
0396 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 31),
0397
0398 BPF_ALU32_IMM(BPF_RSH, BPF_REG_1, 31),
0399
0400 BPF_ALU32_IMM(BPF_SUB, BPF_REG_1, 2),
0401
0402 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0403
0404 BPF_MOV64_IMM(BPF_REG_0, 0),
0405 BPF_EXIT_INSN(),
0406 },
0407 .fixup_map_hash_8b = { 3 },
0408 .errstr = "math between map_value pointer and 4294967294 is not allowed",
0409 .result = REJECT,
0410 },
0411 {
0412 "bounds check map access with off+size signed 32bit overflow. test1",
0413 .insns = {
0414 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0415 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0416 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0417 BPF_LD_MAP_FD(BPF_REG_1, 0),
0418 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0419 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0420 BPF_EXIT_INSN(),
0421 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x7ffffffe),
0422 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
0423 BPF_JMP_A(0),
0424 BPF_EXIT_INSN(),
0425 },
0426 .fixup_map_hash_8b = { 3 },
0427 .errstr = "map_value pointer and 2147483646",
0428 .result = REJECT
0429 },
0430 {
0431 "bounds check map access with off+size signed 32bit overflow. test2",
0432 .insns = {
0433 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0434 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0435 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0436 BPF_LD_MAP_FD(BPF_REG_1, 0),
0437 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0438 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0439 BPF_EXIT_INSN(),
0440 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
0441 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
0442 BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 0x1fffffff),
0443 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
0444 BPF_JMP_A(0),
0445 BPF_EXIT_INSN(),
0446 },
0447 .fixup_map_hash_8b = { 3 },
0448 .errstr = "pointer offset 1073741822",
0449 .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
0450 .result = REJECT
0451 },
0452 {
0453 "bounds check map access with off+size signed 32bit overflow. test3",
0454 .insns = {
0455 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0456 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0457 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0458 BPF_LD_MAP_FD(BPF_REG_1, 0),
0459 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0460 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0461 BPF_EXIT_INSN(),
0462 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
0463 BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 0x1fffffff),
0464 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
0465 BPF_JMP_A(0),
0466 BPF_EXIT_INSN(),
0467 },
0468 .fixup_map_hash_8b = { 3 },
0469 .errstr = "pointer offset -1073741822",
0470 .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range",
0471 .result = REJECT
0472 },
0473 {
0474 "bounds check map access with off+size signed 32bit overflow. test4",
0475 .insns = {
0476 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0477 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0478 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0479 BPF_LD_MAP_FD(BPF_REG_1, 0),
0480 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0481 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0482 BPF_EXIT_INSN(),
0483 BPF_MOV64_IMM(BPF_REG_1, 1000000),
0484 BPF_ALU64_IMM(BPF_MUL, BPF_REG_1, 1000000),
0485 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
0486 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 2),
0487 BPF_JMP_A(0),
0488 BPF_EXIT_INSN(),
0489 },
0490 .fixup_map_hash_8b = { 3 },
0491 .errstr = "map_value pointer and 1000000000000",
0492 .result = REJECT
0493 },
0494 {
0495 "bounds check mixed 32bit and 64bit arithmetic. test1",
0496 .insns = {
0497 BPF_MOV64_IMM(BPF_REG_0, 0),
0498 BPF_MOV64_IMM(BPF_REG_1, -1),
0499 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
0500 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
0501
0502 BPF_JMP32_IMM(BPF_JGT, BPF_REG_1, 1, 3),
0503
0504 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
0505 BPF_JMP32_IMM(BPF_JGT, BPF_REG_1, 2, 1),
0506 BPF_JMP_A(1),
0507
0508 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1),
0509 BPF_EXIT_INSN(),
0510 },
0511 .errstr_unpriv = "R0 invalid mem access 'scalar'",
0512 .result_unpriv = REJECT,
0513 .result = ACCEPT
0514 },
0515 {
0516 "bounds check mixed 32bit and 64bit arithmetic. test2",
0517 .insns = {
0518 BPF_MOV64_IMM(BPF_REG_0, 0),
0519 BPF_MOV64_IMM(BPF_REG_1, -1),
0520 BPF_ALU64_IMM(BPF_LSH, BPF_REG_1, 32),
0521 BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 1),
0522
0523 BPF_MOV64_IMM(BPF_REG_2, 3),
0524
0525 BPF_ALU32_IMM(BPF_ADD, BPF_REG_1, 1),
0526
0527 BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_2, 1),
0528 BPF_JMP_A(1),
0529
0530 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, -1),
0531 BPF_EXIT_INSN(),
0532 },
0533 .errstr_unpriv = "R0 invalid mem access 'scalar'",
0534 .result_unpriv = REJECT,
0535 .result = ACCEPT
0536 },
0537 {
0538 "assigning 32bit bounds to 64bit for wA = 0, wB = wA",
0539 .insns = {
0540 BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1,
0541 offsetof(struct __sk_buff, data_end)),
0542 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
0543 offsetof(struct __sk_buff, data)),
0544 BPF_MOV32_IMM(BPF_REG_9, 0),
0545 BPF_MOV32_REG(BPF_REG_2, BPF_REG_9),
0546 BPF_MOV64_REG(BPF_REG_6, BPF_REG_7),
0547 BPF_ALU64_REG(BPF_ADD, BPF_REG_6, BPF_REG_2),
0548 BPF_MOV64_REG(BPF_REG_3, BPF_REG_6),
0549 BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8),
0550 BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_8, 1),
0551 BPF_LDX_MEM(BPF_W, BPF_REG_5, BPF_REG_6, 0),
0552 BPF_MOV64_IMM(BPF_REG_0, 0),
0553 BPF_EXIT_INSN(),
0554 },
0555 .prog_type = BPF_PROG_TYPE_SCHED_CLS,
0556 .result = ACCEPT,
0557 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
0558 },
0559 {
0560 "bounds check for reg = 0, reg xor 1",
0561 .insns = {
0562 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0563 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0564 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0565 BPF_LD_MAP_FD(BPF_REG_1, 0),
0566 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0567 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0568 BPF_EXIT_INSN(),
0569 BPF_MOV64_IMM(BPF_REG_1, 0),
0570 BPF_ALU64_IMM(BPF_XOR, BPF_REG_1, 1),
0571 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
0572 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
0573 BPF_MOV64_IMM(BPF_REG_0, 0),
0574 BPF_EXIT_INSN(),
0575 },
0576 .errstr_unpriv = "R0 min value is outside of the allowed memory range",
0577 .result_unpriv = REJECT,
0578 .fixup_map_hash_8b = { 3 },
0579 .result = ACCEPT,
0580 },
0581 {
0582 "bounds check for reg32 = 0, reg32 xor 1",
0583 .insns = {
0584 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0585 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0586 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0587 BPF_LD_MAP_FD(BPF_REG_1, 0),
0588 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0589 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0590 BPF_EXIT_INSN(),
0591 BPF_MOV32_IMM(BPF_REG_1, 0),
0592 BPF_ALU32_IMM(BPF_XOR, BPF_REG_1, 1),
0593 BPF_JMP32_IMM(BPF_JNE, BPF_REG_1, 0, 1),
0594 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
0595 BPF_MOV64_IMM(BPF_REG_0, 0),
0596 BPF_EXIT_INSN(),
0597 },
0598 .errstr_unpriv = "R0 min value is outside of the allowed memory range",
0599 .result_unpriv = REJECT,
0600 .fixup_map_hash_8b = { 3 },
0601 .result = ACCEPT,
0602 },
0603 {
0604 "bounds check for reg = 2, reg xor 3",
0605 .insns = {
0606 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0607 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0608 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0609 BPF_LD_MAP_FD(BPF_REG_1, 0),
0610 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0611 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0612 BPF_EXIT_INSN(),
0613 BPF_MOV64_IMM(BPF_REG_1, 2),
0614 BPF_ALU64_IMM(BPF_XOR, BPF_REG_1, 3),
0615 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0, 1),
0616 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
0617 BPF_MOV64_IMM(BPF_REG_0, 0),
0618 BPF_EXIT_INSN(),
0619 },
0620 .errstr_unpriv = "R0 min value is outside of the allowed memory range",
0621 .result_unpriv = REJECT,
0622 .fixup_map_hash_8b = { 3 },
0623 .result = ACCEPT,
0624 },
0625 {
0626 "bounds check for reg = any, reg xor 3",
0627 .insns = {
0628 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0629 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0630 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0631 BPF_LD_MAP_FD(BPF_REG_1, 0),
0632 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0633 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0634 BPF_EXIT_INSN(),
0635 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
0636 BPF_ALU64_IMM(BPF_XOR, BPF_REG_1, 3),
0637 BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
0638 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
0639 BPF_MOV64_IMM(BPF_REG_0, 0),
0640 BPF_EXIT_INSN(),
0641 },
0642 .fixup_map_hash_8b = { 3 },
0643 .result = REJECT,
0644 .errstr = "invalid access to map value",
0645 .errstr_unpriv = "invalid access to map value",
0646 },
0647 {
0648 "bounds check for reg32 = any, reg32 xor 3",
0649 .insns = {
0650 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0651 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0652 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0653 BPF_LD_MAP_FD(BPF_REG_1, 0),
0654 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0655 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0656 BPF_EXIT_INSN(),
0657 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
0658 BPF_ALU32_IMM(BPF_XOR, BPF_REG_1, 3),
0659 BPF_JMP32_IMM(BPF_JNE, BPF_REG_1, 0, 1),
0660 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
0661 BPF_MOV64_IMM(BPF_REG_0, 0),
0662 BPF_EXIT_INSN(),
0663 },
0664 .fixup_map_hash_8b = { 3 },
0665 .result = REJECT,
0666 .errstr = "invalid access to map value",
0667 .errstr_unpriv = "invalid access to map value",
0668 },
0669 {
0670 "bounds check for reg > 0, reg xor 3",
0671 .insns = {
0672 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0673 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0674 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0675 BPF_LD_MAP_FD(BPF_REG_1, 0),
0676 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0677 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0678 BPF_EXIT_INSN(),
0679 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
0680 BPF_JMP_IMM(BPF_JLE, BPF_REG_1, 0, 3),
0681 BPF_ALU64_IMM(BPF_XOR, BPF_REG_1, 3),
0682 BPF_JMP_IMM(BPF_JGE, BPF_REG_1, 0, 1),
0683 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
0684 BPF_MOV64_IMM(BPF_REG_0, 0),
0685 BPF_EXIT_INSN(),
0686 },
0687 .errstr_unpriv = "R0 min value is outside of the allowed memory range",
0688 .result_unpriv = REJECT,
0689 .fixup_map_hash_8b = { 3 },
0690 .result = ACCEPT,
0691 },
0692 {
0693 "bounds check for reg32 > 0, reg32 xor 3",
0694 .insns = {
0695 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0696 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0697 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0698 BPF_LD_MAP_FD(BPF_REG_1, 0),
0699 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0700 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
0701 BPF_EXIT_INSN(),
0702 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
0703 BPF_JMP32_IMM(BPF_JLE, BPF_REG_1, 0, 3),
0704 BPF_ALU32_IMM(BPF_XOR, BPF_REG_1, 3),
0705 BPF_JMP32_IMM(BPF_JGE, BPF_REG_1, 0, 1),
0706 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 8),
0707 BPF_MOV64_IMM(BPF_REG_0, 0),
0708 BPF_EXIT_INSN(),
0709 },
0710 .errstr_unpriv = "R0 min value is outside of the allowed memory range",
0711 .result_unpriv = REJECT,
0712 .fixup_map_hash_8b = { 3 },
0713 .result = ACCEPT,
0714 },
0715 {
0716 "bounds checks after 32-bit truncation. test 1",
0717 .insns = {
0718 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0719 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0720 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0721 BPF_LD_MAP_FD(BPF_REG_1, 0),
0722 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0723 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0724 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
0725
0726 BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1),
0727 BPF_JMP_IMM(BPF_JGT, BPF_REG_1, 0x7fffffff, 1),
0728 BPF_MOV64_IMM(BPF_REG_0, 0),
0729 BPF_EXIT_INSN(),
0730 },
0731 .fixup_map_hash_8b = { 3 },
0732 .errstr_unpriv = "R0 leaks addr",
0733 .result_unpriv = REJECT,
0734 .result = ACCEPT,
0735 },
0736 {
0737 "bounds checks after 32-bit truncation. test 2",
0738 .insns = {
0739 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
0740 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
0741 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
0742 BPF_LD_MAP_FD(BPF_REG_1, 0),
0743 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
0744 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4),
0745 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
0746 BPF_JMP_IMM(BPF_JSLT, BPF_REG_1, 1, 1),
0747 BPF_JMP32_IMM(BPF_JSLT, BPF_REG_1, 0, 1),
0748 BPF_MOV64_IMM(BPF_REG_0, 0),
0749 BPF_EXIT_INSN(),
0750 },
0751 .fixup_map_hash_8b = { 3 },
0752 .errstr_unpriv = "R0 leaks addr",
0753 .result_unpriv = REJECT,
0754 .result = ACCEPT,
0755 },