OSDN Git Service

bpf: Disallow NULLable pointers for trusted kfuncs
authorDavid Vernet <void@manifault.com>
Wed, 25 Jan 2023 14:38:10 +0000 (08:38 -0600)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 25 Jan 2023 15:57:49 +0000 (07:57 -0800)
commitcaf713c338bd95bf9ac003d8985d2c4e46d452dd
tree34e0b14bdee625598bbde4936ff473102883db00
parentb613d335a743cf0e0ef0ccba9ad129904e2a26fb
bpf: Disallow NULLable pointers for trusted kfuncs

KF_TRUSTED_ARGS kfuncs currently have a subtle and insidious bug in
validating pointers to scalars. Say that you have a kfunc like the
following, which takes an array as the first argument:

bool bpf_cpumask_empty(const struct cpumask *cpumask)
{
return cpumask_empty(cpumask);
}

...
BTF_ID_FLAGS(func, bpf_cpumask_empty, KF_TRUSTED_ARGS)
...

If a BPF program were to invoke the kfunc with a NULL argument, it would
crash the kernel. The reason is that struct cpumask is defined as a
bitmap, which is itself defined as an array, and is accessed as a memory
address by bitmap operations. So when the verifier analyzes the
register, it interprets it as a pointer to a scalar struct, which is an
array of size 8. check_mem_reg() then sees that the register is NULL and
returns 0, and the kfunc crashes when it passes it down to the cpumask
wrappers.

To fix this, this patch adds a check for KF_ARG_PTR_TO_MEM which
verifies that the register doesn't contain a possibly-NULL pointer if
the kfunc is KF_TRUSTED_ARGS.

Signed-off-by: David Vernet <void@manifault.com>
Link: https://lore.kernel.org/r/20230125143816.721952-2-void@manifault.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c
tools/testing/selftests/bpf/prog_tests/cgrp_kfunc.c
tools/testing/selftests/bpf/progs/task_kfunc_failure.c