lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <02ce3f503df3446ef1fcfa9338fa5e42b952b13f.camel@redhat.com> Date: Tue, 09 May 2023 10:10:33 +0200 From: Paolo Abeni <pabeni@...hat.com> To: "t.feng" <fengtao40@...wei.com>, netdev@...r.kernel.org, lucien.xin@...il.com, luwei32@...wei.com, kuba@...nel.org, edumazet@...gle.com, davem@...emloft.net Cc: yanan@...wei.com, fw@...len.de Subject: Re: [PATCH] ipvlan:Fix out-of-bounds caused by unclear skb->cb Hi, The patch idea LGTM, but there a few formal things that IMHO should be adjusted, please see below. On Mon, 2023-05-08 at 16:47 +0800, t.feng wrote: > If skb enqueue the qdisc, fq_skb_cb(skb)->time_to_send is changed which > is actually skb->cb, and IPCB(skb_in)->opt will be used in > __ip_options_echo. It is possible that memcpy is out of bounds and lead > to stack overflow. > We should clear skb->cb before ip_local_out or ip6_local_out. > > Stack info: > crash on stable-5.10(reproduce in kasan kernel). > ------------[ cut here ]------------ IIRC the above separator can introduce issues with some patch management tools, please drop it here and below. > [ 2203.651571] BUG: KASAN: stack-out-of-bounds in > __ip_options_echo+0x589/0x800 > [ 2203.653327] Write of size 4 at addr ffff88811a388f27 by task > swapper/3/0 > > [ 2203.655460] CPU: 3 PID: 0 Comm: swapper/3 Kdump: loaded Not tainted > 5.10.0-60.18.0.50.h856.kasan.eulerosv2r11.x86_64 #1 > [ 2203.655466] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), > BIOS rel-1.10.2-0-g5f4c7b1-20181220_000000-szxrtosci10000 04/01/2014 > [ 2203.655475] Call Trace: > [ 2203.655481] <IRQ> > [ 2203.655501] dump_stack+0x9c/0xd3 > [ 2203.655514] print_address_description.constprop.0+0x19/0x170 > [ 2203.655522] ? __ip_options_echo+0x589/0x800 > [ 2203.655530] __kasan_report.cold+0x6c/0x84 > [ 2203.655569] ? resolve_normal_ct+0x301/0x430 [nf_conntrack] > [ 2203.655576] ? __ip_options_echo+0x589/0x800 IMHO it's better if you drop the irrelevant entries - those including ' ? ' - so that the backtrace is smaller and easier to read. > [ 2203.655586] kasan_report+0x3a/0x50 > [ 2203.655594] check_memory_region+0xfd/0x1f0 > [ 2203.655601] memcpy+0x39/0x60 > [ 2203.655608] __ip_options_echo+0x589/0x800 > [ 2203.655616] ? ip_options_build+0x390/0x390 > [ 2203.655628] ? _raw_spin_trylock+0x91/0xe0 > [ 2203.655635] ? _raw_spin_lock_bh+0xe0/0xe0 > [ 2203.655647] ? icmp_global_allow+0x9d/0x120 > [ 2203.655654] __icmp_send+0x59a/0x960 > [ 2203.655662] ? icmpv4_global_allow+0x90/0x90 > [ 2203.655675] ? nf_nat_cleanup_conntrack+0xe0/0xe0 [nf_nat] > [ 2203.655702] ? tcp_print_conntrack+0xb0/0xb0 [nf_conntrack] > [ 2203.655709] ? memset+0x20/0x50 > [ 2203.655719] ? nf_nat_setup_info+0x2fb/0x480 [nf_nat] > [ 2203.655729] ? get_unique_tuple+0x390/0x390 [nf_nat] > [ 2203.655735] ? tcp_mt+0x456/0x550 > [ 2203.655747] ? ipt_do_table+0x776/0xa40 [ip_tables] > [ 2203.655755] nf_send_unreach+0x129/0x3d0 [nf_reject_ipv4] > [ 2203.655763] reject_tg+0x77/0x1bf [ipt_REJECT] > [ 2203.655772] ipt_do_table+0x691/0xa40 [ip_tables] > [ 2203.655783] ? ip_tables_net_init+0x20/0x20 [ip_tables] > [ 2203.655794] ? nf_nat_icmp_reply_translation+0x380/0x380 [nf_nat] > [ 2203.655804] ? nf_nat_ipv4_local_fn+0x1ba/0x290 [nf_nat] > [ 2203.655812] ? iptable_filter_net_pre_exit+0x50/0x50 [iptable_filter] > [ 2203.655821] nf_hook_slow+0x69/0x100 > [ 2203.655828] __ip_local_out+0x21e/0x2b0 > [ 2203.655836] ? ip_finish_output+0x190/0x190 > [ 2203.655842] ? ip_route_output_flow+0x114/0x1b0 > [ 2203.655850] ? ip_forward_options+0x330/0x330 > [ 2203.655857] ip_local_out+0x28/0x90 > [ 2203.655868] ipvlan_process_v4_outbound+0x21e/0x260 [ipvlan] > [ 2203.655878] ? ipvlan_process_v6_forward+0x280/0x280 [ipvlan] > [ 2203.655887] ? dst_release.part.0+0x3a/0xb0 > [ 2203.655931] ipvlan_xmit_mode_l3+0x3bd/0x400 [ipvlan] > [ 2203.655942] ? ipvlan_xmit_mode_l2+0x3a0/0x3a0 [ipvlan] > [ 2203.655950] ? skb_network_protocol+0xd5/0x2d0 > [ 2203.655957] ? skb_crc32c_csum_help+0x50/0x50 > [ 2203.655967] ipvlan_queue_xmit+0xb3/0x190 [ipvlan] > [ 2203.655977] ipvlan_start_xmit+0x2e/0xb0 [ipvlan] > [ 2203.655984] xmit_one.constprop.0+0xe1/0x280 > [ 2203.655992] dev_hard_start_xmit+0x62/0x100 > [ 2203.656000] sch_direct_xmit+0x215/0x640 > [ 2203.656009] ? pvclock_clocksource_read+0xf6/0x1d0 > [ 2203.656015] ? qdisc_free_cb+0x80/0x80 > [ 2203.656022] ? dequeue_skb+0x1d7/0x810 > [ 2203.656028] __qdisc_run+0x153/0x1f0 > [ 2203.656035] ? sch_direct_xmit+0x640/0x640 > [ 2203.656046] ? netem_dequeue+0x621/0x700 [sch_netem] > [ 2203.656053] ? _raw_spin_lock+0x7a/0xd0 > [ 2203.656060] ? _raw_spin_lock_irq+0xd0/0xd0 > [ 2203.656069] __dev_queue_xmit+0x77f/0x1030 > [ 2203.656082] ? netdev_core_pick_tx+0x160/0x160 > [ 2203.656126] ? stack_trace_consume_entry+0x60/0x90 > [ 2203.656139] ? pollwake+0x123/0x180 > [ 2203.656159] ? selinux_peerlbl_enabled+0x81/0x90 > [ 2203.656173] ip_finish_output2+0x59b/0xc20 > [ 2203.656184] ? ip_rcv+0xbf/0x1b0 > [ 2203.656195] ? ip_reply_glue_bits+0x80/0x80 > [ 2203.656206] ? napi_poll+0x14f/0x420 > [ 2203.656213] ? __do_softirq+0xfd/0x402 > [ 2203.656220] ? asm_call_irq_on_stack+0x12/0x20 > [ 2203.656228] ? do_softirq_own_stack+0x37/0x50 > [ 2203.656235] ? get_stack_info_noinstr+0x14/0x110 > [ 2203.656244] __ip_finish_output.part.0+0x318/0x3d0 > [ 2203.656258] ? ip_finish_output_gso+0x130/0x130 > [ 2203.656277] ? get_stack_info+0x32/0xa0 > [ 2203.656289] ? get_stack_info_noinstr+0x14/0x110 > [ 2203.656301] ? get_stack_info_noinstr+0x14/0x110 > [ 2203.656312] ip_finish_output+0x168/0x190 > [ 2203.656320] ip_output+0x12d/0x220 > [ 2203.656327] ? ip_mc_output+0x500/0x500 > [ 2203.656335] ? secondary_startup_64_no_verify+0xc2/0xcb > [ 2203.656343] ? __ip_finish_output+0xb0/0xb0 > [ 2203.656349] ? ipv4_dst_check+0x8b/0xb0 > [ 2203.656357] __ip_queue_xmit+0x392/0x880 > [ 2203.656369] ? __ip_queue_xmit+0x880/0x880 > [ 2203.656380] __tcp_transmit_skb+0x1088/0x11c0 > [ 2203.656395] ? tcp_event_new_data_sent+0x190/0x190 > [ 2203.656402] ? __tcp_select_window+0x490/0x490 > [ 2203.656407] ? tcp_trim_head+0x240/0x240 > [ 2203.656414] ? ipv4_dst_check+0x8b/0xb0 > [ 2203.656421] ? tcp_retrans_try_collapse+0x58/0x200 > [ 2203.656428] ? __sk_dst_check+0x7f/0xe0 > [ 2203.656436] __tcp_retransmit_skb+0x475/0xa30 > [ 2203.656452] ? tcp_retrans_try_collapse+0x200/0x200 > [ 2203.656465] ? tcp_mark_skb_lost+0x158/0x1c0 > [ 2203.656477] ? rb_next+0x1e/0x90 > [ 2203.656484] ? tcp_timeout_mark_lost+0x1b7/0x230 > [ 2203.656492] ? bictcp_cwnd_event+0x15/0xa0 > [ 2203.656498] ? bictcp_state+0x18c/0x1a0 > [ 2203.656505] tcp_retransmit_skb+0x2d/0x190 > [ 2203.656512] tcp_retransmit_timer+0x3af/0x9a0 > [ 2203.656519] tcp_write_timer_handler+0x3ba/0x510 > [ 2203.656529] tcp_write_timer+0x55/0x180 > [ 2203.656536] ? tcp_write_timer_handler+0x510/0x510 > [ 2203.656542] call_timer_fn+0x3f/0x1d0 > [ 2203.656549] ? tcp_write_timer_handler+0x510/0x510 > [ 2203.656555] expire_timers+0x160/0x200 > [ 2203.656562] run_timer_softirq+0x1f4/0x480 > [ 2203.656569] ? expire_timers+0x200/0x200 > [ 2203.656576] ? pvclock_clocksource_read+0xf6/0x1d0 > [ 2203.656584] ? kvm_sched_clock_read+0xd/0x20 > [ 2203.656590] ? sched_clock+0x5/0x10 > [ 2203.656598] ? sched_clock_cpu+0x18/0x130 > [ 2203.656606] __do_softirq+0xfd/0x402 > [ 2203.656613] asm_call_irq_on_stack+0x12/0x20 > [ 2203.656617] </IRQ> > [ 2203.656623] do_softirq_own_stack+0x37/0x50 > [ 2203.656631] irq_exit_rcu+0x134/0x1a0 > [ 2203.656639] sysvec_apic_timer_interrupt+0x36/0x80 > [ 2203.656646] asm_sysvec_apic_timer_interrupt+0x12/0x20 > [ 2203.656654] RIP: 0010:default_idle+0x13/0x20 > [ 2203.656663] Code: 89 f0 5d 41 5c 41 5d 41 5e c3 cc cc cc cc cc cc cc > cc cc cc cc cc cc 0f 1f 44 00 00 0f 1f 44 00 00 0f 00 2d 9f 32 57 00 fb > f4 <c3> cc cc cc cc 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 41 54 be 08 > [ 2203.656668] RSP: 0018:ffff88810036fe78 EFLAGS: 00000256 > [ 2203.656676] RAX: ffffffffaf2a87f0 RBX: ffff888100360000 RCX: > ffffffffaf290191 > [ 2203.656681] RDX: 0000000000098b5e RSI: 0000000000000004 RDI: > ffff88811a3c4f60 > [ 2203.656686] RBP: 0000000000000000 R08: 0000000000000001 R09: > ffff88811a3c4f63 > [ 2203.656690] R10: ffffed10234789ec R11: 0000000000000001 R12: > 0000000000000003 > [ 2203.656695] R13: ffff888100360000 R14: 0000000000000000 R15: > 0000000000000000 > [ 2203.656703] ? __cpuidle_text_start+0x8/0x8 > [ 2203.656713] ? rcu_eqs_enter.constprop.0+0x81/0xa0 > [ 2203.656722] ? __cpuidle_text_start+0x8/0x8 > [ 2203.656729] default_idle_call+0x5a/0x150 > [ 2203.656735] cpuidle_idle_call+0x1c6/0x220 > [ 2203.656742] ? arch_cpu_idle_exit+0x40/0x40 > [ 2203.656748] ? kvm_sched_clock_read+0xd/0x20 > [ 2203.656754] ? sched_clock+0x5/0x10 > [ 2203.656760] ? sched_clock_cpu+0x18/0x130 > [ 2203.656767] ? kvm_clock_get_cycles+0xd/0x20 > [ 2203.656774] ? tsc_verify_tsc_adjust+0x11f/0x160 > [ 2203.656780] do_idle+0xab/0x100 > [ 2203.656786] cpu_startup_entry+0x19/0x20 > [ 2203.656793] secondary_startup_64_no_verify+0xc2/0xcb > > [ 2203.657409] The buggy address belongs to the page: > [ 2203.658648] page:0000000027a9842f refcount:1 mapcount:0 > mapping:0000000000000000 index:0x0 pfn:0x11a388 > [ 2203.658665] flags: > 0x17ffffc0001000(reserved|node=0|zone=2|lastcpupid=0x1fffff) > [ 2203.658675] raw: 0017ffffc0001000 ffffea000468e208 ffffea000468e208 > 0000000000000000 > [ 2203.658682] raw: 0000000000000000 0000000000000000 00000001ffffffff > 0000000000000000 > [ 2203.658686] page dumped because: kasan: bad access detected > ------------[ cut here ]----------- > > To reproduce(ipvlan with IPVLAN_MODE_L3): > Env setting: > ======================================================= > modprobe ipvlan ipvlan_default_mode=1 > sysctl net.ipv4.conf.eth0.forwarding=1 > iptables -t nat -A POSTROUTING -s 20.0.0.0/255.255.255.0 -o eth0 -j > MASQUERADE > ip link add gw link eth0 type ipvlan > ip -4 addr add 20.0.0.254/24 dev gw > ip netns add net1 > ip link add ipv1 link eth0 type ipvlan > ip link set ipv1 netns net1 > ip netns exec net1 ip link set ipv1 up > ip netns exec net1 ip -4 addr add 20.0.0.4/24 dev ipv1 > ip netns exec net1 route add default gw 20.0.0.254 > ip netns exec net1 tc qdisc add dev ipv1 root netem loss 10% > ifconfig gw up > iptables -t filter -A OUTPUT -p tcp --dport 8888 -j REJECT --reject-with > icmp-port-unreachable > ======================================================= > And then excute the shell(curl any address of eth0 can reach): > > for((i=1;i<=100000;i++)) > do > ip netns exec net1 curl x.x.x.x:8888 > done > ======================================================= > > Signed-off-by: "t.feng" <fengtao40@...wei.com> > Suggested-by: Florian Westphal <fw@...len.de> Please include a suitable Fixes tag. > --- > drivers/net/ipvlan/ipvlan_core.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c > index 460b3d4f2245..9937d9f3df72 100644 > --- a/drivers/net/ipvlan/ipvlan_core.c > +++ b/drivers/net/ipvlan/ipvlan_core.c > @@ -436,6 +436,9 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb) > goto err; > } > skb_dst_set(skb, &rt->dst); > + > + memset(skb->cb, 0, sizeof(struct inet_skb_parm)); The preferred style to clear the inet cb is: memset(IPCB(skb), 0, sizeof(*IPCB(skb))); which generates exactly the same code, but is more grep friendly. > + > err = ip_local_out(net, skb->sk, skb); > if (unlikely(net_xmit_eval(err))) > dev->stats.tx_errors++; > @@ -474,6 +477,9 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb) > goto err; > } > skb_dst_set(skb, dst); > + > + memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); and here: memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); Cheers, Paolo
Powered by blists - more mailing lists