
hulk inclusion category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBRT1V CVE: NA ------------------ The skb->cb may be modified in qdisc enqueue() functions, like fq_enqueue and sfb_enqueue. So the cb field should not be visited as IP6CB() after qdisc dequeue(). However, decode_session6() visit IP6CB(skb). If qdisc enqueue() modify the cb field, IP6CB(skb)->nhoff may be also modified, which may trigger a KASAN issue. The stack information is as follows: dump_backtrace+0x12c/0x220 arch/arm64/kernel/stacktrace.c:233 show_stack+0x34/0x50 arch/arm64/kernel/stacktrace.c:240 __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0x80/0x118 lib/dump_stack.c:106 print_address_description.constprop.0+0x84/0x3c8 mm/kasan/report.c:364 print_report+0xb0/0x280 mm/kasan/report.c:475 kasan_report+0x84/0xd0 mm/kasan/report.c:588 __asan_report_load1_noabort+0x20/0x30 mm/kasan/report_generic.c:378 decode_session6+0xf74/0x1198 net/xfrm/xfrm_policy.c:3491 __xfrm_decode_session+0x78/0xf8 net/xfrm/xfrm_policy.c:3597 xfrm_decode_session_reverse include/net/xfrm.h:1257 [inline] icmpv6_route_lookup+0x30c/0x498 net/ipv6/icmp.c:392 icmp6_send+0x94c/0x1af8 net/ipv6/icmp.c:601 __icmpv6_send include/linux/icmpv6.h:28 [inline] icmpv6_send include/linux/icmpv6.h:49 [inline] ip6_link_failure+0x3c/0x1b0 net/ipv6/route.c:2791 dst_link_failure include/net/dst.h:447 [inline] ip6_tnl_xmit+0x3cc/0x2778 net/ipv6/ip6_tunnel.c:1283 ipxip6_tnl_xmit net/ipv6/ip6_tunnel.c:1399 [inline] ip6_tnl_start_xmit+0x774/0x1138 net/ipv6/ip6_tunnel.c:1447 __netdev_start_xmit include/linux/netdevice.h:4965 [inline] netdev_start_xmit include/linux/netdevice.h:4979 [inline] xmit_one.constprop.0+0x114/0x3c0 net/core/dev.c:3580 dev_hard_start_xmit+0xb0/0x180 net/core/dev.c:3596 sch_direct_xmit+0x17c/0x1088 net/sched/sch_generic.c:342 qdisc_restart net/sched/sch_generic.c:407 [inline] __qdisc_run+0x1a4/0x358 net/sched/sch_generic.c:415 __dev_xmit_skb net/core/dev.c:3886 [inline] __dev_queue_xmit+0x156c/0x3380 net/core/dev.c:4358 dev_queue_xmit include/linux/netdevice.h:3146 [inline] neigh_connected_output+0x2e8/0x3e0 net/core/neighbour.c:1592 neigh_output include/net/neighbour.h:553 [inline] ip6_finish_output2+0xb58/0x17b0 net/ipv6/ip6_output.c:141 ip6_fragment+0x1778/0x1d70 net/ipv6/ip6_output.c:962 __ip6_finish_output+0x61c/0x9f0 net/ipv6/ip6_output.c:206 ip6_finish_output+0x48/0x2d8 net/ipv6/ip6_output.c:219 NF_HOOK_COND include/linux/netfilter.h:297 [inline] ip6_output+0x1cc/0x3a0 net/ipv6/ip6_output.c:240 dst_output include/net/dst.h:468 [inline] ip6_local_out+0xa4/0xe0 net/ipv6/output_core.c:155 ip6_send_skb+0x88/0x1f0 net/ipv6/ip6_output.c:2038 udp_v6_send_skb+0xa7c/0x10b8 net/ipv6/udp.c:1295 udpv6_sendmsg+0x1b04/0x2320 net/ipv6/udp.c:1591 inet6_sendmsg+0xb0/0x110 net/ipv6/af_inet6.c:657 sock_sendmsg_nosec net/socket.c:734 [inline] __sock_sendmsg net/socket.c:749 [inline] __sock_sendmsg+0xc8/0x190 net/socket.c:744 sock_sendmsg+0x120/0x210 net/socket.c:772 splice_to_socket+0x8d8/0xc88 fs/splice.c:881 do_splice_from fs/splice.c:933 [inline] direct_splice_actor+0x100/0x1a0 fs/splice.c:1142 splice_direct_to_actor+0x300/0x898 fs/splice.c:1088 do_splice_direct+0x190/0x268 fs/splice.c:1194 do_sendfile+0xa50/0xf50 fs/read_write.c:1256 __do_sys_sendfile64 fs/read_write.c:1324 [inline] __se_sys_sendfile64+0x2e4/0x3a0 fs/read_write.c:1310 __arm64_sys_sendfile64+0x94/0xe0 fs/read_write.c:1310 __invoke_syscall arch/arm64/kernel/syscall.c:37 [inline] invoke_syscall+0x8c/0x2e0 arch/arm64/kernel/syscall.c:51 el0_svc_common.constprop.0+0x200/0x2a8 arch/arm64/kernel/syscall.c:134 do_el0_svc+0x4c/0x70 arch/arm64/kernel/syscall.c:176 el0_svc+0x44/0x1d8 arch/arm64/kernel/entry-common.c:806 el0t_64_sync_handler+0x100/0x130 arch/arm64/kernel/entry-common.c:844 el0t_64_sync+0x188/0x190 arch/arm64/kernel/entry.S:757 Therefore, set the cb field in the skb to 0 before xfrm decode process. Fixes: e5d25a90886d ("[IPV6] XFRM: Fix decoding session with preceding extension header(s).") Signed-off-by: Wang Liang <wangliang74@huawei.com> --- net/ipv6/ip6_tunnel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index d1f819238414..dc8d7ed637ef 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1227,6 +1227,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, t->err_time + IP6TUNNEL_ERR_TIMEO)) { t->err_count--; + memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); dst_link_failure(skb); } else { t->err_count = 0; @@ -1302,6 +1303,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, return 0; tx_err_link_failure: stats->tx_carrier_errors++; + memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); dst_link_failure(skb); tx_err_dst_release: dst_release(dst); -- 2.34.1