• Guillaume Nault's avatar
    ipmr: Fix skb headroom in ipmr_get_route(). · 7901cd97
    Guillaume Nault authored
    In route.c, inet_rtm_getroute_build_skb() creates an skb with no
    headroom. This skb is then used by inet_rtm_getroute() which may pass
    it to rt_fill_info() and, from there, to ipmr_get_route(). The later
    might try to reuse this skb by cloning it and prepending an IPv4
    header. But since the original skb has no headroom, skb_push() triggers
    skb_under_panic():
    
    skbuff: skb_under_panic: text:00000000ca46ad8a len:80 put:20 head:00000000cd28494e data:000000009366fd6b tail:0x3c end:0xec0 dev:veth0
    ------------[ cut here ]------------
    kernel BUG at net/core/skbuff.c:108!
    invalid opcode: 0000 [#1] SMP KASAN PTI
    CPU: 6 PID: 587 Comm: ip Not tainted 5.4.0-rc6+ #1
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014
    RIP: 0010:skb_panic+0xbf/0xd0
    Code: 41 a2 ff 8b 4b 70 4c 8b 4d d0 48 c7 c7 20 76 f5 8b 44 8b 45 bc 48 8b 55 c0 48 8b 75 c8 41 54 41 57 41 56 41 55 e8 75 dc 7a ff <0f> 0b 0f 1f 44 00 00 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00
    RSP: 0018:ffff888059ddf0b0 EFLAGS: 00010286
    RAX: 0000000000000086 RBX: ffff888060a315c0 RCX: ffffffff8abe4822
    RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffff88806c9a79cc
    RBP: ffff888059ddf118 R08: ffffed100d9361b1 R09: ffffed100d9361b0
    R10: ffff88805c68aee3 R11: ffffed100d9361b1 R12: ffff88805d218000
    R13: ffff88805c689fec R14: 000000000000003c R15: 0000000000000ec0
    FS:  00007f6af184b700(0000) GS:ffff88806c980000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00007ffc8204a000 CR3: 0000000057b40006 CR4: 0000000000360ee0
    DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
    DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
    Call Trace:
     skb_push+0x7e/0x80
     ipmr_get_route+0x459/0x6fa
     rt_fill_info+0x692/0x9f0
     inet_rtm_getroute+0xd26/0xf20
     rtnetlink_rcv_msg+0x45d/0x630
     netlink_rcv_skb+0x1a5/0x220
     rtnetlink_rcv+0x15/0x20
     netlink_unicast+0x305/0x3a0
     netlink_sendmsg+0x575/0x730
     sock_sendmsg+0xb5/0xc0
     ___sys_sendmsg+0x497/0x4f0
     __sys_sendmsg+0xcb/0x150
     __x64_sys_sendmsg+0x48/0x50
     do_syscall_64+0xd2/0xac0
     entry_SYSCALL_64_after_hwframe+0x49/0xbe
    
    Actually the original skb used to have enough headroom, but the
    reserve_skb() call was lost with the introduction of
    inet_rtm_getroute_build_skb() by commit 404eb77e ("ipv4: support
    sport, dport and ip_proto in RTM_GETROUTE").
    
    We could reserve some headroom again in inet_rtm_getroute_build_skb(),
    but this function shouldn't be responsible for handling the special
    case of ipmr_get_route(). Let's handle that directly in
    ipmr_get_route() by calling skb_realloc_headroom() instead of
    skb_clone().
    
    Fixes: 404eb77e ("ipv4: support sport, dport and ip_proto in RTM_GETROUTE")
    Signed-off-by: default avatarGuillaume Nault <gnault@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    7901cd97
Name
Last commit
Last update
..
bpfilter Loading commit data...
netfilter Loading commit data...
Kconfig Loading commit data...
Makefile Loading commit data...
af_inet.c Loading commit data...
ah4.c Loading commit data...
arp.c Loading commit data...
cipso_ipv4.c Loading commit data...
datagram.c Loading commit data...
devinet.c Loading commit data...
esp4.c Loading commit data...
esp4_offload.c Loading commit data...
fib_frontend.c Loading commit data...
fib_lookup.h Loading commit data...
fib_notifier.c Loading commit data...
fib_rules.c Loading commit data...
fib_semantics.c Loading commit data...
fib_trie.c Loading commit data...
fou.c Loading commit data...
gre_demux.c Loading commit data...
gre_offload.c Loading commit data...
icmp.c Loading commit data...
igmp.c Loading commit data...
inet_connection_sock.c Loading commit data...
inet_diag.c Loading commit data...
inet_fragment.c Loading commit data...
inet_hashtables.c Loading commit data...
inet_timewait_sock.c Loading commit data...
inetpeer.c Loading commit data...
ip_forward.c Loading commit data...
ip_fragment.c Loading commit data...
ip_gre.c Loading commit data...
ip_input.c Loading commit data...
ip_options.c Loading commit data...
ip_output.c Loading commit data...
ip_sockglue.c Loading commit data...
ip_tunnel.c Loading commit data...
ip_tunnel_core.c Loading commit data...
ip_vti.c Loading commit data...
ipcomp.c Loading commit data...
ipconfig.c Loading commit data...
ipip.c Loading commit data...
ipmr.c Loading commit data...
ipmr_base.c Loading commit data...
metrics.c Loading commit data...
netfilter.c Loading commit data...
netlink.c Loading commit data...
nexthop.c Loading commit data...
ping.c Loading commit data...
proc.c Loading commit data...
protocol.c Loading commit data...
raw.c Loading commit data...
raw_diag.c Loading commit data...
route.c Loading commit data...
syncookies.c Loading commit data...
sysctl_net_ipv4.c Loading commit data...
tcp.c Loading commit data...
tcp_bbr.c Loading commit data...
tcp_bic.c Loading commit data...
tcp_bpf.c Loading commit data...
tcp_cdg.c Loading commit data...
tcp_cong.c Loading commit data...
tcp_cubic.c Loading commit data...
tcp_dctcp.c Loading commit data...
tcp_dctcp.h Loading commit data...
tcp_diag.c Loading commit data...
tcp_fastopen.c Loading commit data...
tcp_highspeed.c Loading commit data...
tcp_htcp.c Loading commit data...
tcp_hybla.c Loading commit data...
tcp_illinois.c Loading commit data...
tcp_input.c Loading commit data...
tcp_ipv4.c Loading commit data...
tcp_lp.c Loading commit data...
tcp_metrics.c Loading commit data...
tcp_minisocks.c Loading commit data...
tcp_nv.c Loading commit data...
tcp_offload.c Loading commit data...
tcp_output.c Loading commit data...
tcp_rate.c Loading commit data...
tcp_recovery.c Loading commit data...
tcp_scalable.c Loading commit data...
tcp_timer.c Loading commit data...
tcp_ulp.c Loading commit data...
tcp_vegas.c Loading commit data...
tcp_vegas.h Loading commit data...
tcp_veno.c Loading commit data...
tcp_westwood.c Loading commit data...
tcp_yeah.c Loading commit data...
tunnel4.c Loading commit data...
udp.c Loading commit data...
udp_diag.c Loading commit data...
udp_impl.h Loading commit data...
udp_offload.c Loading commit data...
udp_tunnel.c Loading commit data...
udplite.c Loading commit data...
xfrm4_input.c Loading commit data...
xfrm4_output.c Loading commit data...
xfrm4_policy.c Loading commit data...
xfrm4_protocol.c Loading commit data...
xfrm4_state.c Loading commit data...
xfrm4_tunnel.c Loading commit data...