mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-31 08:28:13 +00:00
54ea6079b7
It is a simplified example that can trigger a 32bit scalar spill. The const scalar is refilled and added to a skb->data later. Since the reg state of the 32bit scalar spill is not saved now, adding the refilled reg to skb->data and then comparing it with skb->data_end cannot verify the skb->data access. With the earlier verifier patch and the llvm patch [1]. The verifier can correctly verify the bpf prog. Here is the snippet of the verifier log that leads to verifier conclusion that the packet data is unsafe to read. The log is from the kerne without the previous verifier patch to save the <8-byte scalar spill. 67: R0=inv1 R1=inv17 R2=invP2 R3=inv1 R4=pkt(id=0,off=68,r=102,imm=0) R5=inv102 R6=pkt(id=0,off=62,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 67: (63) *(u32 *)(r10 -12) = r5 68: R0=inv1 R1=inv17 R2=invP2 R3=inv1 R4=pkt(id=0,off=68,r=102,imm=0) R5=inv102 R6=pkt(id=0,off=62,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmm???? ... 101: R0_w=map_value_or_null(id=2,off=0,ks=16,vs=1,imm=0) R6_w=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmmmmmm 101: (61) r1 = *(u32 *)(r10 -12) 102: R0_w=map_value_or_null(id=2,off=0,ks=16,vs=1,imm=0) R1_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6_w=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmmmmmm 102: (bc) w1 = w1 103: R0_w=map_value_or_null(id=2,off=0,ks=16,vs=1,imm=0) R1_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6_w=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=0,off=0,r=102,imm=0) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmmmmmm 103: (0f) r7 += r1 last_idx 103 first_idx 67 regs=2 stack=0 before 102: (bc) w1 = w1 regs=2 stack=0 before 101: (61) r1 = *(u32 *)(r10 -12) 104: R0_w=map_value_or_null(id=2,off=0,ks=16,vs=1,imm=0) R1_w=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6_w=pkt(id=0,off=70,r=102,imm=0) R7_w=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9=inv17 R10=fp0 fp-16=mmmmmmmm ... 127: R0_w=inv1 R1=invP(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9_w=invP17 R10=fp0 fp-16=mmmmmmmm 127: (bf) r1 = r7 128: R0_w=inv1 R1_w=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9_w=invP17 R10=fp0 fp-16=mmmmmmmm 128: (07) r1 += 8 129: R0_w=inv1 R1_w=pkt(id=3,off=8,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9_w=invP17 R10=fp0 fp-16=mmmmmmmm 129: (b4) w0 = 1 130: R0=inv1 R1=pkt(id=3,off=8,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9=invP17 R10=fp0 fp-16=mmmmmmmm 130: (2d) if r1 > r8 goto pc-66 R0=inv1 R1=pkt(id=3,off=8,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9=invP17 R10=fp0 fp-16=mmmmmmmm 131: R0=inv1 R1=pkt(id=3,off=8,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R6=pkt(id=0,off=70,r=102,imm=0) R7=pkt(id=3,off=0,r=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R8=pkt_end(id=0,off=0,imm=0) R9=invP17 R10=fp0 fp-16=mmmmmmmm 131: (69) r6 = *(u16 *)(r7 +0) invalid access to packet, off=0 size=2, R7(id=3,off=0,r=0) R7 offset is outside of the packet [1]: https://reviews.llvm.org/D109073 Signed-off-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://lore.kernel.org/bpf/20210922004947.626286-1-kafai@fb.com |
||
---|---|---|
.. | ||
.gitignore | ||
align.c | ||
atomic_bounds.c | ||
atomics.c | ||
attach_probe.c | ||
autoload.c | ||
bind_perm.c | ||
bpf_cookie.c | ||
bpf_iter.c | ||
bpf_iter_setsockopt.c | ||
bpf_obj_id.c | ||
bpf_tcp_ca.c | ||
bpf_verif_scale.c | ||
btf.c | ||
btf_dedup_split.c | ||
btf_dump.c | ||
btf_endian.c | ||
btf_map_in_map.c | ||
btf_module.c | ||
btf_skc_cls_ingress.c | ||
btf_split.c | ||
btf_tag.c | ||
btf_write.c | ||
cg_storage_multi.c | ||
cgroup_attach_autodetach.c | ||
cgroup_attach_multi.c | ||
cgroup_attach_override.c | ||
cgroup_link.c | ||
cgroup_skb_sk_lookup.c | ||
cgroup_v1v2.c | ||
check_mtu.c | ||
cls_redirect.c | ||
connect_force_port.c | ||
core_autosize.c | ||
core_extern.c | ||
core_read_macros.c | ||
core_reloc.c | ||
core_retro.c | ||
cpu_mask.c | ||
d_path.c | ||
enable_stats.c | ||
endian.c | ||
fentry_fexit.c | ||
fentry_test.c | ||
fexit_bpf2bpf.c | ||
fexit_sleep.c | ||
fexit_stress.c | ||
fexit_test.c | ||
flow_dissector.c | ||
flow_dissector_load_bytes.c | ||
flow_dissector_reattach.c | ||
for_each.c | ||
get_branch_snapshot.c | ||
get_func_ip_test.c | ||
get_stack_raw_tp.c | ||
get_stackid_cannot_attach.c | ||
global_data.c | ||
global_data_init.c | ||
global_func_args.c | ||
hash_large_key.c | ||
hashmap.c | ||
kfree_skb.c | ||
kfunc_call.c | ||
ksyms.c | ||
ksyms_btf.c | ||
ksyms_module.c | ||
l4lb_all.c | ||
link_pinning.c | ||
linked_funcs.c | ||
linked_maps.c | ||
linked_vars.c | ||
load_bytes_relative.c | ||
lookup_and_delete.c | ||
map_init.c | ||
map_lock.c | ||
map_ptr.c | ||
metadata.c | ||
migrate_reuseport.c | ||
mmap.c | ||
modify_return.c | ||
module_attach.c | ||
netcnt.c | ||
netns_cookie.c | ||
ns_current_pid_tgid.c | ||
obj_name.c | ||
pe_preserve_elems.c | ||
perf_branches.c | ||
perf_buffer.c | ||
perf_event_stackmap.c | ||
perf_link.c | ||
pinning.c | ||
pkt_access.c | ||
pkt_md_access.c | ||
probe_read_user_str.c | ||
probe_user.c | ||
prog_run_xattr.c | ||
queue_stack_map.c | ||
raw_tp_test_run.c | ||
raw_tp_writable_reject_nbd_invalid.c | ||
raw_tp_writable_test_run.c | ||
rdonly_maps.c | ||
recursion.c | ||
reference_tracking.c | ||
resolve_btfids.c | ||
ringbuf.c | ||
ringbuf_multi.c | ||
section_names.c | ||
select_reuseport.c | ||
send_signal.c | ||
send_signal_sched_switch.c | ||
signal_pending.c | ||
sk_assign.c | ||
sk_lookup.c | ||
sk_storage_tracing.c | ||
skb_ctx.c | ||
skb_helpers.c | ||
skeleton.c | ||
snprintf.c | ||
snprintf_btf.c | ||
sock_fields.c | ||
socket_cookie.c | ||
sockmap_basic.c | ||
sockmap_ktls.c | ||
sockmap_listen.c | ||
sockopt.c | ||
sockopt_inherit.c | ||
sockopt_multi.c | ||
sockopt_qos_to_cc.c | ||
sockopt_sk.c | ||
spinlock.c | ||
stack_var_off.c | ||
stacktrace_build_id.c | ||
stacktrace_build_id_nmi.c | ||
stacktrace_map.c | ||
stacktrace_map_raw_tp.c | ||
static_linked.c | ||
subprogs.c | ||
syscall.c | ||
tailcalls.c | ||
task_fd_query_rawtp.c | ||
task_fd_query_tp.c | ||
task_local_storage.c | ||
task_pt_regs.c | ||
tc_bpf.c | ||
tc_redirect.c | ||
tcp_estats.c | ||
tcp_hdr_options.c | ||
tcp_rtt.c | ||
tcpbpf_user.c | ||
test_bpffs.c | ||
test_bprm_opts.c | ||
test_global_funcs.c | ||
test_ima.c | ||
test_local_storage.c | ||
test_lsm.c | ||
test_overhead.c | ||
test_profiler.c | ||
test_skb_pkt_end.c | ||
timer.c | ||
timer_mim.c | ||
tp_attach_query.c | ||
trace_ext.c | ||
trace_printk.c | ||
trace_vprintk.c | ||
trampoline_count.c | ||
udp_limit.c | ||
varlen.c | ||
vmlinux.c | ||
xdp.c | ||
xdp_adjust_tail.c | ||
xdp_attach.c | ||
xdp_bonding.c | ||
xdp_bpf2bpf.c | ||
xdp_context_test_run.c | ||
xdp_cpumap_attach.c | ||
xdp_devmap_attach.c | ||
xdp_info.c | ||
xdp_link.c | ||
xdp_noinline.c | ||
xdp_perf.c | ||
xdpwall.c |