mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00

Previously, the verifier was treating all PTR_TO_STACK registers passed to a helper call as potentially written to by the helper. However, all calls to check_stack_range_initialized() already have precise access type information available. Rather than treat ACCESS_HELPER as a proxy for BPF_WRITE, pass enum bpf_access_type to check_stack_range_initialized() to more precisely track helper arguments. One benefit from this precision is that registers tracked as valid spills and passed as a read-only helper argument remain tracked after the call. Rather than being marked STACK_MISC afterwards. An additional benefit is the verifier logs are also more precise. For this particular error, users will enjoy a slightly clearer message. See included selftest updates for examples. Acked-by: Eduard Zingerman <eddyz87@gmail.com> Signed-off-by: Daniel Xu <dxu@dxuuu.xyz> Link: https://lore.kernel.org/r/ff885c0e5859e0cd12077c3148ff0754cad4f7ed.1736886479.git.dxu@dxuuu.xyz Signed-off-by: Alexei Starovoitov <ast@kernel.org>
35 lines
601 B
C
35 lines
601 B
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
#include <stddef.h>
|
|
#include <linux/bpf.h>
|
|
#include <bpf/bpf_helpers.h>
|
|
#include "bpf_misc.h"
|
|
|
|
#if !defined(__clang__)
|
|
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
|
#endif
|
|
|
|
struct Small {
|
|
long x;
|
|
};
|
|
|
|
struct Big {
|
|
long x;
|
|
long y;
|
|
};
|
|
|
|
__noinline int foo(const struct Big *big)
|
|
{
|
|
if (!big)
|
|
return 0;
|
|
|
|
return bpf_get_prandom_u32() < big->y;
|
|
}
|
|
|
|
SEC("cgroup_skb/ingress")
|
|
__failure __msg("invalid read from stack")
|
|
int global_func10(struct __sk_buff *skb)
|
|
{
|
|
const struct Small small = {.x = skb->len };
|
|
|
|
return foo((struct Big *)&small) ? 1 : 0;
|
|
}
|