bpf: Fix the off-by-two error in range markings
commit2fa7d94afc
upstream. The first commit cited below attempts to fix the off-by-one error that appeared in some comparisons with an open range. Due to this error, arithmetically equivalent pieces of code could get different verdicts from the verifier, for example (pseudocode): // 1. Passes the verifier: if (data + 8 > data_end) return early read *(u64 *)data, i.e. [data; data+7] // 2. Rejected by the verifier (should still pass): if (data + 7 >= data_end) return early read *(u64 *)data, i.e. [data; data+7] The attempted fix, however, shifts the range by one in a wrong direction, so the bug not only remains, but also such piece of code starts failing in the verifier: // 3. Rejected by the verifier, but the check is stricter than in #1. if (data + 8 >= data_end) return early read *(u64 *)data, i.e. [data; data+7] The change performed by that fix converted an off-by-one bug into off-by-two. The second commit cited below added the BPF selftests written to ensure than code chunks like #3 are rejected, however, they should be accepted. This commit fixes the off-by-two error by adjusting new_range in the right direction and fixes the tests by changing the range into the one that should actually fail. Fixes:fb2a311a31
("bpf: fix off by one for range markings with L{T, E} patterns") Fixes:b37242c773
("bpf: add test cases to bpf selftests to cover all access tests") Signed-off-by: Maxim Mikityanskiy <maximmi@nvidia.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20211130181607.593149-1-maximmi@nvidia.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
e76da2e8a0
Коммит
b4fb67fd1a
|
@ -8228,7 +8228,7 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate,
|
||||||
|
|
||||||
new_range = dst_reg->off;
|
new_range = dst_reg->off;
|
||||||
if (range_right_open)
|
if (range_right_open)
|
||||||
new_range--;
|
new_range++;
|
||||||
|
|
||||||
/* Examples for register markings:
|
/* Examples for register markings:
|
||||||
*
|
*
|
||||||
|
|
|
@ -112,10 +112,10 @@
|
||||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||||
offsetof(struct xdp_md, data_end)),
|
offsetof(struct xdp_md, data_end)),
|
||||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||||
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
||||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
BPF_EXIT_INSN(),
|
BPF_EXIT_INSN(),
|
||||||
},
|
},
|
||||||
|
@ -167,10 +167,10 @@
|
||||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||||
offsetof(struct xdp_md, data_end)),
|
offsetof(struct xdp_md, data_end)),
|
||||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||||
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
||||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
BPF_EXIT_INSN(),
|
BPF_EXIT_INSN(),
|
||||||
},
|
},
|
||||||
|
@ -274,9 +274,9 @@
|
||||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||||
offsetof(struct xdp_md, data_end)),
|
offsetof(struct xdp_md, data_end)),
|
||||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||||
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
||||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
BPF_EXIT_INSN(),
|
BPF_EXIT_INSN(),
|
||||||
},
|
},
|
||||||
|
@ -437,9 +437,9 @@
|
||||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1,
|
||||||
offsetof(struct xdp_md, data_end)),
|
offsetof(struct xdp_md, data_end)),
|
||||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||||
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
||||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
BPF_EXIT_INSN(),
|
BPF_EXIT_INSN(),
|
||||||
},
|
},
|
||||||
|
@ -544,10 +544,10 @@
|
||||||
offsetof(struct xdp_md, data_meta)),
|
offsetof(struct xdp_md, data_meta)),
|
||||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||||
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1),
|
||||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
BPF_EXIT_INSN(),
|
BPF_EXIT_INSN(),
|
||||||
},
|
},
|
||||||
|
@ -599,10 +599,10 @@
|
||||||
offsetof(struct xdp_md, data_meta)),
|
offsetof(struct xdp_md, data_meta)),
|
||||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||||
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1),
|
||||||
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
BPF_JMP_IMM(BPF_JA, 0, 0, 1),
|
||||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
BPF_EXIT_INSN(),
|
BPF_EXIT_INSN(),
|
||||||
},
|
},
|
||||||
|
@ -706,9 +706,9 @@
|
||||||
offsetof(struct xdp_md, data_meta)),
|
offsetof(struct xdp_md, data_meta)),
|
||||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||||
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1),
|
||||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
BPF_EXIT_INSN(),
|
BPF_EXIT_INSN(),
|
||||||
},
|
},
|
||||||
|
@ -869,9 +869,9 @@
|
||||||
offsetof(struct xdp_md, data_meta)),
|
offsetof(struct xdp_md, data_meta)),
|
||||||
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, offsetof(struct xdp_md, data)),
|
||||||
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
BPF_MOV64_REG(BPF_REG_1, BPF_REG_2),
|
||||||
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8),
|
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6),
|
||||||
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1),
|
||||||
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8),
|
BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -6),
|
||||||
BPF_MOV64_IMM(BPF_REG_0, 0),
|
BPF_MOV64_IMM(BPF_REG_0, 0),
|
||||||
BPF_EXIT_INSN(),
|
BPF_EXIT_INSN(),
|
||||||
},
|
},
|
||||||
|
|
Загрузка…
Ссылка в новой задаче