提交 0f80d330 编写于 作者: D Daniel Borkmann 提交者: Zheng Zengkai

bpf: Fix mask direction swap upon off reg sign change

stable inclusion
from stable-5.10.41
commit c87ef240a8bbbda5913fac1e84209d224c1aaf50
bugzilla: 51890
CVE: NA

--------------------------------

commit bb01a1bb upstream.

Masking direction as indicated via mask_to_left is considered to be
calculated once and then used to derive pointer limits. Thus, this
needs to be placed into bpf_sanitize_info instead so we can pass it
to sanitize_ptr_alu() call after the pointer move. Piotr noticed a
corner case where the off reg causes masking direction change which
then results in an incorrect final aux->alu_limit.

Fixes: 7fedb63a ("bpf: Tighten speculative pointer arithmetic mask")
Reported-by: NPiotr Krysiuk <piotras@gmail.com>
Signed-off-by: NDaniel Borkmann <daniel@iogearbox.net>
Reviewed-by: NPiotr Krysiuk <piotras@gmail.com>
Acked-by: NAlexei Starovoitov <ast@kernel.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 f06f3897
...@@ -5666,18 +5666,10 @@ enum { ...@@ -5666,18 +5666,10 @@ enum {
}; };
static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg, static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg,
const struct bpf_reg_state *off_reg, u32 *alu_limit, bool mask_to_left)
u32 *alu_limit, u8 opcode)
{ {
bool off_is_neg = off_reg->smin_value < 0;
bool mask_to_left = (opcode == BPF_ADD && off_is_neg) ||
(opcode == BPF_SUB && !off_is_neg);
u32 max = 0, ptr_limit = 0; u32 max = 0, ptr_limit = 0;
if (!tnum_is_const(off_reg->var_off) &&
(off_reg->smin_value < 0) != (off_reg->smax_value < 0))
return REASON_BOUNDS;
switch (ptr_reg->type) { switch (ptr_reg->type) {
case PTR_TO_STACK: case PTR_TO_STACK:
/* Offset 0 is out-of-bounds, but acceptable start for the /* Offset 0 is out-of-bounds, but acceptable start for the
...@@ -5745,6 +5737,7 @@ static bool sanitize_needed(u8 opcode) ...@@ -5745,6 +5737,7 @@ static bool sanitize_needed(u8 opcode)
struct bpf_sanitize_info { struct bpf_sanitize_info {
struct bpf_insn_aux_data aux; struct bpf_insn_aux_data aux;
bool mask_to_left;
}; };
static int sanitize_ptr_alu(struct bpf_verifier_env *env, static int sanitize_ptr_alu(struct bpf_verifier_env *env,
...@@ -5776,7 +5769,16 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env, ...@@ -5776,7 +5769,16 @@ static int sanitize_ptr_alu(struct bpf_verifier_env *env,
if (vstate->speculative) if (vstate->speculative)
goto do_sim; goto do_sim;
err = retrieve_ptr_limit(ptr_reg, off_reg, &alu_limit, opcode); if (!commit_window) {
if (!tnum_is_const(off_reg->var_off) &&
(off_reg->smin_value < 0) != (off_reg->smax_value < 0))
return REASON_BOUNDS;
info->mask_to_left = (opcode == BPF_ADD && off_is_neg) ||
(opcode == BPF_SUB && !off_is_neg);
}
err = retrieve_ptr_limit(ptr_reg, &alu_limit, info->mask_to_left);
if (err < 0) if (err < 0)
return err; return err;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册