|
Gary Lin |
e93023 |
From: Daniel Borkmann <daniel@iogearbox.net>
|
|
Gary Lin |
e93023 |
Date: Fri, 21 May 2021 10:17:36 +0000
|
|
Gary Lin |
e93023 |
Subject: bpf: Wrap aux data inside bpf_sanitize_info container
|
|
Gary Lin |
e93023 |
Patch-mainline: v5.13 or v5.13-rc4 (next release)
|
|
Gary Lin |
e93023 |
Git-commit: 3d0220f6861d713213b015b582e9f21e5b28d2e0
|
|
Gary Lin |
e93023 |
References: bsc#1186484,CVE-2021-33200
|
|
Gary Lin |
e93023 |
|
|
Gary Lin |
e93023 |
Add a container structure struct bpf_sanitize_info which holds
|
|
Gary Lin |
e93023 |
the current aux info, and update call-sites to sanitize_ptr_alu()
|
|
Gary Lin |
e93023 |
to pass it in. This is needed for passing in additional state
|
|
Gary Lin |
e93023 |
later on.
|
|
Gary Lin |
e93023 |
|
|
Gary Lin |
e93023 |
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
|
|
Gary Lin |
e93023 |
Reviewed-by: Piotr Krysiuk <piotras@gmail.com>
|
|
Gary Lin |
e93023 |
Acked-by: Alexei Starovoitov <ast@kernel.org>
|
|
Gary Lin |
e93023 |
Acked-by: Gary Lin <glin@suse.com>
|
|
Gary Lin |
e93023 |
---
|
|
Gary Lin |
e93023 |
kernel/bpf/verifier.c | 18 +++++++++++-------
|
|
Gary Lin |
e93023 |
1 file changed, 11 insertions(+), 7 deletions(-)
|
|
Gary Lin |
e93023 |
|
|
Gary Lin |
e93023 |
--- a/kernel/bpf/verifier.c
|
|
Gary Lin |
e93023 |
+++ b/kernel/bpf/verifier.c
|
|
Gary Lin |
e93023 |
@@ -1999,15 +1999,19 @@ static bool sanitize_needed(u8 opcode)
|
|
Gary Lin |
e93023 |
return opcode == BPF_ADD || opcode == BPF_SUB;
|
|
Gary Lin |
e93023 |
}
|
|
Gary Lin |
e93023 |
|
|
Gary Lin |
e93023 |
+struct bpf_sanitize_info {
|
|
Gary Lin |
e93023 |
+ struct bpf_insn_aux_data aux;
|
|
Gary Lin |
e93023 |
+};
|
|
Gary Lin |
e93023 |
+
|
|
Gary Lin |
e93023 |
static int sanitize_ptr_alu(struct bpf_verifier_env *env,
|
|
Gary Lin |
e93023 |
struct bpf_insn *insn,
|
|
Gary Lin |
e93023 |
const struct bpf_reg_state *ptr_reg,
|
|
Gary Lin |
e93023 |
const struct bpf_reg_state *off_reg,
|
|
Gary Lin |
e93023 |
struct bpf_reg_state *dst_reg,
|
|
Gary Lin |
e93023 |
- struct bpf_insn_aux_data *tmp_aux,
|
|
Gary Lin |
e93023 |
+ struct bpf_sanitize_info *info,
|
|
Gary Lin |
e93023 |
const bool commit_window)
|
|
Gary Lin |
e93023 |
{
|
|
Gary Lin |
e93023 |
- struct bpf_insn_aux_data *aux = commit_window ? cur_aux(env) : tmp_aux;
|
|
Gary Lin |
e93023 |
+ struct bpf_insn_aux_data *aux = commit_window ? cur_aux(env) : &info->aux;
|
|
Gary Lin |
e93023 |
struct bpf_verifier_state *vstate = env->cur_state;
|
|
Gary Lin |
e93023 |
bool off_is_neg = off_reg->smin_value < 0;
|
|
Gary Lin |
e93023 |
bool ptr_is_dst_reg = ptr_reg == dst_reg;
|
|
Gary Lin |
e93023 |
@@ -2035,8 +2039,8 @@ static int sanitize_ptr_alu(struct bpf_v
|
|
Gary Lin |
e93023 |
/* In commit phase we narrow the masking window based on
|
|
Gary Lin |
e93023 |
* the observed pointer move after the simulated operation.
|
|
Gary Lin |
e93023 |
*/
|
|
Gary Lin |
e93023 |
- alu_state = tmp_aux->alu_state;
|
|
Gary Lin |
e93023 |
- alu_limit = abs(tmp_aux->alu_limit - alu_limit);
|
|
Gary Lin |
e93023 |
+ alu_state = info->aux.alu_state;
|
|
Gary Lin |
e93023 |
+ alu_limit = abs(info->aux.alu_limit - alu_limit);
|
|
Gary Lin |
e93023 |
} else {
|
|
Gary Lin |
e93023 |
alu_state = off_is_neg ? BPF_ALU_NEG_VALUE : 0;
|
|
Gary Lin |
e93023 |
alu_state |= ptr_is_dst_reg ?
|
|
Gary Lin |
e93023 |
@@ -2163,7 +2167,7 @@ static int adjust_ptr_min_max_vals(struc
|
|
Gary Lin |
e93023 |
smin_ptr = ptr_reg->smin_value, smax_ptr = ptr_reg->smax_value;
|
|
Gary Lin |
e93023 |
u64 umin_val = off_reg->umin_value, umax_val = off_reg->umax_value,
|
|
Gary Lin |
e93023 |
umin_ptr = ptr_reg->umin_value, umax_ptr = ptr_reg->umax_value;
|
|
Gary Lin |
e93023 |
- struct bpf_insn_aux_data tmp_aux = {};
|
|
Gary Lin |
e93023 |
+ struct bpf_sanitize_info info = {};
|
|
Gary Lin |
e93023 |
u8 opcode = BPF_OP(insn->code);
|
|
Gary Lin |
e93023 |
u32 dst = insn->dst_reg;
|
|
Gary Lin |
e93023 |
int ret;
|
|
Gary Lin |
e93023 |
@@ -2215,7 +2219,7 @@ static int adjust_ptr_min_max_vals(struc
|
|
Gary Lin |
e93023 |
|
|
Gary Lin |
e93023 |
if (sanitize_needed(opcode)) {
|
|
Gary Lin |
e93023 |
ret = sanitize_ptr_alu(env, insn, ptr_reg, off_reg, dst_reg,
|
|
Gary Lin |
e93023 |
- &tmp_aux, false);
|
|
Gary Lin |
e93023 |
+ &info, false);
|
|
Gary Lin |
e93023 |
if (ret < 0)
|
|
Gary Lin |
e93023 |
return sanitize_err(env, insn, ret, off_reg, dst_reg);
|
|
Gary Lin |
e93023 |
}
|
|
Gary Lin |
e93023 |
@@ -2356,7 +2360,7 @@ static int adjust_ptr_min_max_vals(struc
|
|
Gary Lin |
e93023 |
return -EACCES;
|
|
Gary Lin |
e93023 |
if (sanitize_needed(opcode)) {
|
|
Gary Lin |
e93023 |
ret = sanitize_ptr_alu(env, insn, dst_reg, off_reg, dst_reg,
|
|
Gary Lin |
e93023 |
- &tmp_aux, true);
|
|
Gary Lin |
e93023 |
+ &info, true);
|
|
Gary Lin |
e93023 |
if (ret < 0)
|
|
Gary Lin |
e93023 |
return sanitize_err(env, insn, ret, off_reg, dst_reg);
|
|
Gary Lin |
e93023 |
}
|