Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Move PTR_TO_STACK alignment check to process_dynptr_func

After previous commit, we are minimizing helper specific assumptions
from check_func_arg_reg_off, making it generic, and offloading checks
for a specific argument type to their respective functions called after
check_func_arg_reg_off has been called.

This allows relying on a consistent set of guarantees after that call
and then relying on them in code that deals with registers for each
argument type later. This is in line with how process_spin_lock,
process_timer_func, process_kptr_func check reg->var_off to be constant.
The same reasoning is used here to move the alignment check into
process_dynptr_func. Note that it also needs to check for constant
var_off, and accumulate the constant var_off when computing the spi in
get_spi, but that fix will come in later changes.

Acked-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20221207204141.308952-6-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Kumar Kartikeya Dwivedi and committed by
Alexei Starovoitov
f6ee298f 184c9bdb

+8 -5
+8 -5
kernel/bpf/verifier.c
··· 5932 5932 verbose(env, "verifier internal error: misconfigured dynptr helper type flags\n"); 5933 5933 return -EFAULT; 5934 5934 } 5935 + /* CONST_PTR_TO_DYNPTR already has fixed and var_off as 0 due to 5936 + * check_func_arg_reg_off's logic. We only need to check offset 5937 + * alignment for PTR_TO_STACK. 5938 + */ 5939 + if (reg->type == PTR_TO_STACK && (reg->off % BPF_REG_SIZE)) { 5940 + verbose(env, "cannot pass in dynptr at an offset=%d\n", reg->off); 5941 + return -EINVAL; 5942 + } 5935 5943 /* MEM_UNINIT - Points to memory that is an appropriate candidate for 5936 5944 * constructing a mutable bpf_dynptr object. 5937 5945 * ··· 6309 6301 switch (type) { 6310 6302 /* Pointer types where both fixed and variable offset is explicitly allowed: */ 6311 6303 case PTR_TO_STACK: 6312 - if (arg_type_is_dynptr(arg_type) && reg->off % BPF_REG_SIZE) { 6313 - verbose(env, "cannot pass in dynptr at an offset\n"); 6314 - return -EINVAL; 6315 - } 6316 - fallthrough; 6317 6304 case PTR_TO_PACKET: 6318 6305 case PTR_TO_PACKET_META: 6319 6306 case PTR_TO_MAP_KEY: