diff options
author | Daniel Borkmann <daniel@iogearbox.net> | 2022-01-05 22:35:13 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2022-01-27 13:03:51 +0300 |
commit | a65df848dbe083bfe1c01200b6b5038083824872 (patch) | |
tree | 3333dffb8cddc6802fc297c20dd81df9243aaba3 /kernel/bpf | |
parent | 073f7fb020b52832ab5a05d48fe1c9f73345652b (diff) | |
download | linux-a65df848dbe083bfe1c01200b6b5038083824872.tar.xz |
bpf: Don't promote bogus looking registers after null check.
[ Upstream commit e60b0d12a95dcf16a63225cead4541567f5cb517 ]
If we ever get to a point again where we convert a bogus looking <ptr>_or_null
typed register containing a non-zero fixed or variable offset, then lets not
reset these bounds to zero since they are not and also don't promote the register
to a <ptr> type, but instead leave it as <ptr>_or_null. Converting to a unknown
register could be an avenue as well, but then if we run into this case it would
allow to leak a kernel pointer this way.
Fixes: f1174f77b50c ("bpf/verifier: rework value tracking")
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'kernel/bpf')
-rw-r--r-- | kernel/bpf/verifier.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 18c75d6d9896..7be72682dfda 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8771,15 +8771,15 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state, { if (reg_type_may_be_null(reg->type) && reg->id == id && !WARN_ON_ONCE(!reg->id)) { - /* Old offset (both fixed and variable parts) should - * have been known-zero, because we don't allow pointer - * arithmetic on pointers that might be NULL. - */ if (WARN_ON_ONCE(reg->smin_value || reg->smax_value || !tnum_equals_const(reg->var_off, 0) || reg->off)) { - __mark_reg_known_zero(reg); - reg->off = 0; + /* Old offset (both fixed and variable parts) should + * have been known-zero, because we don't allow pointer + * arithmetic on pointers that might be NULL. If we + * see this happening, don't convert the register. + */ + return; } if (is_null) { reg->type = SCALAR_VALUE; |