| { |
| "map access: known scalar += value_ptr unknown vs const", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9), |
| BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_0, 0), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_4, 1, 4), |
| BPF_MOV64_IMM(BPF_REG_1, 6), |
| BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x7), |
| BPF_JMP_IMM(BPF_JA, 0, 0, 1), |
| BPF_MOV64_IMM(BPF_REG_1, 3), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_16b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R1 tried to add from different maps, paths or scalars", |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: known scalar += value_ptr const vs unknown", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 9), |
| BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_0, 0), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_4, 1, 2), |
| BPF_MOV64_IMM(BPF_REG_1, 3), |
| BPF_JMP_IMM(BPF_JA, 0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 6), |
| BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x7), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_16b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R1 tried to add from different maps, paths or scalars", |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: known scalar += value_ptr const vs const (ne)", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), |
| BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_0, 0), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_4, 1, 2), |
| BPF_MOV64_IMM(BPF_REG_1, 3), |
| BPF_JMP_IMM(BPF_JA, 0, 0, 1), |
| BPF_MOV64_IMM(BPF_REG_1, 5), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_16b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R1 tried to add from different maps, paths or scalars", |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: known scalar += value_ptr const vs const (eq)", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), |
| BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_0, 0), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_4, 1, 2), |
| BPF_MOV64_IMM(BPF_REG_1, 5), |
| BPF_JMP_IMM(BPF_JA, 0, 0, 1), |
| BPF_MOV64_IMM(BPF_REG_1, 5), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_16b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: known scalar += value_ptr unknown vs unknown (eq)", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11), |
| BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_0, 0), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_4, 1, 4), |
| BPF_MOV64_IMM(BPF_REG_1, 6), |
| BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x7), |
| BPF_JMP_IMM(BPF_JA, 0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 6), |
| BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x7), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_16b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: known scalar += value_ptr unknown vs unknown (lt)", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11), |
| BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_0, 0), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_4, 1, 4), |
| BPF_MOV64_IMM(BPF_REG_1, 6), |
| BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x3), |
| BPF_JMP_IMM(BPF_JA, 0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 6), |
| BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x7), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_16b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R1 tried to add from different maps, paths or scalars", |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: known scalar += value_ptr unknown vs unknown (gt)", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11), |
| BPF_LDX_MEM(BPF_B, BPF_REG_4, BPF_REG_0, 0), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_4, 1, 4), |
| BPF_MOV64_IMM(BPF_REG_1, 6), |
| BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x7), |
| BPF_JMP_IMM(BPF_JA, 0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 6), |
| BPF_ALU64_IMM(BPF_NEG, BPF_REG_1, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x3), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_16b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R1 tried to add from different maps, paths or scalars", |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: known scalar += value_ptr from different maps", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 4), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_16b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr -= known scalar from different maps", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_MOV64_IMM(BPF_REG_1, 4), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_16b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result = ACCEPT, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R0 min value is outside of the allowed memory range", |
| .retval = 1, |
| }, |
| { |
| "map access: known scalar += value_ptr from different maps, but same value properties", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, |
| offsetof(struct __sk_buff, len)), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 1, 3), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 1, 2), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 4), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_hash_48b = { 5 }, |
| .fixup_map_array_48b = { 8 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: mixing value pointer and scalar, 1", |
| .insns = { |
| // load map value pointer into r0 and r2 |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_LD_MAP_FD(BPF_REG_ARG1, 0), |
| BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -16), |
| BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0), |
| BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), |
| BPF_EXIT_INSN(), |
| // load some number from the map into r1 |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| // depending on r1, branch: |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 3), |
| // branch A |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), |
| BPF_MOV64_IMM(BPF_REG_3, 0), |
| BPF_JMP_A(2), |
| // branch B |
| BPF_MOV64_IMM(BPF_REG_2, 0), |
| BPF_MOV64_IMM(BPF_REG_3, 0x100000), |
| // common instruction |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3), |
| // depending on r1, branch: |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), |
| // branch A |
| BPF_JMP_A(4), |
| // branch B |
| BPF_MOV64_IMM(BPF_REG_0, 0x13371337), |
| // verifier follows fall-through |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0x100000, 2), |
| BPF_MOV64_IMM(BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| // fake-dead code; targeted from branch A to |
| // prevent dead code sanitization |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 1 }, |
| .result = ACCEPT, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R2 pointer comparison prohibited", |
| .retval = 0, |
| }, |
| { |
| "map access: mixing value pointer and scalar, 2", |
| .insns = { |
| // load map value pointer into r0 and r2 |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_LD_MAP_FD(BPF_REG_ARG1, 0), |
| BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -16), |
| BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0), |
| BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), |
| BPF_EXIT_INSN(), |
| // load some number from the map into r1 |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| // depending on r1, branch: |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), |
| // branch A |
| BPF_MOV64_IMM(BPF_REG_2, 0), |
| BPF_MOV64_IMM(BPF_REG_3, 0x100000), |
| BPF_JMP_A(2), |
| // branch B |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), |
| BPF_MOV64_IMM(BPF_REG_3, 0), |
| // common instruction |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3), |
| // depending on r1, branch: |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1), |
| // branch A |
| BPF_JMP_A(4), |
| // branch B |
| BPF_MOV64_IMM(BPF_REG_0, 0x13371337), |
| // verifier follows fall-through |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_2, 0x100000, 2), |
| BPF_MOV64_IMM(BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| // fake-dead code; targeted from branch A to |
| // prevent dead code sanitization, rejected |
| // via branch B however |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 1 }, |
| .result = ACCEPT, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R0 invalid mem access 'scalar'", |
| .retval = 0, |
| }, |
| { |
| "sanitation: alu with different scalars 1", |
| .insns = { |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_LD_MAP_FD(BPF_REG_ARG1, 0), |
| BPF_MOV64_REG(BPF_REG_ARG2, BPF_REG_FP), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_ARG2, -16), |
| BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0), |
| BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), |
| BPF_EXIT_INSN(), |
| BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_2, 0), |
| BPF_MOV64_IMM(BPF_REG_3, 0x100000), |
| BPF_JMP_A(2), |
| BPF_MOV64_IMM(BPF_REG_2, 42), |
| BPF_MOV64_IMM(BPF_REG_3, 0x100001), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_3), |
| BPF_MOV64_REG(BPF_REG_0, BPF_REG_2), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 1 }, |
| .result = ACCEPT, |
| .retval = 0x100000, |
| }, |
| { |
| "sanitation: alu with different scalars 2", |
| .insns = { |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), |
| BPF_ST_MEM(BPF_DW, BPF_REG_FP, -16, 0), |
| BPF_EMIT_CALL(BPF_FUNC_map_delete_elem), |
| BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), |
| BPF_MOV64_REG(BPF_REG_1, BPF_REG_6), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_FP), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16), |
| BPF_EMIT_CALL(BPF_FUNC_map_delete_elem), |
| BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), |
| BPF_MOV64_REG(BPF_REG_8, BPF_REG_6), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_7), |
| BPF_MOV64_REG(BPF_REG_0, BPF_REG_8), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 1 }, |
| .result = ACCEPT, |
| .retval = -EINVAL * 2, |
| }, |
| { |
| "sanitation: alu with different scalars 3", |
| .insns = { |
| BPF_MOV64_IMM(BPF_REG_0, EINVAL), |
| BPF_ALU64_IMM(BPF_MUL, BPF_REG_0, -1), |
| BPF_MOV64_REG(BPF_REG_7, BPF_REG_0), |
| BPF_MOV64_IMM(BPF_REG_0, EINVAL), |
| BPF_ALU64_IMM(BPF_MUL, BPF_REG_0, -1), |
| BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), |
| BPF_MOV64_REG(BPF_REG_8, BPF_REG_6), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_8, BPF_REG_7), |
| BPF_MOV64_REG(BPF_REG_0, BPF_REG_8), |
| BPF_EXIT_INSN(), |
| }, |
| .result = ACCEPT, |
| .retval = -EINVAL * 2, |
| }, |
| { |
| "map access: value_ptr += known scalar, upper oob arith, test 1", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_MOV64_IMM(BPF_REG_1, 48), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr += known scalar, upper oob arith, test 2", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_MOV64_IMM(BPF_REG_1, 49), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr += known scalar, upper oob arith, test 3", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_MOV64_IMM(BPF_REG_1, 47), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr -= known scalar, lower oob arith, test 1", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), |
| BPF_MOV64_IMM(BPF_REG_1, 47), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_MOV64_IMM(BPF_REG_1, 48), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "R0 min value is outside of the allowed memory range", |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", |
| }, |
| { |
| "map access: value_ptr -= known scalar, lower oob arith, test 2", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), |
| BPF_MOV64_IMM(BPF_REG_1, 47), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_MOV64_IMM(BPF_REG_1, 48), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_MOV64_IMM(BPF_REG_1, 1), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr -= known scalar, lower oob arith, test 3", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), |
| BPF_MOV64_IMM(BPF_REG_1, 47), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_MOV64_IMM(BPF_REG_1, 47), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: known scalar += value_ptr", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 4), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr += known scalar, 1", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 4), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr += known scalar, 2", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 49), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "invalid access to map value", |
| }, |
| { |
| "map access: value_ptr += known scalar, 3", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, -1), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "invalid access to map value", |
| }, |
| { |
| "map access: value_ptr += known scalar, 4", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 7), |
| BPF_MOV64_IMM(BPF_REG_1, 5), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_MOV64_IMM(BPF_REG_1, -2), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_MOV64_IMM(BPF_REG_1, -1), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr += known scalar, 5", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, (6 + 1) * sizeof(int)), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 0xabcdef12, |
| }, |
| { |
| "map access: value_ptr += known scalar, 6", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), |
| BPF_MOV64_IMM(BPF_REG_1, (3 + 1) * sizeof(int)), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_MOV64_IMM(BPF_REG_1, 3 * sizeof(int)), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 0xabcdef12, |
| }, |
| { |
| "map access: value_ptr += N, value_ptr -= N known scalar", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), |
| BPF_MOV32_IMM(BPF_REG_1, 0x12345678), |
| BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, 2), |
| BPF_MOV64_IMM(BPF_REG_1, 2), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 0x12345678, |
| }, |
| { |
| "map access: unknown scalar += value_ptr, 1", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: unknown scalar += value_ptr, 2", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 31), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 0xabcdef12, |
| .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| }, |
| { |
| "map access: unknown scalar += value_ptr, 3", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8), |
| BPF_MOV64_IMM(BPF_REG_1, -1), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_MOV64_IMM(BPF_REG_1, 1), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 31), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", |
| .retval = 0xabcdef12, |
| .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| }, |
| { |
| "map access: unknown scalar += value_ptr, 4", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 6), |
| BPF_MOV64_IMM(BPF_REG_1, 19), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 31), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "R1 max value is outside of the allowed memory range", |
| .errstr_unpriv = "R1 pointer arithmetic of map value goes out of range", |
| .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| }, |
| { |
| "map access: value_ptr += unknown scalar, 1", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr += unknown scalar, 2", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 31), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 0xabcdef12, |
| .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| }, |
| { |
| "map access: value_ptr += unknown scalar, 3", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11), |
| BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0), |
| BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_0, 8), |
| BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 16), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_3, 1), |
| BPF_ALU64_IMM(BPF_OR, BPF_REG_3, 1), |
| BPF_JMP_REG(BPF_JGT, BPF_REG_2, BPF_REG_3, 4), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_3), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| BPF_MOV64_IMM(BPF_REG_0, 2), |
| BPF_JMP_IMM(BPF_JA, 0, 0, -3), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr += value_ptr", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "R0 pointer += pointer prohibited", |
| }, |
| { |
| "map access: known scalar -= value_ptr", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 4), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "R1 tried to subtract pointer from scalar", |
| }, |
| { |
| "map access: value_ptr -= known scalar", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3), |
| BPF_MOV64_IMM(BPF_REG_1, 4), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "R0 min value is outside of the allowed memory range", |
| }, |
| { |
| "map access: value_ptr -= known scalar, 2", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5), |
| BPF_MOV64_IMM(BPF_REG_1, 6), |
| BPF_MOV64_IMM(BPF_REG_2, 4), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_2), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .retval = 1, |
| }, |
| { |
| "map access: unknown scalar -= value_ptr", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_1, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_1, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "R1 tried to subtract pointer from scalar", |
| }, |
| { |
| "map access: value_ptr -= unknown scalar", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 4), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "R0 min value is negative", |
| }, |
| { |
| "map access: value_ptr -= unknown scalar, 2", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0xf), |
| BPF_ALU64_IMM(BPF_OR, BPF_REG_1, 0x7), |
| BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x7), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_1), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = ACCEPT, |
| .result_unpriv = REJECT, |
| .errstr_unpriv = "R0 pointer arithmetic of map value goes out of range", |
| .retval = 1, |
| }, |
| { |
| "map access: value_ptr -= value_ptr", |
| .insns = { |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_0), |
| BPF_LDX_MEM(BPF_B, BPF_REG_1, BPF_REG_0, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 1), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 3 }, |
| .result = REJECT, |
| .errstr = "R0 invalid mem access 'scalar'", |
| .errstr_unpriv = "R0 pointer -= pointer prohibited", |
| }, |
| { |
| "map access: trying to leak tainted dst reg", |
| .insns = { |
| BPF_MOV64_IMM(BPF_REG_0, 0), |
| BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), |
| BPF_LD_MAP_FD(BPF_REG_1, 0), |
| BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem), |
| BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1), |
| BPF_EXIT_INSN(), |
| BPF_MOV64_REG(BPF_REG_2, BPF_REG_0), |
| BPF_MOV32_IMM(BPF_REG_1, 0xFFFFFFFF), |
| BPF_MOV32_REG(BPF_REG_1, BPF_REG_1), |
| BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_1), |
| BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_2, 0), |
| BPF_MOV64_IMM(BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .fixup_map_array_48b = { 4 }, |
| .result = REJECT, |
| .errstr = "math between map_value pointer and 4294967295 is not allowed", |
| }, |
| { |
| "32bit pkt_ptr -= scalar", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1, |
| offsetof(struct __sk_buff, data_end)), |
| BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, |
| offsetof(struct __sk_buff, data)), |
| BPF_MOV64_REG(BPF_REG_6, BPF_REG_7), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 40), |
| BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_8, 2), |
| BPF_ALU32_REG(BPF_MOV, BPF_REG_4, BPF_REG_7), |
| BPF_ALU32_REG(BPF_SUB, BPF_REG_6, BPF_REG_4), |
| BPF_MOV64_IMM(BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
| .result = ACCEPT, |
| .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| }, |
| { |
| "32bit scalar -= pkt_ptr", |
| .insns = { |
| BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_1, |
| offsetof(struct __sk_buff, data_end)), |
| BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1, |
| offsetof(struct __sk_buff, data)), |
| BPF_MOV64_REG(BPF_REG_6, BPF_REG_7), |
| BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 40), |
| BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_8, 2), |
| BPF_ALU32_REG(BPF_MOV, BPF_REG_4, BPF_REG_6), |
| BPF_ALU32_REG(BPF_SUB, BPF_REG_4, BPF_REG_7), |
| BPF_MOV64_IMM(BPF_REG_0, 0), |
| BPF_EXIT_INSN(), |
| }, |
| .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
| .result = ACCEPT, |
| .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| }, |