|
Gary Lin |
f5833e |
From: Piotr Krysiuk <piotras@gmail.com>
|
|
Gary Lin |
f5833e |
Date: Mon, 5 Apr 2021 22:52:15 +0100
|
|
Gary Lin |
f5833e |
Subject: bpf, x86: Validate computation of branch displacements for x86-64
|
|
Gary Lin |
f5833e |
Patch-mainline: v5.12-rc7
|
|
Gary Lin |
f5833e |
Git-commit: e4d4d456436bfb2fe412ee2cd489f7658449b098
|
|
Gary Lin |
f5833e |
References: bsc#1184391 CVE-2021-29154
|
|
Gary Lin |
f5833e |
|
|
Gary Lin |
f5833e |
The branch displacement logic in the BPF JIT compilers for x86 assumes
|
|
Gary Lin |
f5833e |
that, for any generated branch instruction, the distance cannot
|
|
Gary Lin |
f5833e |
increase between optimization passes.
|
|
Gary Lin |
f5833e |
|
|
Gary Lin |
f5833e |
But this assumption can be violated due to how the distances are
|
|
Gary Lin |
f5833e |
computed. Specifically, whenever a backward branch is processed in
|
|
Gary Lin |
f5833e |
do_jit(), the distance is computed by subtracting the positions in the
|
|
Gary Lin |
f5833e |
machine code from different optimization passes. This is because part
|
|
Gary Lin |
f5833e |
of addrs[] is already updated for the current optimization pass, before
|
|
Gary Lin |
f5833e |
the branch instruction is visited.
|
|
Gary Lin |
f5833e |
|
|
Gary Lin |
f5833e |
And so the optimizer can expand blocks of machine code in some cases.
|
|
Gary Lin |
f5833e |
|
|
Gary Lin |
f5833e |
This can confuse the optimizer logic, where it assumes that a fixed
|
|
Gary Lin |
f5833e |
point has been reached for all machine code blocks once the total
|
|
Gary Lin |
f5833e |
program size stops changing. And then the JIT compiler can output
|
|
Gary Lin |
f5833e |
abnormal machine code containing incorrect branch displacements.
|
|
Gary Lin |
f5833e |
|
|
Gary Lin |
f5833e |
To mitigate this issue, we assert that a fixed point is reached while
|
|
Gary Lin |
f5833e |
populating the output image. This rejects any problematic programs.
|
|
Gary Lin |
f5833e |
The issue affects both x86-32 and x86-64. We mitigate separately to
|
|
Gary Lin |
f5833e |
ease backporting.
|
|
Gary Lin |
f5833e |
|
|
Gary Lin |
f5833e |
Signed-off-by: Piotr Krysiuk <piotras@gmail.com>
|
|
Gary Lin |
f5833e |
Reviewed-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Gary Lin |
f5833e |
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Gary Lin |
f5833e |
Acked-by: Gary Lin <glin@suse.com>
|
|
Gary Lin |
f5833e |
---
|
|
Gary Lin |
f5833e |
arch/x86/net/bpf_jit_comp.c | 11 ++++++++++-
|
|
Gary Lin |
f5833e |
1 file changed, 10 insertions(+), 1 deletion(-)
|
|
Gary Lin |
f5833e |
|
|
Gary Lin |
f5833e |
--- a/arch/x86/net/bpf_jit_comp.c
|
|
Gary Lin |
f5833e |
+++ b/arch/x86/net/bpf_jit_comp.c
|
|
Gary Lin |
f5833e |
@@ -1394,7 +1394,16 @@ emit_jmp:
|
|
Gary Lin |
f5833e |
}
|
|
Gary Lin |
f5833e |
|
|
Gary Lin |
f5833e |
if (image) {
|
|
Gary Lin |
f5833e |
- if (unlikely(proglen + ilen > oldproglen)) {
|
|
Gary Lin |
f5833e |
+ /*
|
|
Gary Lin |
f5833e |
+ * When populating the image, assert that:
|
|
Gary Lin |
f5833e |
+ *
|
|
Gary Lin |
f5833e |
+ * i) We do not write beyond the allocated space, and
|
|
Gary Lin |
f5833e |
+ * ii) addrs[i] did not change from the prior run, in order
|
|
Gary Lin |
f5833e |
+ * to validate assumptions made for computing branch
|
|
Gary Lin |
f5833e |
+ * displacements.
|
|
Gary Lin |
f5833e |
+ */
|
|
Gary Lin |
f5833e |
+ if (unlikely(proglen + ilen > oldproglen ||
|
|
Gary Lin |
f5833e |
+ proglen + ilen != addrs[i])) {
|
|
Gary Lin |
f5833e |
pr_err("bpf_jit: fatal error\n");
|
|
Gary Lin |
f5833e |
return -EFAULT;
|
|
Gary Lin |
f5833e |
}
|