| From f528819334881fd622fdadeddb3f7edaed8b7c9b Mon Sep 17 00:00:00 2001 |
| From: Daniel Borkmann <daniel@iogearbox.net> |
| Date: Wed, 24 Mar 2021 11:25:39 +0100 |
| Subject: bpf: Move sanitize_val_alu out of op switch |
| |
| From: Daniel Borkmann <daniel@iogearbox.net> |
| |
| commit f528819334881fd622fdadeddb3f7edaed8b7c9b upstream. |
| |
| Add a small sanitize_needed() helper function and move sanitize_val_alu() |
| out of the main opcode switch. In upcoming work, we'll move sanitize_ptr_alu() |
| as well out of its opcode switch so this helps to streamline both. |
| |
| Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> |
| Reviewed-by: John Fastabend <john.fastabend@gmail.com> |
| Acked-by: Alexei Starovoitov <ast@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| kernel/bpf/verifier.c | 17 +++++++++++------ |
| 1 file changed, 11 insertions(+), 6 deletions(-) |
| |
| --- a/kernel/bpf/verifier.c |
| +++ b/kernel/bpf/verifier.c |
| @@ -5473,6 +5473,11 @@ static int sanitize_val_alu(struct bpf_v |
| return update_alu_sanitation_state(aux, BPF_ALU_NON_POINTER, 0); |
| } |
| |
| +static bool sanitize_needed(u8 opcode) |
| +{ |
| + return opcode == BPF_ADD || opcode == BPF_SUB; |
| +} |
| + |
| static int sanitize_ptr_alu(struct bpf_verifier_env *env, |
| struct bpf_insn *insn, |
| const struct bpf_reg_state *ptr_reg, |
| @@ -6445,6 +6450,12 @@ static int adjust_scalar_min_max_vals(st |
| return 0; |
| } |
| |
| + if (sanitize_needed(opcode)) { |
| + ret = sanitize_val_alu(env, insn); |
| + if (ret < 0) |
| + return sanitize_err(env, insn, ret, NULL, NULL); |
| + } |
| + |
| /* Calculate sign/unsigned bounds and tnum for alu32 and alu64 bit ops. |
| * There are two classes of instructions: The first class we track both |
| * alu32 and alu64 sign/unsigned bounds independently this provides the |
| @@ -6461,17 +6472,11 @@ static int adjust_scalar_min_max_vals(st |
| */ |
| switch (opcode) { |
| case BPF_ADD: |
| - ret = sanitize_val_alu(env, insn); |
| - if (ret < 0) |
| - return sanitize_err(env, insn, ret, NULL, NULL); |
| scalar32_min_max_add(dst_reg, &src_reg); |
| scalar_min_max_add(dst_reg, &src_reg); |
| dst_reg->var_off = tnum_add(dst_reg->var_off, src_reg.var_off); |
| break; |
| case BPF_SUB: |
| - ret = sanitize_val_alu(env, insn); |
| - if (ret < 0) |
| - return sanitize_err(env, insn, ret, NULL, NULL); |
| scalar32_min_max_sub(dst_reg, &src_reg); |
| scalar_min_max_sub(dst_reg, &src_reg); |
| dst_reg->var_off = tnum_sub(dst_reg->var_off, src_reg.var_off); |