summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2021-08-27 10:55:31 -0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-09-03 09:58:00 +0200
commitc348d806ed1d3075af52345344243824d72c4945 (patch)
tree9046375af505fdb243412550f9ca86d1ea11006c
parentce7d8be2eaa4cab3032e256d154d1c33843d2367 (diff)
downloadlinux-stable-c348d806ed1d3075af52345344243824d72c4945.tar.gz
linux-stable-c348d806ed1d3075af52345344243824d72c4945.tar.bz2
linux-stable-c348d806ed1d3075af52345344243824d72c4945.zip
bpf: Do not use ax register in interpreter on div/mod
Partially undo old commit 144cd91c4c2b ("bpf: move tmp variable into ax register in interpreter"). The reason we need this here is because ax register will be used for holding temporary state for div/mod instruction which otherwise interpreter would corrupt. This will cause a small +8 byte stack increase for interpreter, but with the gain that we can use it from verifier rewrites as scratch register. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Reviewed-by: John Fastabend <john.fastabend@gmail.com> [cascardo: This partial revert is needed in order to support using AX for the following two commits, as there is no JMP32 on 4.19.y] Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--kernel/bpf/core.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 36be400c3e65..d2b6d2459aad 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -705,9 +705,6 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from,
* below.
*
* Constant blinding is only used by JITs, not in the interpreter.
- * The interpreter uses AX in some occasions as a local temporary
- * register e.g. in DIV or MOD instructions.
- *
* In restricted circumstances, the verifier can also use the AX
* register for rewrites as long as they do not interfere with
* the above cases!
@@ -1057,6 +1054,7 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn, u64 *stack)
#undef BPF_INSN_3_LBL
#undef BPF_INSN_2_LBL
u32 tail_call_cnt = 0;
+ u64 tmp;
#define CONT ({ insn++; goto select_insn; })
#define CONT_JMP ({ insn++; goto select_insn; })
@@ -1117,36 +1115,36 @@ select_insn:
(*(s64 *) &DST) >>= IMM;
CONT;
ALU64_MOD_X:
- div64_u64_rem(DST, SRC, &AX);
- DST = AX;
+ div64_u64_rem(DST, SRC, &tmp);
+ DST = tmp;
CONT;
ALU_MOD_X:
- AX = (u32) DST;
- DST = do_div(AX, (u32) SRC);
+ tmp = (u32) DST;
+ DST = do_div(tmp, (u32) SRC);
CONT;
ALU64_MOD_K:
- div64_u64_rem(DST, IMM, &AX);
- DST = AX;
+ div64_u64_rem(DST, IMM, &tmp);
+ DST = tmp;
CONT;
ALU_MOD_K:
- AX = (u32) DST;
- DST = do_div(AX, (u32) IMM);
+ tmp = (u32) DST;
+ DST = do_div(tmp, (u32) IMM);
CONT;
ALU64_DIV_X:
DST = div64_u64(DST, SRC);
CONT;
ALU_DIV_X:
- AX = (u32) DST;
- do_div(AX, (u32) SRC);
- DST = (u32) AX;
+ tmp = (u32) DST;
+ do_div(tmp, (u32) SRC);
+ DST = (u32) tmp;
CONT;
ALU64_DIV_K:
DST = div64_u64(DST, IMM);
CONT;
ALU_DIV_K:
- AX = (u32) DST;
- do_div(AX, (u32) IMM);
- DST = (u32) AX;
+ tmp = (u32) DST;
+ do_div(tmp, (u32) IMM);
+ DST = (u32) tmp;
CONT;
ALU_END_TO_BE:
switch (IMM) {