Star64_linux/kernel
Yonghong Song 01c66c48d4 bpf: Fix an incorrect branch elimination by verifier
Wenbo reported an issue in [1] where a checking of null
pointer is evaluated as always false. In this particular
case, the program type is tp_btf and the pointer to
compare is a PTR_TO_BTF_ID.

The current verifier considers PTR_TO_BTF_ID always
reprents a non-null pointer, hence all PTR_TO_BTF_ID compares
to 0 will be evaluated as always not-equal, which resulted
in the branch elimination.

For example,
 struct bpf_fentry_test_t {
     struct bpf_fentry_test_t *a;
 };
 int BPF_PROG(test7, struct bpf_fentry_test_t *arg)
 {
     if (arg == 0)
         test7_result = 1;
     return 0;
 }
 int BPF_PROG(test8, struct bpf_fentry_test_t *arg)
 {
     if (arg->a == 0)
         test8_result = 1;
     return 0;
 }

In above bpf programs, both branch arg == 0 and arg->a == 0
are removed. This may not be what developer expected.

The bug is introduced by Commit cac616db39 ("bpf: Verifier
track null pointer branch_taken with JNE and JEQ"),
where PTR_TO_BTF_ID is considered to be non-null when evaluting
pointer vs. scalar comparison. This may be added
considering we have PTR_TO_BTF_ID_OR_NULL in the verifier
as well.

PTR_TO_BTF_ID_OR_NULL is added to explicitly requires
a non-NULL testing in selective cases. The current generic
pointer tracing framework in verifier always
assigns PTR_TO_BTF_ID so users does not need to
check NULL pointer at every pointer level like a->b->c->d.

We may not want to assign every PTR_TO_BTF_ID as
PTR_TO_BTF_ID_OR_NULL as this will require a null test
before pointer dereference which may cause inconvenience
for developers. But we could avoid branch elimination
to preserve original code intention.

This patch simply removed PTR_TO_BTD_ID from reg_type_not_null()
in verifier, which prevented the above branches from being eliminated.

 [1]: https://lore.kernel.org/bpf/79dbb7c0-449d-83eb-5f4f-7af0cc269168@fb.com/T/

Fixes: cac616db39 ("bpf: Verifier track null pointer branch_taken with JNE and JEQ")
Reported-by: Wenbo Zhang <ethercflow@gmail.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Acked-by: Andrii Nakryiko <andriin@fb.com>
Link: https://lore.kernel.org/bpf/20200630171240.2523722-1-yhs@fb.com
2020-06-30 22:21:05 +02:00
..
bpf bpf: Fix an incorrect branch elimination by verifier 2020-06-30 22:21:05 +02:00
cgroup mmap locking API: convert mmap_sem comments 2020-06-09 09:39:14 -07:00
configs
debug kernel: rename show_stack_loglvl() => show_stack() 2020-06-09 09:39:13 -07:00
dma dma-mapping: Add a new dma_need_sync API 2020-06-30 15:44:03 +02:00
events Merge branch 'akpm' (patches from Andrew) 2020-06-09 09:54:46 -07:00
gcov treewide: replace '---help---' in Kconfig files with 'help' 2020-06-14 01:57:21 +09:00
irq treewide: replace '---help---' in Kconfig files with 'help' 2020-06-14 01:57:21 +09:00
kcsan kcsan: Support distinguishing volatile accesses 2020-06-11 20:04:01 +02:00
livepatch
locking The X86 entry, exception and interrupt code rework 2020-06-13 10:05:47 -07:00
power treewide: replace '---help---' in Kconfig files with 'help' 2020-06-14 01:57:21 +09:00
printk One more printk change for 5.8 2020-06-12 12:13:36 -07:00
rcu TTY/Serial driver updates for 5.8-rc1 2020-06-07 09:52:36 -07:00
sched Rebase locking/kcsan to locking/urgent 2020-06-11 20:02:46 +02:00
time The X86 entry, exception and interrupt code rework 2020-06-13 10:05:47 -07:00
trace Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 2020-06-17 13:26:55 -07:00
.gitignore
acct.c mmap locking API: convert mmap_sem comments 2020-06-09 09:39:14 -07:00
async.c
audit.c
audit.h
audit_fsnotify.c
audit_tree.c
audit_watch.c
auditfilter.c
auditsc.c
backtracetest.c
bounds.c
capability.c
compat.c
configs.c
context_tracking.c context_tracking: Ensure that the critical path cannot be instrumented 2020-06-11 15:14:36 +02:00
cpu.c The changes in this cycle are: 2020-06-03 13:06:42 -07:00
cpu_pm.c
crash_core.c
crash_dump.c
cred.c
delayacct.c
dma.c
elfcore.c
exec_domain.c
exit.c mmap locking API: convert mmap_sem comments 2020-06-09 09:39:14 -07:00
extable.c
fail_function.c
fork.c mmap locking API: convert nested write lock sites 2020-06-09 09:39:14 -07:00
freezer.c
futex.c mmap locking API: use coccinelle to convert mmap_sem rwsem call sites 2020-06-09 09:39:14 -07:00
gen_kheaders.sh kbuild: add variables for compression tools 2020-06-06 23:42:01 +09:00
groups.c
hung_task.c kernel/hung_task.c: introduce sysctl to print all traces when a hung task is detected 2020-06-08 11:05:56 -07:00
iomem.c
irq_work.c
jump_label.c
kallsyms.c
kcmp.c
Kconfig.freezer
Kconfig.hz
Kconfig.locks
Kconfig.preempt
kcov.c kcov: check kcov_softirq in kcov_remote_stop() 2020-06-10 19:14:17 -07:00
kexec.c
kexec_core.c
kexec_elf.c
kexec_file.c kexec_file: don't place kexec images on IORESOURCE_MEM_DRIVER_MANAGED 2020-06-04 19:06:23 -07:00
kexec_internal.h
kheaders.c
kmod.c
kprobes.c kernel/kprobes.c: convert to use DEFINE_SEQ_ATTRIBUTE macro 2020-06-04 19:06:26 -07:00
ksysfs.c
kthread.c Merge branch 'akpm' (patches from Andrew) 2020-06-11 13:25:53 -07:00
latencytop.c
Makefile Notifications over pipes + Keyring notifications 2020-06-13 09:56:21 -07:00
module-internal.h
module.c module: move the set_fs hack for flush_icache_range to m68k 2020-06-08 11:05:58 -07:00
module_signature.c
module_signing.c
notifier.c
nsproxy.c
padata.c padata: add basic support for multithreaded jobs 2020-06-03 20:09:45 -07:00
panic.c bug: Annotate WARN/BUG/stackfail as noinstr safe 2020-06-11 15:14:36 +02:00
params.c
pid.c
pid_namespace.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next 2020-06-03 16:27:18 -07:00
profile.c
ptrace.c
range.c
reboot.c
relay.c mmap locking API: convert mmap_sem comments 2020-06-09 09:39:14 -07:00
resource.c
rseq.c
scs.c scs: Report SCS usage in bytes rather than number of entries 2020-06-04 16:14:56 +01:00
seccomp.c
signal.c
smp.c The changes in this cycle are: 2020-06-03 13:06:42 -07:00
smpboot.c
smpboot.h
softirq.c x86/entry: Clarify irq_{enter,exit}_rcu() 2020-06-11 15:15:24 +02:00
stackleak.c
stacktrace.c
stop_machine.c
sys.c Add additional LSM hooks for SafeSetID 2020-06-14 11:39:31 -07:00
sys_ni.c
sysctl-test.c
sysctl.c kernel/sysctl.c: ignore out-of-range taint bits introduced via kernel.tainted 2020-06-08 11:05:56 -07:00
sysctl_binary.c
task_work.c
taskstats.c
test_kprobes.c
torture.c
tracepoint.c
tsacct.c
ucount.c
uid16.c
uid16.h
umh.c
up.c
user-return-notifier.c
user.c user.c: make uidhash_table static 2020-06-04 19:06:24 -07:00
user_namespace.c
utsname.c
utsname_sysctl.c
watch_queue.c Notifications over pipes + Keyring notifications 2020-06-13 09:56:21 -07:00
watchdog.c kernel/watchdog.c: convert {soft/hard}lockup boot parameters to sysctl aliases 2020-06-08 11:05:56 -07:00
watchdog_hld.c
workqueue.c
workqueue_internal.h