This is a note to let you know that I've just added the patch titled bpf: Do not use ax register in interpreter on div/mod to the 4.14-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: bpf-do-not-use-ax-register-in-interpreter-on-div-mod.patch and it can be found in the queue-4.14 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Wed Sep 1 11:42:16 AM CEST 2021 From: Thadeu Lima de Souza Cascardo <cascardo@xxxxxxxxxxxxx> Date: Mon, 30 Aug 2021 15:32:08 -0300 Subject: bpf: Do not use ax register in interpreter on div/mod To: stable@xxxxxxxxxxxxxxx Cc: bpf@xxxxxxxxxxxxxxx, Daniel Borkmann <daniel@xxxxxxxxxxxxx>, Alexei Starovoitov <ast@xxxxxxxxxx>, John Fastabend <john.fastabend@xxxxxxxxx>, Pavel Machek <pavel@xxxxxxx>, Thadeu Lima de Souza Cascardo <cascardo@xxxxxxxxxxxxx> Message-ID: <20210830183211.339054-2-cascardo@xxxxxxxxxxxxx> From: Daniel Borkmann <daniel@xxxxxxxxxxxxx> 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@xxxxxxxxxxxxx> Reviewed-by: John Fastabend <john.fastabend@xxxxxxxxx> [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@xxxxxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- kernel/bpf/core.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -616,9 +616,6 @@ static int bpf_jit_blind_insn(const stru * 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! @@ -951,6 +948,7 @@ static unsigned int ___bpf_prog_run(u64 u32 tail_call_cnt = 0; void *ptr; int off; + u64 tmp; #define CONT ({ insn++; goto select_insn; }) #define CONT_JMP ({ insn++; goto select_insn; }) @@ -1013,22 +1011,22 @@ select_insn: ALU64_MOD_X: if (unlikely(SRC == 0)) return 0; - div64_u64_rem(DST, SRC, &AX); - DST = AX; + div64_u64_rem(DST, SRC, &tmp); + DST = tmp; CONT; ALU_MOD_X: if (unlikely((u32)SRC == 0)) return 0; - 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: if (unlikely(SRC == 0)) @@ -1038,17 +1036,17 @@ select_insn: ALU_DIV_X: if (unlikely((u32)SRC == 0)) return 0; - 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) { Patches currently in stable-queue which might be from cascardo@xxxxxxxxxxxxx are queue-4.14/bpf-do-not-use-ax-register-in-interpreter-on-div-mod.patch queue-4.14/bpf-fix-truncation-handling-for-mod32-dst-reg-wrt-zero.patch queue-4.14/bpf-fix-subprog-verifier-bypass-by-div-mod-by-0-exception.patch queue-4.14/bpf-fix-32-bit-src-register-truncation-on-div-mod.patch