NACK: [PATCH bpf v2 1/2] bpf, x86: Validate computation of branch displacements for x86-64
Colin Ian King
colin.king at canonical.com
Tue Jul 6 18:27:25 UTC 2021
Igore, I fat fingered a git send.
Colin
On 06/07/2021 19:26, Colin King wrote:
> From: Piotr Krysiuk <piotras at gmail.com>
>
> The branch displacement logic in the BPF JIT compilers for x86 assumes
> that, for any generated branch instruction, the distance cannot
> increase between optimization passes.
>
> But this assumption can be violated due to how the distances are
> computed. Specifically, whenever a backward branch is processed in
> do_jit(), the distance is computed by subtracting the positions in the
> machine code from different optimization passes. This is because part
> of addrs[] is already updated for the current optimization pass, before
> the branch instruction is visited.
>
> And so the optimizer can expand blocks of machine code in some cases.
>
> This can confuse the optimizer logic, where it assumes that a fixed
> point has been reached for all machine code blocks once the total
> program size stops changing. And then the JIT compiler can output
> abnormal machine code containing incorrect branch displacements.
>
> To mitigate this issue, we assert that a fixed point is reached while
> populating the output image. This rejects any problematic programs.
>
> The issue affects both x86-32 and x86-64. We mitigate separately to
> ease backporting.
>
> Signed-off-by: Piotr Krysiuk <piotras at gmail.com>
> ---
> arch/x86/net/bpf_jit_comp.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
> index 023ac12f54a2..f104c36f1e79 100644
> --- a/arch/x86/net/bpf_jit_comp.c
> +++ b/arch/x86/net/bpf_jit_comp.c
> @@ -1476,7 +1476,15 @@ xadd: if (is_imm8(insn->off))
> }
>
> if (image) {
> - if (unlikely(proglen + ilen > oldproglen)) {
> + /*
> + * When populating the image, assert that
> + * i) we do not write beyond the allocated space, and
> + * ii) addrs[i] did not change from the prior run, in order
> + * to validate assumptions made for computing branch
> + * displacements
> + */
> + if (unlikely(proglen + ilen > oldproglen ||
> + proglen + ilen != addrs[i])) {
> pr_err("bpf_jit: fatal error\n");
> return -EFAULT;
> }
>
More information about the kernel-team
mailing list