Skip to content
Snippets Groups Projects
Commit 87d185f3 authored by Piotr Krysiuk's avatar Piotr Krysiuk Committed by Cheng Jian
Browse files

bpf: Fix off-by-one for area size in creating mask to left

stable inclusion
from linux-4.19.182
commit ec5307f2ed2377fc55f0a8c990c6004c63014a54
CVE: CVE-2020-27171

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

commit 10d2bb2e6b1d8c4576c56a748f697dbeb8388899 upstream.

retrieve_ptr_limit() computes the ptr_limit for registers with stack and
map_value type. ptr_limit is the size of the memory area that is still
valid / in-bounds from the point of the current position and direction
of the operation (add / sub). This size will later be used for masking
the operation such that attempting out-of-bounds access in the speculative
domain is redirected to remain within the bounds of the current map value.

When masking to the right the size is correct, however, when masking to
the left, the size is off-by-one which would lead to an incorrect mask
and thus incorrect arithmetic operation in the non-speculative domain.
Piotr found that if the resulting alu_limit value is zero, then the
BPF_MOV32_IMM() from the fixup_bpf_calls() ...
parent 25907492
No related branches found
No related tags found
No related merge requests found
......@@ -2740,13 +2740,13 @@ static int retrieve_ptr_limit(const struct bpf_reg_state *ptr_reg,
case PTR_TO_STACK:
off = ptr_reg->off + ptr_reg->var_off.value;
if (mask_to_left)
*ptr_limit = MAX_BPF_STACK + off;
*ptr_limit = MAX_BPF_STACK + off + 1;
else
*ptr_limit = -off;
return 0;
case PTR_TO_MAP_VALUE:
if (mask_to_left) {
*ptr_limit = ptr_reg->umax_value + ptr_reg->off;
*ptr_limit = ptr_reg->umax_value + ptr_reg->off + 1;
} else {
off = ptr_reg->smin_value + ptr_reg->off;
*ptr_limit = ptr_reg->map_ptr->value_size - off;
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment