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
 			}