bpf: improve dead code sanitizing
authorDaniel Borkmann <daniel@iogearbox.net>
Fri, 26 Jan 2018 22:33:37 +0000 (23:33 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 27 Jan 2018 00:42:05 +0000 (16:42 -0800)
commit2a5418a13fcfbb1f13a847eedb9a8e30a9ead765
tree763875aa5d2f111b1668ef1706c4d0d7e8587dbb
parent1d621674d923790d09cab9e2c7da7da6446a6257
bpf: improve dead code sanitizing

Given we recently had c131187db2d3 ("bpf: fix branch pruning
logic") and 95a762e2c8c9 ("bpf: fix incorrect sign extension in
check_alu_op()") in particular where before verifier skipped
verification of the wrongly assumed dead branch, we should not
just replace the dead code parts with nops (mov r0,r0). If there
is a bug such as fixed in 95a762e2c8c9 in future again, where
runtime could execute those insns, then one of the potential
issues with the current setting would be that given the nops
would be at the end of the program, we could execute out of
bounds at some point.

The best in such case would be to just exit the BPF program
altogether and return an exception code. However, given this
would require two instructions, and such a dead code gap could
just be a single insn long, we would need to place 'r0 = X; ret'
snippet at the very end after the user program or at the start
before the program (where we'd skip that region on prog entry),
and then place unconditional ja's into the dead code gap.

While more complex but possible, there's still another block
in the road that currently prevents from this, namely BPF to
BPF calls. The issue here is that such exception could be
returned from a callee, but the caller would not know that
it's an exception that needs to be propagated further down.
Alternative that has little complexity is to just use a ja-1
code for now which will trap the execution here instead of
silently doing bad things if we ever get there due to bugs.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c